The coupling operator takes an ICT of weight and an ICT
of weight to the weight- part of their
product, the Cartesian counterpart of a Clebsch-Gordan coefficient. takes
and as its two inputs, so is act(K, X, Y).
Two vectors, ICTs of weight 1, couple to weight 2, a symmetric traceless matrix:
import numpy as np
from natto import act, get_coupling_operator
X = np.array([1.0, 0.0, 0.0])
Y = np.array([0.0, 1.0, 0.0])
K = get_coupling_operator(1, 1, 2)
Z = act(K, X, Y)
print(f"K from weights 1 and 1 to 2: {K}\n")
print(f"Z = K · X Y:\n{Z}")K from weights 1 and 1 to 2: +3/4 δ_Aa δ_Bb +3/4 δ_Ab δ_Ba -1/2 δ_AB δ_ab
Z = K · X Y:
[[0. 0.75 0. ]
[0.75 0. 0. ]
[0. 0. 0. ]]
As with the other operators, act evaluates into an array and contracts it with
its inputs by numpy.einsum. evaluate gives the array and the rule, with one operand
for and one for :
from natto import evaluate
K_array, rule = evaluate(K)
Z = np.einsum(rule, K_array, X, Y)
print(f"einsum rule: {rule}\n")
print(f"Z = K · X Y:\n{Z}")einsum rule: abAB,...A,...B->...ab
Z = K · X Y:
[[0. 0.75 0. ]
[0.75 0. 0. ]
[0. 0. 0. ]]
By default, normalize="legendre", the scale of is fixed so that, for even
, the Cartesian harmonics of one direction
couple to the harmonic of that direction. normalize="none" leaves unscaled.