私はテンソルの収縮に依存するC++ライブラリに取り組んでいます。私はここに完全なアプリケーションを掲載するつもりはありませんが、私はそれを次のように蒸留しました。Eigen :: Tensorの収縮でテンソルを交換することによって、異なる結果が生じるのはなぜですか?
我々は(0、1 ...、15)は何もなく、されていないおもちゃのランク4テンソルを定義作り直さ:
Eigen::Tensor<double, 4> T (2, 2, 2, 2);
for (size_t i = 0; i < 2; i++) {
for (size_t j = 0; j < 2; j++) {
for (size_t k = 0; k < 2; k++) {
for (size_t l = 0; l < 2; l++) {
T(i, j, k, l) = l + 2 * k + 4 * j + 8 * i;
}
}
}
}
と何物でもありませんとの契約ランク2テンソル、しかし、(1、2、3、4)形状変更:
Eigen::Tensor<double, 2> A (2, 2);
for (size_t i = 0; i < 2; i++) {
for (size_t j = 0; j < 2; j++) {
A(i, j) = 1 + j + 2 * i;
}
}
を固有に2つのテンソルを縮小するためには、我々は収縮ペアを指定する必要があります。我々の目標は、T(ijkl)*A(ib)=M(bjkl)
のように、テンソルの最初の2つのインデックスを縮小することです。固有におけるテンソルモジュールの私の現在の理解では、我々は
Eigen::array<Eigen::IndexPair<int>, 1> contraction_pair = {Eigen::IndexPair<int>(0, 0)};
として収縮ペアを書きますが、私は収縮A(ib)*T(ijkl)=N(bjkl)
を実行するために、まったく同じ収縮ペアを使用することが可能であるべきだと思います。残念ながら、これはそうではありません、と私はnumpyの中に同じおもちゃのテンソルをテストしている
0 0 0 0 24
0 0 0 1 28
0 0 1 0 32
0 0 1 1 36
0 1 0 0 40
0 1 0 1 44
0 1 1 0 48
0 1 1 1 52
1 0 0 0 32
1 0 0 1 38
1 0 1 0 44
1 0 1 1 50
1 1 0 0 56
1 1 0 1 62
1 1 1 0 68
1 1 1 1 74
N
のこれらがある一方でM
の要素を使用して、
0 0 0 0 24
0 0 0 1 32
0 0 1 0 28
0 0 1 1 38
0 1 0 0 32
0 1 0 1 44
0 1 1 0 36
0 1 1 1 50
1 0 0 0 40
1 0 0 1 56
1 0 1 0 44
1 0 1 1 62
1 1 0 0 48
1 1 0 1 68
1 1 1 0 52
1 1 1 1 74
ですeinsum:
T = np.arange(16).reshape(2, 2, 2, 2)
A = np.arange(1, 5).reshape(2, 2)
contraction1 = np.einsum('ijkl,ia->ajkl', integrals, C)
contraction2 = np.einsum('ia,ijkl->ajkl', C, integrals)
およびcontraction1
およびcontraction2
は、
0 0 0 0 24
0 0 0 1 28
0 0 1 0 32
0 0 1 1 36
0 1 0 0 40
0 1 0 1 44
0 1 1 0 48
0 1 1 1 52
1 0 0 0 32
1 0 0 1 38
1 0 1 0 44
1 0 1 1 50
1 1 0 0 56
1 1 0 1 62
1 1 1 0 68
1 1 1 1 74
であり、EigenのケースA(ib)*T(ijkl)=N(bjkl)
と一致する。アイゲンは、どちらの場合も同じ結果をもたらさない原因は何ですか?
私はここに完全に間違っているかもしれないが、あなただけ収縮する軸を指定した場合、それは、注文残りの軸はで表示されますかが明確ではありません。あなたは完全に最初の引数によって、これを指定するnumpyの例では。おそらく、Eigenは最初のテンソルの生き残り軸を最初に、次に2番目のテンソルの生存軸の順番に保つでしょうか? –
@PaulPanzerその洞察的な答えをくれてありがとう。 'M'の軸を' Mshuffle(Eigen :: array {3、0、1、2}) 'としてシャッフルすると、' M_shuffled = = N).all() 'は値1につながります。つまり、要素ごとに等価です。私はそれを受け入れることができるように答えとしてあなたのコメントを(おそらくこのコメントを含む?)与えることができますか? –
lelemmen
私は数分します。 –