Skip to content

Connor1y/spintensor

Repository files navigation

SpinTensor

A Python library for constructing linear constraints on tensors under transformations using Kronecker products. Supports operation-dependent T-parity, P-parity, and index-permutation symmetries, with automatic nullspace computation via SVD and LaTeX output.

Overview

This library constructs linear constraints for order-r tensors in dimension n under spin-group operations (Rs, Rr) of the form:

Tᵢ₁…ᵢᵣ = sign_T · sign_P · Rrᵢ₁ⱼ₁ … Rrᵢᵣⱼᵣ Tⱼ₁…ⱼᵣ

where the per-operation sign factors are computed from matrix determinants:

sign_T = det(Rs) ** T_constraint
sign_P = det(Rr) ** P_constraint
  • Rs is the spin-space matrix: det(Rs) = -1 contributes an effective time-reversal sign for T-odd tensors (T_constraint = 1).
  • Rr is the real-space matrix applied to every tensor axis: det(Rr) = -1 contributes a parity sign for P-odd tensors (P_constraint = 1).
  • The real-space action Rr ⊗ Rr ⊗ ... ⊗ Rr always drives the tensor transformation; Rs only contributes a sign.

The library builds constraint matrices, computes their nullspace using SVD (not row reduction), and outputs readable LaTeX relations with automatic index-to-symbol mapping.

Installation

pip install spintensor

Or install in development mode:

pip install -e .

Features

  • Operation-Dependent Sign Logic: Per-operation sign factors sign_T = det(Rs)**T_constraint and sign_P = det(Rr)**P_constraint (not global fixed values)
  • Kronecker Product Transformations: Efficiently build transformation matrices using Kronecker products of the real-space matrix Rr
  • T-parity and P-parity: Support for time reversal and spatial parity symmetries
  • Index Permutation Symmetries: Handle symmetric, antisymmetric, and general permutation symmetries
  • SVD-based Nullspace: Numerically stable nullspace computation using Singular Value Decomposition
  • LaTeX Output: Automatic generation of readable constraint relations with smart index notation

Quick Start

import numpy as np
from spintensor import solve_tensor_constraints

# Define operations in [Rs, Rr] format
# Rs: spin-space matrix; Rr: real-space matrix
n = 3  # dimension
r = 2  # tensor rank

# Spin reflection (det(Rs) = -1) in spin space, identity in real space
Rs = np.diag([1., 1., -1.])  # det = -1
Rr = np.eye(3)               # det = +1

# T-odd tensor: sign_T = det(Rs)**1 = -1
A, nullspace, relations, components = solve_tensor_constraints(
    [[Rs, Rr]], n, r, T_constraint=1, P_constraint=0
)

print(f"Independent components: {nullspace.shape[1]}")
for rel in relations:
    print(f"  {rel}")

Input Formats

All transformation formats are supported. The [Rs, Rr] format is the primary API for the new per-operation sign convention:

Format 1: [Rs, Rr] (recommended)

# Each entry is [spin_matrix, real_space_matrix]
transformations = [
    [Rs1, Rr1],  # sign_T = det(Rs1)**T_constraint, sign_P = det(Rr1)**P_constraint
    [Rs2, Rr2],
]

With spin_axes set, Rs is also applied to the specified tensor axes.

Format 2: [Tflag, Rr] (explicit anti-unitary flag)

# Tflag=True means the operation is anti-unitary (contributes sign_T=-1 when T_constraint=1)
transformations = [
    [False, Rr_unitary],    # sign_T = +1
    [True, Rr_antiunitary], # sign_T = -1
]

Format 3: Rr only (no spin component)

# Single numpy array: treated as Rs = identity (det=+1, no T sign)
transformations = [Rr1, Rr2]  # sign_T = +1 always

Format 4: Legacy (R, s_T, s_P) tuple

# Explicit parity values (backward compatible)
transformations = [(R, s_T, s_P)]

API Reference

Main Function

solve_tensor_constraints(transformations, n, r, symmetries=None, antisymmetries=None, tol=1e-10, spin_axes=None, T_constraint=0, det_tol=1e-6, symbol='\\sigma', extra_constraints=None, P_constraint=0)

Complete solver for tensor constraints.

Parameters:

  • transformations: List of transformations in any supported format
  • n: int, dimension of the tensor space
  • r: int, order (rank) of the tensor
  • symmetries: list of tuples, optional index permutations for symmetric constraints (T_perm = T)
  • antisymmetries: list of tuples, optional index permutations for antisymmetric constraints (T_perm = -T)
  • tol: float, tolerance for numerical operations
  • spin_axes: optional tuple of axis indices for spin axes (used with [Rs, Rr] format)
  • T_constraint: int, exponent for time-reversal sign. sign_T = det(Rs)**T_constraint. Use 1 for T-odd tensors (default 0)
  • P_constraint: int, exponent for parity sign. sign_P = det(Rr)**P_constraint. Use 1 for P-odd/axial tensors (default 0)
  • det_tol: float, tolerance for determinant comparison to ±1

Returns:

  • constraint_matrix: numpy array, full constraint matrix
  • nullspace_basis: numpy array, columns are basis vectors
  • latex_relations: list of strings, formatted LaTeX relations
  • tensor_components: nested list of component expressions

Convenience Functions

solve_qmd(transformations, n=3, tol=1e-10)

Solve for QMD (quadrupole moment derivative) tensors: T-odd, rank-3, with last-two-index symmetry.

solve_imd(transformations, n=3, tol=1e-10)

Solve for IMD tensors: T-odd, rank-3, with both last-two and first-two index symmetry.

solve_bcd(transformations, n=3, tol=1e-10, use_cyclic_constraint=True)

Solve for BCD (Berry curvature dipole) tensors: T-even, rank-3, with last-two-index symmetry and optional cyclic sum constraint.

Core Functions

build_constraint_matrix(transformations, n, r, ...)

Build the full constraint matrix from transformations and symmetries.

compute_nullspace_svd(A, tol=1e-10)

Compute nullspace of matrix A using SVD.

format_latex_relations(nullspace, n, r, tol=1e-10)

Format nullspace basis vectors as readable LaTeX relations.

Examples

Example 1: AHE Conductivity (T-odd, polar, rank-2)

import numpy as np
from spintensor import solve_tensor_constraints

# Operations in [Rs, Rr] format
# T-odd tensor: sign_T = det(Rs)**1

ops = [
    [np.diag([1., 1.,  1.]), np.diag([1., 1., 1.])],   # identity
    [np.diag([1., 1., -1.]), np.diag([1., 1.,-1.])],   # z-mirror: det(Rs)=-1 → s_T=-1
]

A, nullspace, relations, comps = solve_tensor_constraints(
    ops, n=3, r=2, T_constraint=1, P_constraint=0
)

print(f"Independent components: {nullspace.shape[1]}")

Example 2: QMD Tensor with Spin-Group Operations

import numpy as np
from spintensor import solve_qmd

# Operations in [Rs, Rr] format
# Mirror op: det(Rs) = -1 → T-odd sign applies
s = np.sqrt(3) / 2
ops = [
    [np.eye(3), np.eye(3)],
    [np.array([[-0.5, s, 0], [s, 0.5, 0], [0, 0, 1]]),
     np.array([[-0.5, s, 0], [s, 0.5, 0], [0, 0, 1]])],
    # ... more operations
]

A, nullspace, relations, comps = solve_qmd(ops)

Example 3: P-odd (Axial) Tensor

import numpy as np
from spintensor import solve_tensor_constraints

# P_constraint=1: sign_P = det(Rr)**1
# For a reflection with det(Rr)=-1, this adds a -1 sign factor
R_reflect = np.diag([1., 1., -1.])

A, nullspace, relations, comps = solve_tensor_constraints(
    [[np.eye(3), R_reflect]], n=3, r=2,
    T_constraint=0, P_constraint=1
)

Example 4: Legacy Format (Backward Compatible)

import numpy as np
from spintensor import solve_tensor_constraints

R_z = np.array([[-1, 0, 0], [0, -1, 0], [0, 0, 1]])

# Legacy tuple format: (R, s_T, s_P) — explicit parity values
transformations = [(R_z, 1.0, 1.0)]
A, nullspace, relations, comps = solve_tensor_constraints(
    transformations, n=3, r=2, symmetries=[(1, 0)]
)

Mathematical Background

Operation-Dependent Sign Logic

For each operation (Rs, Rr), the transformation matrix acting on the flattened tensor is:

M = sign_T · sign_P · (Rr ⊗ Rr ⊗ ... ⊗ Rr)

where:

sign_T = det(Rs) ** T_constraint
sign_P = det(Rr) ** P_constraint

The constraint for a symmetry-invariant tensor is (M - I) · T = 0.

Physical interpretation:

  • det(Rs) = -1: The spin-space operation flips the spin (effective time-reversal character). For T-odd tensors (T_constraint=1), this contributes a factor of -1.
  • det(Rr) = -1: The real-space operation is an improper rotation (parity-odd). For P-odd/axial tensors (P_constraint=1), this contributes a factor of -1.
  • These factors are per-operation — each operation in the symmetry group can independently flip or not flip each parity sign.

Index Symmetries

Index permutation symmetries impose additional constraints:

(P_perm - I) · T = 0   (symmetric)
(P_perm + I) · T = 0   (antisymmetric)

Nullspace Computation

The solution space consists of all tensors satisfying the constraints. This is the nullspace of the combined constraint matrix A, computed via SVD:

A = U · Σ · Vᵀ

The nullspace is spanned by columns of V corresponding to zero singular values. The basis is further reduced to RREF form for clean, canonical coefficients.

Output Format

Relations are output in LaTeX format with automatic index notation:

  • For n ≤ 4: uses letters (x, y, z, w)
  • For n > 4: uses numbers (1, 2, 3, ...)

Example output:

\sigma_{xxy} = \sigma_{xyx} = \sigma_{yxx} = -\sigma_{yyy}
\sigma_{xyz} = \sigma_{xzy} = -\sigma_{yxz} = -\sigma_{yzx}

Requirements

  • Python ≥ 3.7
  • NumPy ≥ 1.19.0

License

MIT License

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Citation

If you use this library in your research, please cite:

@software{spintensor,
  title = {SpinTensor: Linear Constraints for Tensors Under Transformations},
  author = {Connor1y},
  year = {2026},
  url = {https://github.com/Connor1y/spintensor}
}

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors