Skip to content

_invariants

Pure-python rotation-invariant descriptors of spherical harmonic coefficients.

Public functions match the previous cython module:

  • p_invariants_c(coeffs) — invariants from a complex SHT coefficient vector
  • p_invariants_r(coeffs) — invariants from a real (m >= 0) coefficient vector
  • clebsch_gordan(l1, m1, l2, m2, l, m) — convenience wrapper

The Racah formula for Clebsch-Gordan coefficients is computed in scalar python with an LRU cache so that repeated triples in the invariant loops are free after the first call. lmax is typically <= 20 for shape descriptors so even without vectorisation this runs in a few ms.

References

Brink & Satchler, "Angular Momentum", Oxford, 1968 (Racah formula) Burel & Henocq, "Three-dimensional invariants and their application to object recognition", Sig. Proc. 45 (1995) 1-22 (P-invariants)

clebsch_gordan(l1, m1, l2, m2, l, m)

Clebsch-Gordan coefficient ⟨l1 m1; l2 m2 | l m⟩.

Source code in chmpy/shape/_invariants.py
def clebsch_gordan(l1: int, m1: int, l2: int, m2: int, l: int, m: int) -> float:
    """Clebsch-Gordan coefficient ⟨l1 m1; l2 m2 | l m⟩."""
    return _clebsch_doubled(2 * l1, 2 * m1, 2 * l2, 2 * m2, 2 * l, 2 * m)

p_invariants_c(coeffs)

P-invariants from a complex SHT coefficient vector (length (lmax+1)^2).

Source code in chmpy/shape/_invariants.py
def p_invariants_c(coeffs):
    """P-invariants from a complex SHT coefficient vector (length (lmax+1)^2)."""
    coeffs = np.asarray(coeffs, dtype=np.complex128)
    l_max = int(round(np.sqrt(len(coeffs)))) - 1
    return _p_invariants_impl(coeffs, l_max, real=False)

p_invariants_r(coeffs)

P-invariants from a real (m >= 0) SHT coefficient vector.

Source code in chmpy/shape/_invariants.py
def p_invariants_r(coeffs):
    """P-invariants from a real (m >= 0) SHT coefficient vector."""
    coeffs = np.asarray(coeffs, dtype=np.complex128)
    n = len(coeffs)
    l_max = int((-3 + np.sqrt(8 * n + 1)) // 2)
    return _p_invariants_impl(coeffs, l_max, real=True)