get_reduction builds the operators of Extraction and embedding for every
weight and channel in one call. For each (ell, p) it gives the embedding operator
under "embedding" and the extraction operator under
"extraction", and it takes the same ell, symmetry and basis arguments.
Reducing a rank-2 tensor extracts each ICT and embeds it back into the part of the tensor it carries:
import numpy as np
from natto import act, evaluate, get_reduction
T = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 12.0]])
reduction = get_reduction(n=2)
for (ell, p), operators in reduction.items():
G = operators["embedding"]
G_tilde = operators["extraction"]
X = act(G_tilde, T)
T_part = act(G, X)
print(f"--- weight {ell}, channel {p} ---")
print(f"G~: {G_tilde}")
print(f"G: {G}")
print(f"X, the ICT:\n{X}")
print(f"G · X, the part of T:\n{T_part}\n")--- weight 0, channel 1 ---
G~: +1/3 δ_AB
G: +1 δ_AB
X, the ICT:
6.0
G · X, the part of T:
[[6. 0. 0.]
[0. 6. 0.]
[0. 0. 6.]]
--- weight 1, channel 1 ---
G~: +1/2 ε_ABa
G: +1 ε_ABa
X, the ICT:
[-1. 2. -1.]
G · X, the part of T:
[[ 0. -1. -2.]
[ 1. 0. -1.]
[ 2. 1. 0.]]
--- weight 2, channel 1 ---
G~: +1/2 δ_Aa δ_Bb +1/2 δ_Ab δ_Ba -1/3 δ_AB δ_ab
G: +1/2 δ_Aa δ_Bb +1/2 δ_Ab δ_Ba -1/3 δ_AB δ_ab
X, the ICT:
[[-5. 3. 5.]
[ 3. -1. 7.]
[ 5. 7. 6.]]
G · X, the part of T:
[[-5. 3. 5.]
[ 3. -1. 7.]
[ 5. 7. 6.]]
The three parts are times the identity, the
antisymmetric part and the symmetric traceless part, and they sum to T.
The same reduction with arrays and einsum rules, each operator evaluated once:
for (ell, p), operators in reduction.items():
G_array, G_rule = evaluate(operators["embedding"])
G_tilde_array, G_tilde_rule = evaluate(operators["extraction"])
X = np.einsum(G_tilde_rule, G_tilde_array, T)
T_part = np.einsum(G_rule, G_array, X)
print(f"--- weight {ell}, channel {p} ---")
print(f"rule of G~: {G_tilde_rule}")
print(f"rule of G: {G_rule}")
print(f"G · X, the part of T:\n{T_part}\n")--- weight 0, channel 1 ---
rule of G~: AB,...AB->...
rule of G: AB,...->...AB
G · X, the part of T:
[[6. 0. 0.]
[0. 6. 0.]
[0. 0. 6.]]
--- weight 1, channel 1 ---
rule of G~: aAB,...AB->...a
rule of G: aAB,...a->...AB
G · X, the part of T:
[[ 0. -1. -2.]
[ 1. 0. -1.]
[ 2. 1. 0.]]
--- weight 2, channel 1 ---
rule of G~: abAB,...AB->...ab
rule of G: abAB,...ab->...AB
G · X, the part of T:
[[-5. 3. 5.]
[ 3. -1. 7.]
[ 5. 7. 6.]]