タプル1変数関数と多変数関数を区別しなければならない状況として、複線形写像の話をして、最後に復圏と多圏に少し触れます。
内容:
多値と多引数
関数が多値であるとは、一度に複数の値を返すことです。余域の部分集合を返す非決定性関数〈nondeterministic function〉のことではありません。また、タプルデータを1つ返すのでもなくて、複数の値を返すのが多値関数です。
多値関数の話は、2006年2月9日から2月22日のあいだに次の記事を書いています。「そんなこともあったなー」と懐旧の念:
ところで、関数の値ではなくて引数〈入力〉が複数なのは珍しくはないですね。特に難しいことも面白いこともなさそうです。ですが、状況によっては、タプルデータを1つ受け取る関数と、複数の引数を受け取る関数を区別する必要があります。通常、区別はしてない(する必要もない)ので、区別すべき状況での対応が難しいようです。具体的に言えば、複線形写像〈多重線形写像〉の議論でだいぶ面食らうみたい。
というわけで、この記事では、多引数関数 -- 多変数関数と呼ぶのが普通かな -- について主題的に扱います。
多変数関数
タプル変数と多変数を区別しない環境に慣れている人=大部分の人には、何が問題かも分かりにくと思いますから、故意に次のルールを設けます。
- タプルは、角括弧で囲む必要がある。
- タプルの並びは縦方向である。
- 多変数の並びは(従来どおり)横方向でよい。
このルールを守るとして、足し算をする関数 add に、2 と 3 を引数として渡す方法は次の2つがあります。
引数の渡し方が違えば関数は別物とみなします。オーバーロードするのが便利ですが、オーバーロードも禁止です。次のように名前を変えるしかありません(機能は同じ足し算です)。
add1 と add2 のプロファイルを次のように書きます。
3つの実数の情報を必要とする関数のプロファイルは何種類かあります。
それぞれの引数の渡し方は次のようになります。
こんな区別をして書く必要があるんでしょうか? 3つの実数分の情報を貰えば関数は仕事できるんだから、どれだって同じでしょ -- そう思いますが、さて‥‥
複線形写像
をベクトル空間とします。前節の f1, f2, f3, f4 は、引数も戻り値も実数や実数タプルでしたが、この節から先は次のプロファイルで考えます。
ベクトル空間の場合、台集合の直積に線形構造(足し算とスカラー倍)を入れたベクトル空間は直和ベクトル空間と呼び、記号 '' を使って書きます*1から、次のように書いたほうがよいでしょう。
として、引数の渡し方は前節と同じです。
さて、一般に、ベクトル引数を幾つか持つベクトル値の関数が複線形写像〈multilinear map〉だとは、どの引数〈入力変数〉に関しても、他の引数を固定して線形になることです。
f1, f2, f3, f4 が複線形写像である条件のうち、変数〈引数〉ごとに足し算を保存すること(加法性)だけを書いてみます。複線形写像の条件には、変数〈引数〉ごとにスカラー倍を保存することもありますが、それは割愛します。
f1 が変数〈引数〉ごとに加法的 ⇔
f2 が変数〈引数〉ごとに加法的 ⇔
f3 が変数〈引数〉ごとに加法的 ⇔
f4 が変数〈引数〉ごとに加法的 ⇔
変数〈引数〉の個数が違うと、「加法的である」という条件の形も違ってきます。
注意して欲しいのは、「複線形写像」に「復」の字が入っていても、普通の線形写像(強いて言えば「単線形写像」)も除外してないことです。変数〈引数〉が1個である複線形写像は普通の線形写像のことです。
「多項式」に「多」の字が入っているから「単項式は多項式ではない」とか言う人がいるそうですが、「多」「復」のような字の印象でテクニカルタームの意味が決まるわけでも/決めるわけでもありません。字の印象や語感でテクニカルタームを解釈するのはホントやめてね。
曖昧記法が破綻するとき
ここで、タプルを角括弧・縦方向でなくて丸括弧・横方向でもいいとしましょう。すると:
入れ子の丸括弧はめんどくさいし鬱陶しいな-、と省略を始めます。
こうして、タプル1変数と2変数の区別を忘れてしまいます。こういう横着をしても、実害が出ることは少ないので咎〈とが〉められることはありません。
さて、次の問題を出されたとします
- が複線形写像である条件を書きくだせ。
そもそも、この問題の出し方が不適切ですが、その不適切さを指摘するなら、タプル1変数と2変数の区別を意識しなくてはなりません。
問題の がタプル1変数 だとすれば、複線形写像であることは単線形写像であることですから、次の条件になります。
1.
2.
問題の が2変数だとすれば、複線形写像であることは双線形写像であることですから、次の条件になります。
1.
2.
3.
4.
通常我々が使っている記法 は、タプル1変数だか2変数だか曖昧になっています。多くの状況下では曖昧でも問題ない、むしろ曖昧なほうが便利なこともあります。しかし、複線形写像の議論をするときに「タプル1変数とも言えるし、2変数とも言える」では埒が明かないのです。
複圏、多圏
タプル1変数と多変数を区別する必要がある、あるいは区別したほうが便利である状況を扱う抽象的枠組みに復圏〈multicategory〉があります。出力に関しても、タプル1値と多値を区別するのなら多圏〈polycategory〉という枠組みを使います。入力が常に単一で出力側だけが多値であるときは余複圏〈comulticategory〉てのがありますが、複圏の方向をひっくり返すだけなので、ほとんど言及されません。
- one-in one-out なら圏
- multi-in one-out なら復圏
- one-in multi-out なら余復圏
- multi-in multi-out なら多圏
複線形写像は、圏の射としては扱いにくい典型例です。ただし、ベクトル空間のテンソル積を使うと、複線形写像を単なる圏のなかに押し込めることができます。これが、テンソル積が便利で多用される理由です。
複線形写像の復圏ではなくて、多少無理矢理に複線形写像の圏だけで頑張る方法もあります。「モナドを使って多線形写像の圏を作る」で述べています。
既存のモノイド圏から復圏や多圏を作ると、扱いやすさが向上することがあります。これについては次の記事にあります。
我々に馴染みの集合圏(モノイド積は直積)に対しても、対応する復圏 MultiSet、多圏 PolySet を作れます。ほとんど使われないのは、得られるメリットと煩雑さの代償を天秤にかけて、あまり嬉しくないからです。
メリットが大きいときは、圏だけではなくて復圏/多圏も使うと話がスムーズに進みます。特に、モノイド圏を多圏化するとストリング図との相性がより高まります。