入出力¶
JSON¶
to_json() は profile、data、dtype を
持つ辞書を返します。ラベルがあるときはプロファイルもラベル付きです。
from_json() は profile と data から
テンソルを作り直します。names があるときは、domain と codomain の
軸の名前の組です。names のない JSON は、名前のないテンソルとして読みます。
save_to_file() はその辞書を JSON として書き、
load_from_file() が読み戻します。
import numpy as np
from fxtensor_salmon import FXTensor
json_data = {
"profile": [[["a", "b"]], [["x", "y"]]],
"data": [[0.2, 0.8], [0.6, 0.4]],
}
tensor = FXTensor.from_json(json_data)
assert tensor.labels == ([["a", "b"]], [["x", "y"]])
payload = tensor.to_json()
assert payload["profile"] == [[["a", "b"]], [["x", "y"]]]
assert payload["dtype"] == str(tensor.data.dtype)
assert FXTensor.from_json(payload) == tensor
import tempfile
from pathlib import Path
import numpy as np
from fxtensor_salmon import FXTensor
source = FXTensor(
[[["a", "b"]], [["x", "y"]]],
data=np.array([[0.2, 0.8], [0.6, 0.4]]),
)
with tempfile.TemporaryDirectory() as tmp:
filename = str(Path(tmp) / "tensor.json")
source.save_to_file(filename)
loaded = FXTensor.load_from_file(filename)
assert loaded == source
ストランド¶
from_strands() は、ストランドのキーから重みへの
対応を読みます。キーは文字列または整数の入れ子リストという Python リテラルで、
コードとしては評価しません。それ以外のキーは ValueError です。ラベル付きの
ストランドは点の名前を書きます。数値のストランドは 1 始まり の添字で、
各添字をそれぞれのリストで包みます。重みは float または
fractions.Fraction で、float として保存します。
to_original_dict() は数値形式の逆向きです。
非ゼロ成分を 1 始まりの添字リストにします。重みは data の NumPy スカラーで、
プロファイルは数値のプロファイルです。
import numpy as np
from fractions import Fraction
from fxtensor_salmon import FXTensor
profile = [[2], [3]]
strands = {
"[[[1]], [[1]]]": 0.1,
"[[[1]], [[2]]]": 0.2,
"[[[1]], [[3]]]": 0.7,
"[[[2]], [[1]]]": 0.3,
"[[[2]], [[2]]]": 0.3,
"[[[2]], [[3]]]": 0.4,
}
tensor = FXTensor.from_strands(profile, strands)
assert np.allclose(
tensor.data,
[
[0.1, 0.2, 0.7],
[0.3, 0.3, 0.4],
],
)
half = FXTensor.from_strands([[2], [1]], {"[[[1]], [[1]]]": Fraction(1, 2)})
assert np.isclose(half.data[0, 0], 0.5)
original = FXTensor([[2], [3]], data=np.array([[0.1, 0.0, 0.7], [0.0, 0.3, 0.0]]))
encoded = original.to_original_dict()
assert encoded["profile"] == [[2], [3]]
assert float(encoded["strands"]["[[1], [1]]"]) == 0.1
assert "[[1], [2]]" not in encoded["strands"]
try:
FXTensor.from_strands([[["a", "b"]], [["x", "y"]]], {"not-a-list": 1.0})
except ValueError:
pass
else:
raise AssertionError("strand keys must be nested lists")