確率的な性質

is_markov() は、どの domain の点でも codomain スライスの和が 1 または 0 のときに真です。0 は、条件付けでできるゼロ行のためです。 状態は domain が空なので、is_markov は False を返します。正規化された 状態は numpy.isclose(state.data.sum(), 1) で確認します。

is_deterministic() は、すべての codomain スライスが点質量(1 が1つで残りが 0)のときに真です。ゼロのスライスは決定的では ありません。恒等、copy、swap、discard は決定的です。一般の確率核はそうでは ありません。

import numpy as np
from fxtensor_salmon import FXTensor

state = FXTensor([[], [2]], data=np.array([0.2, 0.8]))
assert not state.is_markov()
assert np.isclose(state.data.sum(), 1.0)

kernel = FXTensor([[2], [2]], data=np.array([[0.2, 0.8], [0.0, 0.0]]))
assert kernel.is_markov()
assert not kernel.is_deterministic()

bad = FXTensor([[2], [2]], data=np.array([[0.2, 0.2], [0.5, 0.5]]))
assert not bad.is_markov()

identity = FXTensor.identity_tensor([2])
assert identity.is_deterministic()
assert identity.is_markov()
zeros = FXTensor([[2], [2]], data=np.zeros((2, 2)))
assert not zeros.is_deterministic()

等価と比較と複製

== はプロファイル、ラベル、データを比べます。データは FXTensor._RTOL と FXTensor._ATOL による allclose です。hash は生のバイト列を使うので、 許容誤差の内側で値が違っていても == が真になり、ハッシュは異なることが あります。その組を辞書のキーとして同一視しないでください。

copy``(および ``copy.copy)は配列を複製します。片方への書き込みは、もう 片方を変えません。

import numpy as np
from fxtensor_salmon import FXTensor

left = FXTensor([[2], [1]], data=np.array([[1.0], [1.0]]))
right = FXTensor([[2], [1]], data=np.array([[1.0], [1.0 + 1e-9]]))
assert left == right
assert hash(left) != hash(right)

labeled = FXTensor([[["a", "b"]], [["x", "y"]]], data=np.array([[0.2, 0.8], [0.6, 0.4]]))
relabeled = FXTensor([[["a", "b"]], [["y", "x"]]], data=np.array([[0.2, 0.8], [0.6, 0.4]]))
assert labeled != relabeled

cloned = labeled.copy()
cloned.data[0, 0] = 0.0
assert labeled.data[0, 0] == 0.2
assert cloned is not labeled