構造射

これらのコンストラクタは、マルコフ圏の決定的な配線を作ります。 copy_tensor、identity_tensor、delta_tensor は、整数の長さか 文字列ラベルのリストを受けます。swap、exclamation、unit_tensor は 整数の長さだけを受けます。

恒等、デルタ、複製

identity_tensor() は恒等核です。 delta_tensor() はその別名です。 copy_tensor() は対角 X → X⊗n です。 n=1 は恒等、n=0 は破棄(domain 上のすべて 1)、負の n は ValueError です。因子リストが空なら、モノイド単位上のスカラー 1 です。

import numpy as np
from fxtensor_salmon import FXTensor

labels = [["a", "b"]]
identity = FXTensor.identity_tensor(labels)
assert identity.labels == ([["a", "b"]], [["a", "b"]])
assert identity.is_deterministic()

numeric_identity = FXTensor.identity_tensor([2, 3])
assert numeric_identity.profile == [[2, 3], [2, 3]]
assert FXTensor.delta_tensor([2]) == FXTensor.identity_tensor([2])
assert FXTensor.delta_tensor([2]).profile == [[2], [2]]
assert FXTensor.identity_tensor([]).profile == [[], []]

copy = FXTensor.copy_tensor([2])
assert copy.profile == [[2], [2, 2]]
assert np.array_equal(
    copy.data,
    [
        [[1, 0], [0, 0]],
        [[0, 0], [0, 1]],
    ],
)
labeled_copy = FXTensor.copy_tensor([["a", "b"]])
assert labeled_copy.labels == ([["a", "b"]], [["a", "b"], ["a", "b"]])
assert FXTensor.copy_tensor([2], n=1) == FXTensor.identity_tensor([2])
discarding_copy = FXTensor.copy_tensor([["a", "b"]], n=0)
assert discarding_copy.profile == [[2], []]
assert discarding_copy.labels == ([["a", "b"]], None)
assert np.array_equal(discarding_copy.data, [1.0, 1.0])
try:
    FXTensor.copy_tensor([2], n=-1)
except ValueError:
    pass
else:
    raise AssertionError("copy_tensor rejects a negative count")

交換、破棄、すべて 1 の状態

swap() は2つの因子ブロックを入れ替えます。 exclamation() は破棄 X → I で、domain 上は すべて 1、codomain は空です。 unit_tensor() はすべて 1 の状態です。正規化は されておらず、モノイド単位(空のプロファイル)でもありません。

import numpy as np
from fxtensor_salmon import FXTensor

swap = FXTensor.swap([2], [3])
assert swap.profile == [[2, 3], [3, 2]]
assert swap.is_deterministic()
assert swap.composition(FXTensor.swap([3], [2])) == FXTensor.identity_tensor([2, 3])

discard = FXTensor.exclamation([2, 3])
assert discard.profile == [[2, 3], []]
assert np.all(discard.data == 1)
assert discard.is_deterministic()

unit = FXTensor.unit_tensor([2, 3])
assert unit.profile == [[], [2, 3]]
assert unit.labels == (None, None)
assert np.all(unit.data == 1)

copy の法則

これらのテンソルの上で、copy は余可換・余結合・余単位的で、discard は自然です。 つまり核 f に対して f ; ! = ! です。決定的な核は copy と交換します。

copy の余結合律

copy の余結合律。

copy の余単位律

copy の余単位律。

copy の余可換律

copy の余可換律。

discard は自然で、f と discard の合成は discard に等しい

discard の自然性: f ; ! = !。

import numpy as np
from fxtensor_salmon import FXTensor

copy = FXTensor.copy_tensor([2])
identity = FXTensor.identity_tensor([2])
discard = FXTensor.exclamation([2])
assert copy.composition(FXTensor.swap([2], [2])) == copy
assert copy.composition(identity.tensor_product(discard)) == identity
assert copy.composition(discard.tensor_product(identity)) == identity
assert copy.composition(copy.tensor_product(identity)) == FXTensor.copy_tensor([2], n=3)

kernel = FXTensor([[2], [2]], data=np.array([[0.8, 0.2], [0.4, 0.6]]))
assert kernel.composition(FXTensor.exclamation([2])) == FXTensor.exclamation([2])
assert identity.composition(copy) == copy.composition(identity.tensor_product(identity))