このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

圏論的線形代数をもう少し: 自由ベクトル空間の圏

昨日の記事「圏論的線形代数とフレームの話」の続きとして、自由ベクトル空間の圏を作ってしまいましょう。有限次元の自由ベクトル空間の圏は使い勝手が良い圏で、線形代数の難所であるテンソル積も比較的容易に構成できます。

内容:

自由ベクトル空間の圏

「自由ベクトル空間」という言葉には曖昧性があって、次の2つの意味があります。

  1. Vが自由ベクトル空間 :⇔ (V = FreeVect(A) in Vect となる集合Aが存在する)
  2. Vが自由ベクトル空間 :⇔ (V \cong FreeVect(A) in Vect となる集合Aが存在する)

イコールか同型かの違いです。二番目の定義にすると、「すべてのベクトル空間は自由ベクトル空間(ベクトル空間=自由ベクトル空間)」になってしまう*1ので、一番目の定義を採用します。(より詳しいことに興味があれば「自由生成関手/自由忘却随伴と線形代数」参照。)

自由ベクトル空間の圏〈category of free vector spaces〉とは、V = FreeVect(A) となる集合Aが存在するようなベクトル空間V達からなる圏です。ホムセットはVectからそのまま受け継ぎます。結合と恒等射もVectのヤツをそのまま使います。

上記のように定義される(かなり曖昧な定義ですが)自由ベクトル空間の圏をFreeVectと書くことにします。同じ綴り字ですが、FreeVect:SetVect は関手で、FreeVectは圏なので注意してください*2

自由ベクトル空間の圏FreeVectは、自由ベクトル空間生成関手 FreeVect:SetVect の像圏から生成された充満部分圏と言えます。

  • FreeVectVect (部分圏)
  • V∈|FreeVect| ⇔ (V = FreeVect(A) となる集合Aが存在する)
  • V, W∈|FreeVect| に対して、FreeVect(V, W) = Vect(V, W)

三番目の性質が部分圏の充満性で、部分圏のホムセットが親の圏と同じであることです*3

今述べた“自由ベクトル空間の圏”の定義は、直感的には分かりやすいと思いますが、あまり扱いやすくありません。別な定義に書き換えましょう。

対象を集合にする

関手 FreeVect:SetVect の域圏と余域圏は大きな圏なので、通常の集合・写像とまったく同じ扱いは出来ません。が、FreeVectの対象部分〈object part〉 FreeVectobj:|Set| → |Vect| は単射とみなしていいでしょう。つまり、次が成立します。

  • FreeVect(A) = FreeVect(B) in Vect ならば A = B in Set

そうであるなら、圏FreeVectの対象と圏Setの対象は1:1対応することになります。

  • |FreeVect|∋ V ←→ A ∈|Set| ここで V = FreeVect(A)

いっそのこと |FreeVect| を |Set| で置き換えてしまいましょう。FreeVectの定義は次のように変わります。

  • |FreeVect| := |Set|
  • For A, B∈|Set| (|Set| = |FreeVect|)
    FreeVect(A, B) := Vect(FreeVect(A), FreeVect(B))
  • 結合、恒等射はVectから引き継ぐ。

今述べた圏の構成法は、一般的な関手 F:CD に対して使えます。Fが対象上で単射〈injective-on-objects〉じゃなくてもかまいません([追記]Fが忠実関手でないと、ちょっと話がややこしくなりますが。[/追記])。Fから作られる新しい圏をEとすると:

  • |E| := |C|
  • For A, B∈|C| (|C| = |E|)
    E(A, B) := D(F(A), F(B))
  • 結合、恒等射はDから引き継ぐ。

Fが対象上で単射ではないときは、ホムセットが交わる可能性があります。が、これは大した問題ではなくてすぐに修正できます。気になる方は次の記事を参照してください。

FreeVectの対象を集合にすることのメリットは、対象のテンソル積を集合の直積として定義できることです。

  • FreeVect(A)\otimesFreeVect(B) \cong FreeVect(A×B)

この同型を念頭に置くと、ベクトル空間のテンソル積の代わりに集合の直積を使えます。しかし、射は相変わらず線形写像なので扱いが簡単ではありません。射も集合のあいだの(線形の条件を忘れた)単なる写像になると嬉しいのですが。

射を集合のあいだの写像にする

自由ベクトル空間生成関手 FreeVect:SetVect と忘却関手 Und:VectSet は随伴関手ペアでした。ペアとは言っても、実際には2つの圏、2つの関手、2つの自然変換、2つの等式から構成される代数的構造です。このことは次の記事で書いています。

自由-忘却・随伴ペア〈free-forgetful {adjoint pair | adjunction}〉FreeVect -| Und (随伴関手ペアは '-|' で区切って並べる習慣です)は、次のホムセット同型を誘導します*4

  • For A∈|Set|, V∈|Vect|
    Vect(FreeVect(A), V) \stackrel{\sim}{=} Set(A, Und(V))

このホムセット同型は昨日の記事でも述べたもので、「独立性/生成性/基底性」の定義に使いました。

ホムセット同型のVに FreeVect(B) を代入すると:

  • Vec(FreeVect(A), FreeVect(B)) \cong Set(A, Und(FreeVect(B)))

同型を与える写像は(昨日の記事参照):

  • linRestrictA,FreeVect(B):Vec(FreeVect(A), FreeVect(B)) → Set(A, Und(FreeVect(B)))
  • linExtA,FreeVect(B):Set(A, Und(FreeVect(B))) → Vec(FreeVect(A), FreeVect(B))

この同型を利用すれば、圏FreeVectのホムセットを集合圏のホムセットとして定義できそうです。つまり:

  • |FreeVect| := |Set|
  • For A, B∈|Set| (|Set| = |FreeVect|)
    FreeVect(A, B) := Set(A, Und(FreeVect(B)))

この定義では、FreeVectの射(の実体)は、A → Und(FreeVect(B)) という写像になります。昨日の記事で Und(FreeVect(B)) = LinComb(B) と約束しておいたので、A → LinComb(B) という写像と言っても同じです。単なる写像で、特に線形性どうこうの条件はありません。嬉しいですね。

しかし問題があります。圏FreeVectのホムセットをこのように定義してしまうと、Vectの結合と恒等射をそのまま使うわけにはいきません。新しい結合と恒等射を構成する必要があります。

新しい射、結合、恒等射をそれぞれ、クライスリ射、クライスリ結合、クライスリ恒等射と呼び、次のように書くことにします(とりあえず呼び名と書き方を先に)。

  • クライスリ射はラテン文字大文字で書く。F:A → B in FreeVect のように。クライスリ射の実体は集合圏の射で F:A → LinComb(B) in Set。実体としてはひとつのFに、FreeVectの射としての顔と、Setの射としての顔があるのです*5
  • F:A → B, G:B → C in FreeVect のクライスリ結合(FreeVectの新しい結合)を F;;G と書く。
  • 対象Aのクライスリ恒等射(FreeVectの新しい恒等射)を kidA と書く。

この後、クライスリ結合 ;; とクライスリ恒等射 kid の定義を与えますが、その前にクライスリ拡張〈Kleisli extension〉と呼ばれるオペレーター klExt を定義しておきます。

クライスリ拡張と行列表示

A, B∈|FreeVect|(A, B∈|Set|)に対して、クライスリ拡張 klExtA,B は次のように定義します。

  • klExtA,B:Set(A, LinComb(B)) → Set(LinComb(A), LinComb(B))
  • klExtA,B := Und(linExtA,FreeVect(B))

忘却関手Undは積極的には何もしない(線形性を忘れるだけ)ので、klExtA,B は linExtA,FreeVect(B) と同じです。同じですが、昨日述べたように「忘却関手の忘却」は危険なので、必要なときに忘却関手の存在を思い出してください。

klExtA,B の具体的な定義は linExtA,FreeVect(B)昨日の記事参照)と同じなので次のように書けます。

\newcommand{\ind}{\:\:\:\:}%
klExt_{A,B} := \\
\lambda\, F \in Map(A, LinComb(B)).( \\
\ind \lambda\, (x = \stackrel{\scriptsize formal}{\sum}_{a \in A}x_a\cdot [a]) \in LinComb(A).(\\
\ind\ind  \stackrel{\scriptsize actual}{\sum}_{a \in A} x_a \cdot F(a)\:\: \in LinComb(B) \\
\ind ) \\
)

F(a)∈LinComb(B) なので、F(a) はBの要素の形式的線形結合で書けます。それを次のようにしましょう。

 F(a) = \stackrel{\scriptsize formal}{\sum}_{b\in B}F(a)_b\cdot [b]

これを先の定義式に代入すると:


klExt_{A,B} := \\
\lambda\, F \in Map(A, LinComb(B)).( \\
\ind \lambda\, (x = \stackrel{\scriptsize formal}{\sum}_{a \in A}x_a\cdot [a]) \in LinComb(A).(\\
\ind\ind  \stackrel{\scriptsize actual}{\sum}_{a \in A} x_a \cdot \left(\stackrel{\scriptsize formal}{\sum}_{b\in B}F(a)_b\cdot [b]\right)\:\: \in LinComb(B) \\
\ind ) \\
)

LinComb(B)内での実際の計算〈actual calculation〉は、形式的な計算〈formal calculation〉を遂行することなので、形式的和と形式的スカラー倍を展開して次のように書けます。


klExt_{A,B} := \\
\lambda\, F \in Map(A, LinComb(B)).( \\
\ind \lambda\, (x = \stackrel{\scriptsize formal}{\sum}_{a \in A}x_a\cdot [a]) \in LinComb(A).(\\
\ind\ind  \stackrel{\scriptsize formal}{\sum}_{a \in A}\stackrel{\scriptsize formal}{\sum}_{b\in B}  (x_a\ F(a)_b\ \cdot [b])\:\: \in LinComb(B) \\
\ind ) \\
)

実数と実数の掛け算は併置(演算子記号なし)にしています。具体的には  x_a\ F(a)_b\ の掛け算は実数の掛け算です。ドット〈ナカグロ〉は形式的スカラー倍として残してあります。

自由ベクトル空間における計算では、形式的和/形式的スカラー倍をいちいち意識することはないでしょう。それは、自由ベクトル空間においては、形式的計算が実際の計算だからです。

さて、Fのクライスリ拡張(による結果) klExtA,B(F) を F# と略記することにして、その定義をより分かりやすく書きましょう。「形式的計算が実際の計算」なので、総和記号にformalを付けるのはやめます(ドットは残します)。


\mbox{For }F \in Map(A, LinComb(B)) \\
\ind \mbox{where } F(a) = {\sum}_{b\in B}F(a)_b\cdot [b] \\
\:\\
F^\#(\,{\sum}_{a \in A}x_a\cdot [a]\,) := {\sum}_{a \in A}{\sum}_{b\in B}  (x_a F(a)_b \cdot [b]) \\

実は、クライスリ射Fとは行列のことです。行列Fのクライスリ拡張F#は、行列が定義する線形写像の台写像のことです([追記]写像については、「忘却関手は難しい」に書いています。[/追記])。クライスリ射が行列に見えないのは、書き方の問題です。行列の書き方に合わせるために次の約束にしましょう。

  • スカラー倍を右からの掛け算にする。
  • 結合や適用が反図式順になるように書く。
  •  F(a)_b F_{b,a} と書く。b,a の順なのは反図式順だから。

書き方を変更して再度定義の主要部分を書いてみます。


F^\#(\,{\sum}_{a \in A} [a]\cdot x_a\,) := {\sum}_{b\in B}{\sum}_{a \in A} ([b] \cdot F_{b,a} x_a)  \\

我々は通常、次の略記も使っています。


(x_a)_{a\in A} := {\sum}_{a \in A} [a]\cdot x_a \\
(y_b)_{b\in B} := {\sum}_{b \in B} [b]\cdot y_b

この略記を使って書き換えると:


F^\#(\, (x_a)_{a\in A} \,) := \left({\sum}_{a \in A} F_{b,a} x_a \right)_{b\in B} \\

A = {1, ..., m}, B = {1, ..., n} という特別な場合を書いてみましょう。


F^\#(\, (x_a)_{a = 1,\cdots, m} \,) := \left({\sum}^m_{a = 1} F_{b,a} x_a \right)_{b = 1,\cdots, n} \\

やっとお馴染みの行列計算の形に到達しました。 a = 1,\cdots, m\:\: b = 1,\cdots, n でインデックスされた行列成分達  F_{b,a} が定義する線形写像(の台写像 F^\# が、上の等式で定義されるわけです。別な言い方をすると、線形写像  F^\# の行列表示が  (F_{b,a})_{a = 1,\cdots, m\:\: b = 1,\cdots, n} です。

まとめて言えば; クライスリ射は実は行列のことで、クライスリ拡張は行列から線形写像を得ることです

これは、書き方や言い方が異なるだけで、同一概念がまったく別物のように見えてしまう例になるでしょう。我々は、非常にしばしば書き方・言い方に惑わされます。同じ概念的実体を、異なる書き方や言い方で表現されると違ったものとして捉えてしまいます(致し方ないのですが)。なので、書き方・言い方の翻訳のスキルが重要になります。

クライスリ結合と行列乗法

クライスリ拡張が定義できれば、クライスリ結合とクライスリ恒等射をクライスリ拡張を使って定義できます。先に言っておくと; クライスリ結合は行列の掛け算で、クライスリ恒等射は単位行列のことです。書き方や言い方が異なるだけです。

念の為に、書き方や言い方の違いを注意しておくと:

  • クライスリ射(行列)Fに対応する線形写像をF#と書く。通常、FとF#は同一視される(別物だが区別しない習慣)。
  • クライスリ射(行列)F, G のクライスリ結合を F;;G と書く。通常の記法では GF で、結合演算子記号は無く、反図式順(右から左)になる。
  • クライスリ恒等射(単位行列)を kidA と書く。通常の記法では IA が多い。

[補足]
F:A → B in FreeVect (F:A → LinComb(B) in Set)のとき、

  • F#∈Map(LinComb(A), LinComb(B))

なので、F# は集合のあいだの写像です。

では、このF#は線形写像ではないのでしょうか? 線形写像と言っていいですよね。つまり、

  • F#Vect(FreeVect(A), FreeVect(B))

F# が Map(LinComb(A), LinComb(B)) = FreeVect(A, B) と Vect(FreeVect(A), FreeVect(B)) の両方に入ってますが、これは別におかしなことではありません。

  • Vect(FreeVect(A), FreeVect(B)) ⊆ Map(LinComb(A), LinComb(B))

だからです。

F:A → LinComb(B) と F#:LinComb(A) → LinComb(B) は、写像として別物ですが、Map(LinComb(A), LinComb(B)) = FreeVect(A, B) に入っているF#と、Vect(FreeVect(A), FreeVect(B))に入っているF#は実体として同じ写像です。

同じ写像を、別な圏の別な射とみなすことは普通のことです。同一人物が、会社では「課長さん」であり、家庭では「おとうさん」であり、病院では「患者さん」と呼ばれて別な扱いを受けるのは当然でしょ。

[/補足]

クライスリ結合〈Kleisli composition〉とクライスリ恒等射〈Kleisli identity〉の定義は以下のとおりです。

  • F;;G := F;G#
  • kidA := linEmbedA = λa∈A.([a])

クライスリ結合とクライスリ恒等射を備えたFreeVectが、実際に圏になるには、次の法則が成立している必要があります。

  • For F:A → B, G:B → C, H:C → D in FreeVect
    (F;;G);;H = F;;(G;;H) :A → D in FreeVect
  • For F:A → B in FreeVect
    kidA;;F = F かつ F;;kidB = F

クライスリ結合とクライスリ恒等射の具体的な定義に基づいてガシガシ計算すれば示せます。次の等式達を先に示しておくと楽かも知れません。

  1. (kidA)# = idLinComb(A)
  2. kidA;F# = F
  3. (F;G#)# = F#;G#

クライスリ結合が行列の掛け算であり、クライスリ恒等射が単位行列であることも、具体的な定義に基づいて確認してみてください。実際に確認してみれば、自由ベクトル空間の圏における計算が実は行列計算であることが納得できるでしょう。

  1. FreeVectは(一般化された)行列の圏
  2. FreeVectの射は行列
     F = (F_{b,a})_{a\in A,\, b\in B}
  3. FreeVectの恒等射は単位行列
     I_A = kid_A = (\delta_{b,a})_{a\in A,\, b\in B} \delta_{b,a}クロネッカーのデルタ)
  4. FreeVectの結合は行列の掛け算〈乗法 | 積〉
     F;;G = GF = \left(\sum_{b\in B}(G_{c, b}F_{b, a})\right)_{a\in A,\, c\in C}

*1:「すべてのベクトル空間は基底を持つ」と同値な命題です。通常、「すべてのベクトル空間は基底を持つ」は成立します。「通常」と言ったのは、選択公理が必要だからで、選択公理が使えないなら命題は成立しません。

*2:[追記]後で気付いたけど、見出しの文字は太字になるので関手か圏か区別が付かなくなりますね。[/追記]

*3:充満部分圏は、ホムセットがめいっぱい太っている部分圏です。

*4:ニョロニョロ等式を満たす代数系としての随伴系からホムセット同型は導けます。逆に、可逆自然変換としてホムセット同型が与えられれば、そこから代数系としての随伴系を構成できます。

*5:同一の実体が2つ以上の顔〈役割〉を持つことは、日常では当たり前のことなんですが、なかなか難しいようです。セミナー補足資料として書いた記事に「「僕のおとうさん」と「お友達のおとうさん」 (C A4)」があります。