TensorExpression
TensorExpression
class TensorExpressionA symbolic tensor expression with an ordered set of external axes.
Construct tensors from TensorName and Representation objects, or wrap a Symbolica expression whose tensor structure can be inferred. Scalar tensors have rank zero. Components are obtained separately through to_tensor.
Products contract matching explicit indices and unambiguous compatible unresolved axes. Use outer to keep axes independent, contract_ports to choose a contraction, or compose to choose matrix channels. Arithmetic with Tensor or TensorNetwork operands returns a TensorNetwork.
Reductions preserve this tensor type and keep unrelated sums factorized. Ordinary algebra, including expand_num(), collect_factors(), and factor(), also returns a tensor expression with its ordered interface. This is a Symbolica Expression subclass: inspection, matching, evaluators, and other unoverridden methods are inherited directly. Inherited transformations return ordinary expressions; the tensor-aware overrides retain the interface. Use to_expression() to explicitly drop the tensor interface.
Pass intern="indices" to reversibly encode compound index labels, or intern="flattened" to create readable names. Both modes operate only on index payloads. An explicit structure retains the declared axis order and can describe the interface of a symbolic zero.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(3)
A = TensorName("A")(space, space)
indexed = A("i", "j")
indexed.rank
2Attributes
| Name | Description |
|---|---|
arguments |
Scalar arguments identifying the named tensor. |
axes |
External axes in the current component and port-position order. |
contraction_complete |
Whether symbolic metric/vector contraction is certified complete. |
is_scalar |
Whether the tensor has no external axes. |
name |
Optional name identifying stored tensor data. |
rank |
Number of external tensor axes. |
reduction_status |
Report completion under the last reduction settings and budget. |
shape |
Dimensions in logical axis order. |
structure |
Canonical external signature of the whole expression. |
arguments
TensorExpression.arguments: tuple[Expression, ...]Scalar arguments identifying the named tensor.
Returns
tuple of ExpressionScalar key arguments in their original order; empty for an unnamed expression. These belong to the expression, not its external signature.
Examples
from symbolica import S
from symbolica.community.tensor import Representation, TensorName
x = S("x")
A = TensorName("A")(x, 7, Representation.euc(3))
A.arguments == (x, 7)
Trueaxes
TensorExpression.axes: tuple[Slot | Representation, ...]External axes in the current component and port-position order.
Returns
tuple of Slot or RepresentationIndexed or unresolved axes, respectively. Component coordinates and methods taking axis positions use this order. It follows construction and explicit permute_axes() calls; structure.axes instead gives the canonical signature.
Examples
from symbolica.community.tensor import Representation, TensorName
r = Representation.euc(3)
A = TensorName("A")(r("j"), r("i"))
A.axes == (r("j"), r("i"))
True
A.permute_axes([1, 0]).axes == A.axes[::-1]
Truecontraction_complete
TensorExpression.contraction_complete: builtins.boolWhether symbolic metric/vector contraction is certified complete.
Returns
boolFalse also covers a value not yet contracted or stopped before completion.
Examples
from symbolica.community.tensor import TensorExpression
TensorExpression(3).contract().contraction_complete
Trueis_scalar
TensorExpression.is_scalar: builtins.boolWhether the tensor has no external axes.
Returns
boolTrue exactly when rank is zero.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(3)
A = TensorName("A")(space, space)
A.is_scalar
Falsename
TensorExpression.name: typing.Optional[TensorName]Optional name identifying stored tensor data.
Returns
TensorName or NoneComposite expressions may have no name.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(3)
A = TensorName("A")(space, space)
name = A.namerank
TensorExpression.rank: builtins.intNumber of external tensor axes.
Returns
intZero for a scalar.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(3)
A = TensorName("A")(space, space)
A.rank
2reduction_status
TensorExpression.reduction_status: ReductionStatusReport completion under the last reduction settings and budget.
Returns
ReductionStatusComplete, Deferred, or Capped. Unfinished results remain exact and can be passed to contract() or simplify_algebra() again.
Examples
from symbolica.community.tensor import TensorExpression, ReductionStatus
TensorExpression(3).contract().reduction_status == ReductionStatus.Complete
Trueshape
TensorExpression.shape: tuple[int | Expression, ...]Dimensions in logical axis order.
Returns
tuple of int or ExpressionConcrete dimensions are integers; symbolic dimensions remain expressions.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(3)
A = TensorName("A")(space, space)
A.shape
(3, 3)structure
TensorExpression.structure: TensorStructureCanonical external signature of the whole expression.
Returns
TensorStructureImmutable signature in canonical order. Inspect this to determine rank, representations, or existing index labels.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(3)
A = TensorName("A")(space, space)
A.structure.shape
(3, 3)Methods
| Name | Description |
|---|---|
__add__ |
Add tensors with compatible external interfaces. |
__bool__ |
Test whether the symbolic tensor expression is nonzero. |
__call__ |
Assign labels to the unresolved external axes. |
__copy__ |
Copy the expression and its tensor metadata. |
__deepcopy__ |
Copy the tensor’s immutable expression, ordered axes, and data metadata. |
__eq__ |
Compare normalized expressions and their ordered tensor interfaces for equality |
__getitem__ |
Convert between flat component positions and coordinates. |
__hash__ |
Hash the immutable tensor value for use in dictionaries and sets |
__len__ |
Count all components in the tensor shape. |
__mul__ |
Multiply by an extension operand with its own multiplication result type. |
__ne__ |
Test whether normalized expressions or their ordered tensor interfaces differ. |
__neg__ |
Negate every tensor component. |
__new__ |
Wrap symbolic algebra as a tensor and check its external axes. |
__pow__ |
Raise tensor algebra to a scalar power. |
__radd__ |
Implement reflected addition. |
__reduce__ |
Reject pickling that would silently discard the ordered tensor interface |
__repr__ |
Return a readable object description for inspection. |
__rmul__ |
Implement reflected multiplication. |
__rpow__ |
Use a scalar tensor expression as an exponent. |
__rsub__ |
Implement reflected subtraction. |
__rtruediv__ |
Implement reflected division. |
__str__ |
Return a readable text representation. |
__sub__ |
Subtract tensors with compatible external interfaces. |
__symbolica_rmul__ |
Preserve the tensor type when a Symbolica expression multiplies this tensor. |
__truediv__ |
Divide tensor components by a scalar expression. |
_display_ |
Return marimo’s notebook presentation with bounded pages for large expressions. |
_repr_html_ |
|
_repr_latex_ |
|
_repr_mimebundle_ |
Return the rich representations requested by a Jupyter frontend. |
_repr_pretty_ |
|
apart |
Decompose scalar denominators into partial fractions, retaining the tensor interface. |
cancel |
Cancel common numerator and denominator factors, retaining ordered ports and metadata |
canonize |
Canonicalize tensor factors and dummy-index labels. |
charge_conjugation |
Construct the Dirac charge-conjugation matrix. |
collect |
Collect terms in variables or functions, retaining the tensor interface. |
collect_by_coefficient |
Group terms with equal numerical coefficients, retaining ordered ports and metadata. |
collect_factors |
Collect common factors from nested sums without applying tensor identities |
collect_horner |
Rewrite polynomial algebra in Horner form, retaining ordered ports and metadata. |
collect_num |
Extract common numerical coefficients from sums, retaining ordered ports and metadata |
collect_symbol |
Collect terms by powers of a variable or calls with the same function head. |
color_f |
Construct the antisymmetric color structure constants f^{abc}. |
color_t |
Construct the fundamental color generators T^a. |
components |
Evaluate this tensor and return its flat component list. |
compose |
Multiply two tensors along explicitly selected matrix channels. |
contract |
Contract compatible indices without applying tensor-algebra identities |
contract_ports |
Contract one chosen pair of axes between two tensors. |
derivative |
Differentiate scalar coefficients, preserving tensor zeros and ports |
dirac_adjoint |
Construct the Dirac adjoint of a spinor tensor expression. |
dirac_gamma |
Construct the Dirac gamma matrices for Clifford algebra. |
expand |
Distribute scalar products and powers over sums. |
expand_num |
Distribute numerical coefficients over sums without expanding symbolic products |
expand_projectors |
Expand normalized factor groups into their permutation sums. |
factor |
Factor scalar algebra while retaining ordered tensor ports and data metadata |
flat |
Construct the metric map for raising or lowering an index. |
format_tensor |
Produce compact plain-text tensor notation. |
formatted |
Create a lazy rich display value for a notebook. |
g |
Construct the metric pairing, optionally with explicit indices. |
gamma0 |
Construct the time-component Dirac matrix gamma^0. |
gamma5 |
Construct the Dirac chirality matrix gamma^5. |
index |
Assign labels to the unresolved external axes. |
is_expanded |
Test whether products and powers are expanded, optionally with respect to var |
is_one |
Test whether the expression is exactly the scalar one. |
is_zero |
Test whether the expression is exactly zero, including zeros with nonzero tensor rank |
levi_civita |
Construct the totally antisymmetric Levi-Civita tensor. |
list_dangling |
List the external indices that are not summed over. |
map |
Apply a Symbolica Transformer and retain the validated tensor interface. |
nterms |
Count top-level additive terms without expanding the expression |
outer |
Form an outer product without implicit contractions between the operands. |
paged |
Create a bounded, interactive MathML viewer in marimo or Jupyter |
permute_axes |
Reorder the external axes in logical component order. |
projm |
Construct the left-chiral Dirac projector (I - gamma^5)/2. |
projp |
Construct the right-chiral Dirac projector (I + gamma^5)/2. |
reindex |
Assign labels to all external axes. |
rename_indices |
Rename selected external labels without changing the tensor rank. |
replace |
Replace symbolic patterns or apply whole-tensor replacement rules. |
replace_multiple |
Apply simultaneous Symbolica replacements and validate the resulting tensor. |
sigma |
Construct the antisymmetric Dirac sigma tensor. |
simplify_algebra |
Reduce enabled tensor identities and their required index contractions |
to_dots |
Write compact metric products using dot notation. |
to_expression |
Return ordinary Symbolica algebra without the tensor interface. |
to_html |
Render the tensor as an HTML fragment. |
to_latex |
Produce LaTeX for the symbolic tensor expression. |
to_network |
Build an executable network for this symbolic tensor. |
to_svg |
Render static mathematical tensor notation to SVG. |
to_tensor |
Evaluate this expression and return its components. |
to_typst |
Produce static Typst math source. |
together |
Combine scalar denominators into one fraction, retaining ordered ports and metadata |
trace |
Close a pair of matrix axes on this tensor. |
undo_chain |
Expose collected chain factors with fresh compatible dummy indices. |
undo_dots |
Write dot products as explicit indexed contractions. |
undo_trace |
Open compact traces as closed chains without evaluating them. |
with_lorentz_dimension |
Replace four-dimensional Minkowski index spaces by a supplied dimension. |
with_name |
Assign a data identity without rewriting the symbolic computation. |
wrap_indices |
Give explicit indices a scope that separates them from other copies. |
__add__
TensorExpression.__add__(rhs: TensorExpression | _ScalarInput) -> TensorExpression
TensorExpression.__add__(rhs: typing.Union[Tensor, TensorNetwork]) -> TensorNetworkAdd tensors with compatible external interfaces.
Parameters
rhs(scalar expression, TensorExpression, Tensor, or TensorNetwork) Other operand. Component data are retained in a lazy network.
Returns
TensorExpression or TensorNetworkSymbolic operands return TensorExpression; component-bearing operands return TensorNetwork.
Notes
Scalar zero acts as the additive identity. Other scalars can be added only to rank-zero tensors.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
result = A + A__bool__
TensorExpression.__bool__() -> builtins.boolTest whether the symbolic tensor expression is nonzero.
Examples
from symbolica.community import tensor as sp
r = sp.Representation.euc(2)
A = sp.TensorName("docs::A")(r, r)
nonzero = bool(A)__call__
TensorExpression.__call__(
*indices: _IndexInput,
intern: typing.Optional[typing.Literal['indices', 'flattened']] = None,
) -> TensorExpressionAssign labels to the unresolved external axes.
Parameters
*indices(int, str, Expression, Slot, or AUTO) One label per unresolved axis, in logical order. AUTO leaves the corresponding axis unchanged. A Slot must have the matching representation. Repeated compatible labels cause contraction.intern({“indices”, “flattened”} or None, optional) Encode compound index labels before checking the tensor structure. “indices” retains reversible payloads; “flattened” creates readable names. Both preserve index tags and leave scalar arguments and tensor heads intact. None leaves labels unchanged and requires ordinary atomic index labels.
Returns
TensorExpressionAn indexed expression.
Notes
Equivalent to index(*indices).
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
indexed = A("i", "j")
indexed.rank
2__copy__
TensorExpression.__copy__() -> TensorExpressionCopy the expression and its tensor metadata.
Returns
TensorExpressionA copy with the same ordered axes and optional data name.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
import copy
copy.copy(A).shape
(2, 2)__deepcopy__
TensorExpression.__deepcopy__(memo: dict) -> TensorExpressionCopy the tensor’s immutable expression, ordered axes, and data metadata.
Parameters
memo(dict) Copy bookkeeping maintained by Python’s copy module.
Returns
TensorExpressionIndependent Python wrapper sharing the immutable tensor value.
Examples
import copy
from symbolica.community.tensor import Representation, TensorName
A = TensorName("A")(Representation.euc(3))
zero = 0 * A
assert copy.deepcopy(zero).structure == zero.structure__eq__
TensorExpression.__eq__(other: typing.Any) -> builtins.boolCompare normalized expressions and their ordered tensor interfaces for equality. For a comparison to a plain Symbolica expression, first use .to_expression().
Examples
from symbolica.community import tensor as sp
r = sp.Representation.euc(2)
A = sp.TensorName("docs::A")(r, r)
assert A == sp.TensorExpression(A)Parameters
other(object) TensorExpression to compare. Values without an ordered tensor interface are unequal.
__getitem__
TensorExpression.__getitem__(item: builtins.int) -> builtins.list[builtins.int]
TensorExpression.__getitem__(item: typing.Sequence[builtins.int]) -> builtins.int
TensorExpression.__getitem__(item: builtins.slice) -> builtins.list[builtins.list[builtins.int]]Convert between flat component positions and coordinates.
Parameters
item(int, sequence of int, or slice) A nonnegative flat position, coordinates in logical axis order, or a slice of flat positions. All axis dimensions must be concrete.
Returns
int, list of int, or list of lists of intCoordinates for a flat position, a flat position for coordinates, or a coordinate list for a slice. No component values are evaluated.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
A[2]
[1, 0]
A[1, 0]
2__hash__
TensorExpression.__hash__() -> builtins.intHash the immutable tensor value for use in dictionaries and sets. Equal tensor expressions have equal hashes, including their ordered interfaces.
Examples
from symbolica.community import tensor as sp
r = sp.Representation.euc(2)
A = sp.TensorName("docs::A")(r, r)
labels = {A: "matrix A"}
assert labels[sp.TensorExpression(A)] == "matrix A"__len__
TensorExpression.__len__() -> builtins.intCount all components in the tensor shape.
Returns
intProduct of the axis dimensions, including implicit zeros; dimensions must be concrete.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
len(A)
4__mul__
__mul__ has 3 variants:
__mul__ returning _ProductT
TensorExpression.__mul__(rhs: symbolica.core._ExpressionProduct[_ProductT]) -> _ProductTMultiply by an extension operand with its own multiplication result type.
Parameters
rhs(extension operand) Implements__symbolica_rmul__(left). The tensor is passed unchanged as the left operand, so the extension can access its tensor structure.
Returns
extension resultThe result declared by the extension’s multiplication method.
Examples
from symbolica import Expression
from symbolica.community.tensor import Representation, TensorName
class Product:
def __symbolica_rmul__(self, left: Expression) -> tuple[Expression, str]:
return left, "product"
vector = TensorName.vector("v")(Representation.euc(2))
result, label = vector * Product()
label
'product'__mul__ returning TensorExpression
TensorExpression.__mul__(rhs: TensorExpression | _ScalarInput) -> TensorExpressionMultiply tensors, contracting unambiguous compatible axes.
Parameters
rhs(scalar expression, TensorExpression, Tensor, or TensorNetwork) Other operand. Component data are retained in a lazy network.
Returns
TensorExpression or TensorNetworkSymbolic operands return TensorExpression; component-bearing operands return TensorNetwork.
Notes
Matching explicit labels contract. Compatible unresolved axes are paired to maximize the number of contractions. Among equally complete pairings, unresolved-unresolved pairs take precedence over unresolved-named pairs; equally preferred alternatives raise an ambiguity error. Established matrix channels retain their composition order. Use outer(), contract_ports(), or compose() to make the intended pairing explicit.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
result = A * 2__mul__ returning TensorNetwork
TensorExpression.__mul__(rhs: typing.Union[Tensor, TensorNetwork]) -> TensorNetworkMultiply tensors, contracting unambiguous compatible axes.
Parameters
rhs(scalar expression, TensorExpression, Tensor, or TensorNetwork) Other operand. Component data are retained in a lazy network.
Returns
TensorExpression or TensorNetworkSymbolic operands return TensorExpression; component-bearing operands return TensorNetwork.
Notes
Matching explicit labels contract. Compatible unresolved axes are paired to maximize the number of contractions. Among equally complete pairings, unresolved-unresolved pairs take precedence over unresolved-named pairs; equally preferred alternatives raise an ambiguity error. Established matrix channels retain their composition order. Use outer(), contract_ports(), or compose() to make the intended pairing explicit.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
result = A * 2__ne__
TensorExpression.__ne__(other: typing.Any) -> builtins.boolTest whether normalized expressions or their ordered tensor interfaces differ.
Examples
from symbolica.community import tensor as sp
r = sp.Representation.euc(2)
A = sp.TensorName("docs::A")(r, r)
assert A != 2 * AParameters
other(object) TensorExpression to compare. Values without an ordered tensor interface are unequal.
__neg__
TensorExpression.__neg__() -> TensorExpressionNegate every tensor component.
Returns
TensorExpressionNegated symbolic algebra with the same external axes.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
negated = -A__new__
TensorExpression.__new__(
expression: TensorExpression | _ScalarInput,
*,
structure: typing.Optional[TensorStructure] = None,
intern: typing.Optional[typing.Literal['indices', 'flattened']] = None,
) -> TensorExpressionWrap symbolic algebra as a tensor and check its external axes.
Parameters
expression(TensorExpression or scalar expression) Existing tensor, Symbolica Expression, or scalar convertible to one. Tensor syntax is inferred; an ordinary scalar has no external axes.structure(TensorStructure, optional) Canonical free-axis signature to check against the expression. It does not reorder arguments or component axes. For zero, it supplies the rank and axes that cannot be inferred from the scalar expression alone.intern({“indices”, “flattened”} or None, optional) Encode compound index labels before checking the tensor structure. “indices” retains reversible payloads; “flattened” creates readable names. Both preserve index tags and leave scalar arguments and tensor heads intact. None leaves labels unchanged and requires ordinary atomic index labels.
Returns
TensorExpressionA checked tensor expression, preserving existing metadata where possible.
Examples
from symbolica.community.tensor import TensorExpression, TensorStructure, Representation
zero = TensorExpression(0, structure=TensorStructure([Representation.euc(3)]))
zero.rank
1
from symbolica import S
from symbolica.community.tensor import TensorName
vector = TensorName.vector("v")(Representation.euc(3))
label, payload = S("i"), S("edge")(7, 2)
raw = vector(label).to_expression().replace(label, payload)
TensorExpression(raw, intern="indices").rank
1__pow__
TensorExpression.__pow__(
exponent: TensorExpression | _ScalarInput,
modulo: typing.Optional[typing.Any] = None,
) -> TensorExpressionRaise tensor algebra to a scalar power.
Parameters
exponent(TensorExpression or scalar expression) Scalar exponent.modulo(object, optional) Must be None; modular tensor powers are not supported.
Returns
TensorExpressionPowered tensor expression. A non-scalar base requires a nonnegative integer exponent and uses repeated tensor multiplication, including its contraction and ambiguity rules. This is not an elementwise power.
Examples
from symbolica.community.tensor import TensorExpression
squared = TensorExpression(3)**2
squared.to_expression() == 9
True__radd__
TensorExpression.__radd__(lhs: TensorExpression | _ScalarInput) -> TensorExpression
TensorExpression.__radd__(lhs: typing.Union[Tensor, TensorNetwork]) -> TensorNetworkImplement reflected addition.
Parameters
lhs(scalar expression, TensorExpression, Tensor, or TensorNetwork) Other operand. Component data are retained in a lazy network.
Returns
TensorExpression or TensorNetworkSymbolic operands return TensorExpression; component-bearing operands return TensorNetwork.
Notes
Scalar zero acts as the additive identity. Other scalars can be added only to rank-zero tensors.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
result = A + A__reduce__
TensorExpression.__reduce__() -> typing.NoReturnReject pickling that would silently discard the ordered tensor interface. Use to_expression() when explicitly serializing only the symbolic algebra.
Raises
TypeError: Tensor metadata serialization is not supported.
__repr__
TensorExpression.__repr__() -> builtins.strReturn a readable object description for inspection.
Examples
from symbolica.community import tensor as sp
r = sp.Representation.euc(2)
A = sp.TensorName("docs::A")(r, r)
text = repr(A)__rmul__
TensorExpression.__rmul__(lhs: TensorExpression | _ScalarInput) -> TensorExpression
TensorExpression.__rmul__(lhs: typing.Union[Tensor, TensorNetwork]) -> TensorNetworkImplement reflected multiplication.
Parameters
lhs(scalar expression, TensorExpression, Tensor, or TensorNetwork) Other operand. Component data are retained in a lazy network.
Returns
TensorExpression or TensorNetworkSymbolic operands return TensorExpression; component-bearing operands return TensorNetwork.
Notes
Matching explicit labels contract. Compatible unresolved axes are paired to maximize the number of contractions. Among equally complete pairings, unresolved-unresolved pairs take precedence over unresolved-named pairs; equally preferred alternatives raise an ambiguity error. Established matrix channels retain their composition order. Use outer(), contract_ports(), or compose() to make the intended pairing explicit.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
result = 2 * A__rpow__
TensorExpression.__rpow__(
base: TensorExpression | _ScalarInput,
modulo: typing.Optional[typing.Any] = None,
) -> TensorExpressionUse a scalar tensor expression as an exponent.
Parameters
base(TensorExpression or scalar expression) Scalar base.modulo(None, optional) Must be None; modular powers are not supported.
Returns
TensorExpressionScalar power with a checked tensor interface.
Examples
from symbolica.community.tensor import TensorExpression
result = 2**TensorExpression(3)
result.to_expression() == 8
True__rsub__
TensorExpression.__rsub__(lhs: TensorExpression | _ScalarInput) -> TensorExpression
TensorExpression.__rsub__(lhs: typing.Union[Tensor, TensorNetwork]) -> TensorNetworkImplement reflected subtraction.
Parameters
lhs(scalar expression, TensorExpression, Tensor, or TensorNetwork) Other operand. Component data are retained in a lazy network.
Returns
TensorExpression or TensorNetworkSymbolic operands return TensorExpression; component-bearing operands return TensorNetwork.
Notes
Subtraction requires matching tensor axes; a nonzero scalar cannot be subtracted from a tensor with external axes.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
result = A - A__rtruediv__
TensorExpression.__rtruediv__(lhs: TensorExpression | _ScalarInput) -> TensorExpression
TensorExpression.__rtruediv__(lhs: typing.Union[Tensor, TensorNetwork]) -> TensorNetworkImplement reflected division.
Parameters
lhs(scalar expression, TensorExpression, Tensor, or TensorNetwork) Other operand. Component data are retained in a lazy network.
Returns
TensorExpression or TensorNetworkSymbolic operands return TensorExpression; component-bearing operands return TensorNetwork.
Notes
The denominator must be scalar. For scalar divided by tensor, the tensor must also have rank zero.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
result = 2 / TensorExpression(3)__str__
TensorExpression.__str__() -> builtins.strReturn a readable text representation.
Examples
from symbolica.community import tensor as sp
r = sp.Representation.euc(2)
A = sp.TensorName("docs::A")(r, r)
text = str(A)__sub__
TensorExpression.__sub__(rhs: TensorExpression | _ScalarInput) -> TensorExpression
TensorExpression.__sub__(rhs: typing.Union[Tensor, TensorNetwork]) -> TensorNetworkSubtract tensors with compatible external interfaces.
Parameters
rhs(scalar expression, TensorExpression, Tensor, or TensorNetwork) Other operand. Component data are retained in a lazy network.
Returns
TensorExpression or TensorNetworkSymbolic operands return TensorExpression; component-bearing operands return TensorNetwork.
Notes
Subtraction requires matching tensor axes; a nonzero scalar cannot be subtracted from a tensor with external axes.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
result = A - A__symbolica_rmul__
TensorExpression.__symbolica_rmul__(lhs: Expression) -> TensorExpressionPreserve the tensor type when a Symbolica expression multiplies this tensor.
Parameters
lhs(Expression) Left operand; a tensor expression retains its tensor structure.
Returns
TensorExpressionThe same ordered product aslhs * self.
Examples
from symbolica import S
from symbolica.community.tensor import Representation, TensorName
vector = TensorName.vector("v")(Representation.euc(2))
(S("x") * vector).rank
1__truediv__
TensorExpression.__truediv__(rhs: TensorExpression | _ScalarInput) -> TensorExpression
TensorExpression.__truediv__(rhs: typing.Union[Tensor, TensorNetwork]) -> TensorNetworkDivide tensor components by a scalar expression.
Parameters
rhs(scalar expression, TensorExpression, Tensor, or TensorNetwork) Other operand. Component data are retained in a lazy network.
Returns
TensorExpression or TensorNetworkSymbolic operands return TensorExpression; component-bearing operands return TensorNetwork.
Notes
The denominator must be scalar. For scalar divided by tensor, the tensor must also have rank zero.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
result = A / 2_display_
TensorExpression._display_() -> typing.AnyReturn marimo’s notebook presentation with bounded pages for large expressions.
Returns
objectRich notebook output or an interactive viewer, using default settings.
_repr_html_
TensorExpression._repr_html_() -> typing.Optional[builtins.str]_repr_latex_
TensorExpression._repr_latex_() -> builtins.str_repr_mimebundle_
TensorExpression._repr_mimebundle_(
include: typing.Optional[typing.Sequence[builtins.str]] = None,
exclude: typing.Optional[typing.Sequence[builtins.str]] = None,
) -> typing.AnyReturn the rich representations requested by a Jupyter frontend.
Parameters
include, exclude(list of str, optional) MIME types to include or exclude from the returned representations.
Returns
objectMIME bundle for the complete small expression or paged large expression.
_repr_pretty_
TensorExpression._repr_pretty_(pretty: typing.Any, cycle: builtins.bool) -> Noneapart
TensorExpression.apart(*variables: symbolica.core.Expression) -> TensorExpressionDecompose scalar denominators into partial fractions, retaining the tensor interface.
Parameters
*variables(Expression) Variables for partial fractioning. Omit them to use all indeterminates, as in Expression.apart().
Returns
TensorExpressionPartial fractions with the original ordered ports and metadata.
Examples
from symbolica import S
from symbolica.community.tensor import TensorName, Representation
x = S("x")
A = TensorName("A")(Representation.euc(3))("i")
assert (A/(x*(x + 1))).apart(x) == A/x - A/(x + 1)cancel
TensorExpression.cancel() -> TensorExpressionCancel common numerator and denominator factors, retaining ordered ports and metadata. This is ordinary rational algebra and performs no tensor contractions.
Returns
TensorExpressionRational expression with common factors cancelled and the original tensor interface.
Examples
from symbolica import S
from symbolica.community.tensor import TensorName, Representation
x = S("x")
A = TensorName("A")(Representation.euc(3))("i")
assert ((x**2 - 1)/(x - 1)*A).cancel() == (x + 1)*Acanonize
TensorExpression.canonize() -> TensorExpressionCanonicalize tensor factors and dummy-index labels.
Returns
TensorExpressionAn equivalent expression with deterministically named contracted indices.
Raises
CanonicalizationError: The tensor expression cannot be canonicalized.
Notes
This identifies different spellings of the same dummy-index contractions; it is not a general polynomial simplifier.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
canonical = A("i", "j").canonize()
canonical.rank
2charge_conjugation
TensorExpression.charge_conjugation(spinor_dimension: builtins.int | Expression | str) -> TensorExpressionConstruct the Dirac charge-conjugation matrix.
Parameters
spinor_dimension(int, Expression, or str) Number of spinor components.
Returns
TensorExpressionA rank-2 symbolic tensor with distinct unresolved axes. Call the result with index labels to fill those axes in the order described below.
Notes
The axes are spinor row and column. The head is antisymmetric. The HEP libraries provide the four-component Weyl-basis convention.
Examples
from symbolica.community.tensor import TensorExpression, Representation
tensor = TensorExpression.charge_conjugation(4)
tensor.rank
2collect
TensorExpression.collect(
*x: symbolica.core.Expression,
key_map: typing.Optional[typing.Callable[[symbolica.core.Expression], symbolica.core.Expression]] = None,
coeff_map: typing.Optional[typing.Callable[[symbolica.core.Expression], symbolica.core.Expression]] = None,
) -> TensorExpressionCollect terms in variables or functions, retaining the tensor interface.
Parameters
*x(Expression) Variables or functions to collect in, with Expression.collect semantics.key_map, coeff_map(callable, optional) Map each collected key or coefficient. Callbacks receive and return ordinary Expressions. Their results must preserve this tensor’s ordered external ports; otherwise the operation raises ValueError. Zero retains the original interface.
Returns
TensorExpressionCollected expression with the original interface and metadata.
Examples
from symbolica import S
from symbolica.community.tensor import TensorName, Representation
x, y = S("x", "y")
A = TensorName("A")(Representation.euc(3))("i")
result = (x*A + x*y*A).collect(x)
assert result.expand() == (x*(1+y)*A).expand()collect_by_coefficient
TensorExpression.collect_by_coefficient() -> TensorExpressionGroup terms with equal numerical coefficients, retaining ordered ports and metadata.
Returns
TensorExpressionExpression grouped by numerical coefficient with the original tensor interface.
Examples
from symbolica import S
from symbolica.community.tensor import TensorExpression
x, y = S("x", "y")
result = TensorExpression(2*x + 2*y).collect_by_coefficient()
assert result.to_expression() == 2*(x + y)collect_factors
TensorExpression.collect_factors() -> TensorExpressionCollect common factors from nested sums without applying tensor identities. Ordered ports, unresolved axes, tensor zeros, and data metadata are retained.
Returns
TensorExpressionRewritten scalar algebra with the original tensor interface and metadata.
Examples
from symbolica import S
from symbolica.community.tensor import TensorName, Representation
x, y = S("x", "y")
A = TensorName("A")(Representation.euc(3))("i")
result = (x*A + y*A).collect_factors()
assert result == (x+y)*Acollect_horner
TensorExpression.collect_horner(vars: typing.Optional[typing.Sequence[Expression]] = None) -> TensorExpressionRewrite polynomial algebra in Horner form, retaining ordered ports and metadata.
Parameters
vars(list of Expression, optional) Variable order. Omit it to use Symbolica’s heuristic ordering.
Returns
TensorExpressionHorner-form expression with the original tensor interface.
Examples
from symbolica import S
from symbolica.community.tensor import TensorExpression
x, y = S("x", "y")
result = TensorExpression(x**2 + x*y).collect_horner([x, y])
assert result.to_expression() == x*(x + y)collect_num
TensorExpression.collect_num() -> TensorExpressionExtract common numerical coefficients from sums, retaining ordered ports and metadata. This reverses numerical distribution performed by expand_num().
Returns
TensorExpressionExpression with common numerical coefficients extracted.
Examples
from symbolica import S
from symbolica.community.tensor import TensorName, Representation
x, y = S("x", "y")
A = TensorName("A")(Representation.euc(3))("i")
assert ((2*x + 4*y)*A).collect_num() == 2*(x + 2*y)*Acollect_symbol
TensorExpression.collect_symbol(
x: Expression,
key_map: typing.Optional[typing.Callable[[symbolica.core.Expression], symbolica.core.Expression]] = None,
coeff_map: typing.Optional[typing.Callable[[symbolica.core.Expression], symbolica.core.Expression]] = None,
) -> TensorExpressionCollect terms by powers of a variable or calls with the same function head.
Parameters
x(Expression) Variable or function symbol to collect in.key_map, coeff_map(callable, optional) Map ordinary Expressions. As with collect(), the result is checked for preservation of the tensor’s ordered external ports.
Returns
TensorExpressionCollected expression with the original interface and metadata.
Examples
from symbolica import S
from symbolica.community.tensor import TensorName, Representation
x, f = S("x", "f")
A = TensorName("A")(Representation.euc(3))("i")
result = (f(x)*A + 2*f(x)*A).collect_symbol(f)
assert result.expand() == (3*f(x)*A).expand()color_f
TensorExpression.color_f(adjoint_dimension: builtins.int | Expression | str) -> TensorExpressionConstruct the antisymmetric color structure constants f^{abc}.
Parameters
adjoint_dimension(int, Expression, or str) Dimension of the adjoint representation, for example 8 for SU(3).
Returns
TensorExpressionA rank-3 symbolic tensor with distinct unresolved axes. Call the result with index labels to fill those axes in the order described below.
Notes
The axes are three adjoint indices (a, b, c). This dimension is the number of generators, not the dimension of the fundamental representation.
Examples
from symbolica.community.tensor import TensorExpression, Representation
tensor = TensorExpression.color_f(8)
tensor.rank
3color_t
TensorExpression.color_t(
adjoint_dimension: builtins.int | Expression | str,
fundamental_dimension: builtins.int | Expression | str,
) -> TensorExpressionConstruct the fundamental color generators T^a.
Parameters
adjoint_dimension(int, Expression, or str) Adjoint dimension, for example 8 for SU(3).fundamental_dimension(int, Expression, or str) Fundamental dimension, for example 3 for SU(3).
Returns
TensorExpressionA rank-3 symbolic tensor with distinct unresolved axes. Call the result with index labels to fill those axes in the order described below.
Notes
The axes are (adjoint, fundamental, antifundamental). The HEP libraries provide SU(3) generators; symbolic color identities retain representation invariants unless their substitution is requested.
Examples
from symbolica.community.tensor import TensorExpression, Representation
tensor = TensorExpression.color_t(8, 3)
tensor.rank
3components
TensorExpression.components(library: typing.Optional[TensorLibrary] = None) -> builtins.list[Expression | builtins.complex | builtins.float]Evaluate this tensor and return its flat component list.
Parameters
library(TensorLibrary, optional) Component definitions. Defaults to the built-in four-dimensional Dirac and SU(3) library. Unregistered tensors receive symbolic components.
Returns
list of Expression, float, or complexComponents in logical row-major order; one element for a scalar. Dimensions must be concrete.
Notes
Unregistered tensors receive symbolic components. Relabeling abstract indices does not change those component identities.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
len(A.components())
4compose
TensorExpression.compose(
rhs: TensorExpression | Expression,
*,
left: tuple[builtins.int, builtins.int],
right: tuple[builtins.int, builtins.int],
) -> TensorExpression
TensorExpression.compose(
rhs: typing.Union[Tensor, TensorNetwork],
*,
left: tuple[int, int],
right: tuple[int, int],
) -> TensorNetworkMultiply two tensors along explicitly selected matrix channels.
Parameters
rhs(TensorExpression, Tensor, or TensorNetwork) Next factor in the ordered matrix product.left, right(tuple of int and int) (input_axis, output_axis) in this tensor and rhs, respectively. The left output contracts with the right input. Other axes are retained as spectator axes.
Returns
TensorExpression or TensorNetworkSymbolic operands return TensorExpression. A concrete rhs produces a TensorNetwork that retains its data.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
product = A.compose(A, left=(0, 1), right=(0, 1))
product.rank
2contract
TensorExpression.contract(
*,
representations: typing.Optional[typing.Sequence[Representation | RepresentationName]] = None,
metrics: builtins.bool = True,
rank_one: builtins.bool = True,
collect_chains: builtins.bool = True,
collect_traces: builtins.bool = True,
expand: builtins.bool = True,
order: typing.Optional[typing.Sequence[builtins.int]] = None,
max_steps_per_domain: typing.Optional[builtins.int] = None,
) -> TensorExpressionContract compatible indices without applying tensor-algebra identities.
Eliminate metrics and identity tensors, including closed dimension factors; substitute vectors into compatible ports; form scalar products; and collect ordered matrix chains and unevaluated traces. Matrix order and orientation are preserved. The input is unchanged.
Parameters
representations(sequence of Representation or RepresentationName, optional) Filter connections by representation family: None permits all, [] none. Families include dual representations. For example, Representation.mink(4) permits the Minkowski family, including symbolic-D slots; the 4 is not a dimension filter. Each connection must still satisfy dimension and orientation compatibility. Matching representation names alone is insufficient. The filter acts on connecting ports, not whole tensor factors: a Lorentz connection can enter a gamma matrix while its spinor ports survive. Chain assembly and trace closure also require a permitted connection.metrics(bool, default True) Eliminate compatible metric/identity tensors by index substitution and evaluate closed metric loops to their representation dimension.rank_one(bool, default True) Substitute vectors into compatible tensor ports (Schoonschip notation) and contract vector pairs into scalar products. This can enter a gamma matrix without applying a gamma identity. False retains those connections.collect_chains(bool, default True) Represent connected matrix products as ordered chains without evaluating their matrices. False retains the indexed factors for open products.collect_traces(bool, default True) Represent compatible closed matrix products as unevaluated traces. False retains indexed closure, including when collect_chains=True. It does not unfold trace notation already present in the input.expand(bool, default True) Permit local arithmetic distribution required by a selected contraction. False performs the minimal structural work: substitute at boundaries and contract within existing sum branches, but do not multiply out independent sum alternatives. A product of tensor sums can therefore remain indexed and still be Complete under expand=False. Neither value requests global polynomial expansion; expand() is a separate operation.order(sequence of int, optional) Optional zero-based permutation of every normalized top-level factor, used for the initial contraction round. Factors follow Symbolica’s normalized order, not necessarily the order in the Python source. None lets the planner choose. This affects scheduling, never matrix order; omit it unless you need to prescribe a factor order explicitly.max_steps_per_domain(int or None, default None) Optional nonnegative limit on successful planner transformations in each active expression domain. None imposes no automatic work limit. This is not a limit on time, memory, generated terms, or work inside one kernel. Zero preserves eligible work and reports Capped; a request with no eligible work can still report Complete. All unfinished results remain exact.
Returns
TensorExpressionA typed result with its checked external interface and reduction_status. Unrelated scalar coefficients and sums remain factored. No alias wrapper or separate materialization step is required.
Raises
ValueError: order is not a permutation of all normalized top-level factors, or a substitution cannot produce a valid tensor interface.
Notes
Contracting a color delta does not enable generator or Fierz identities. Collecting a Dirac or color trace does not evaluate it. Use simplify_algebra() for identities, contract_ports(rhs, left=…, right=…) for an explicit binary port contraction, and to_tensor() for component-library evaluation. With rank_one=False, collect_chains=False and collect_traces=False, only metric/identity contraction is requested.
Planning starts with a depth-one view of factor interfaces. It opens a selected region only when the contraction needs its interior, reusing unchanged leaves and known interfaces. With expand=True, necessary local distribution is allowed; an unrelated scalar sum is not routinely expanded. Internal dummy contractions can be processed even inside a scalar-interface leaf. This is distinct from expanding the whole expression with expand().
Settings do not undo intrinsic normalization performed during construction. A metric with identical compatible ports can already be its dimension, typed vector multiplication can already form a scalar product, and symmetric dot arguments are already ordered. representations=[] and disabled flags preserve these existing normalizations. Assign explicit compatible indices before requesting a particular Einstein contraction; unresolved axes are distinct port identities, not dummy indices to pair by guesswork.
Scalar products can remain in compact metric notation g(p(R), q(R)). to_dots() converts that surviving notation to dot(p(R), q(R)) without searching for repeated indices. undo_dots(), undo_chain() and undo_trace() unfold existing notation with fresh compatible dummy indices, preserving matrix order. They do not recover expressions already changed by identities.
Complete means no eligible work remains under the requested settings; disabled contractions and unevaluated traces may remain. Deferred retains exact work the current implementation could not finish. Capped means an explicit work limit stopped the operation. Completed reruns with the same settings are stable. Unfinished results can be passed back to contract(), possibly with different settings; unsupported cases need not make progress. Inspect this operation’s reduction_status before other transformations. contraction_complete is a separate structural certificate, not a substitute for completion under a restricted representation filter or expand=False.
See Also
simplify_algebra : Gamma, color and epsilon identities plus their contractions. contract_ports : Explicit binary contraction of selected logical ports. to_dots : Scalar-product notation conversion without index contraction. undo_trace : Turn trace notation into a closed indexed chain. expand : Explicit arithmetic distribution.
Examples
A metric relabels a vector. A Lorentz-only filter also permits a metric to enter a gamma matrix without touching its two spinor ports.
from symbolica import S
from symbolica.community import tensor as sp
lorentz = sp.Representation.mink(4)
metric = sp.TensorExpression.g(lorentz)
p = sp.TensorName.vector("contract_docs::p")(lorentz)
source = metric("mu", "nu") * p("nu")
assert source.contract() == p("mu")
gamma = sp.TensorExpression.dirac_gamma(4)
mixed = gamma("a", "b", "nu") * metric("mu", "nu")
assert mixed.contract(representations=[lorentz]) == gamma("a", "b", "mu")Trace collection and trace evaluation are separate operations. The collected trace represents the same tensor as 4*g(mu,nu), but contract() leaves it unevaluated. Unfolding and contracting it recovers the collected notation.
word = gamma("a", "b", "mu") * gamma("b", "a", "nu")
collected = word.contract()
assert collected.simplify_algebra(color=False) == 4 * metric("mu", "nu")
assert collected.undo_trace().undo_chain().contract() == collected
uncollected = word.contract(collect_traces=False)
assert uncollected.contract() == collectedA closed color delta gives N_c without any color-algebra identity. An empty filter retains this product, and an unrelated scalar power remains factored.
Nc = S("contract_docs::Nc")
fundamental = sp.Representation.cof(Nc)
delta = sp.TensorExpression.g(fundamental, fundamental.dual())
cycle = delta("i", "j") * delta("j", "i")
assert cycle.contract().to_expression() == Nc
assert cycle.contract(representations=[]) == cycle
x, y = S("contract_docs::x", "contract_docs::y")
assert ((x + y)**8 * cycle).contract().to_expression() == (x + y)**8 * NcMinimal contraction still relabels ports through a sum. It leaves products of independent tensor sums factorized instead of enumerating their pairings.
q = sp.TensorName.vector("contract_docs::q")(lorentz)
A = sp.TensorName("contract_docs::A")(lorentz, lorentz)
relabel = metric("mu", "nu") * (p("nu") + q("nu"))
assert relabel != p("mu") + q("mu")
assert relabel.contract(expand=False) == p("mu") + q("mu")
product = (metric("mu", "nu") + A("mu", "nu")) * (p("mu") + q("mu"))
minimal = product.contract(expand=False)
assert minimal == product
assert minimal.reduction_status == sp.ReductionStatus.Complete
full = product.contract()
assert minimal != full
assert minimal.contract() == fullAn explicit zero limit retains eligible work exactly. Continuing without that limit completes it, while the original input remains available.
pending = cycle.contract(max_steps_per_domain=0)
assert pending.reduction_status == sp.ReductionStatus.Capped
assert pending == cycle
assert pending.contract().to_expression() == Nccontract_ports
TensorExpression.contract_ports(
rhs: TensorExpression | Expression,
*,
left: builtins.int,
right: builtins.int,
) -> TensorExpression
TensorExpression.contract_ports(
rhs: typing.Union[Tensor, TensorNetwork],
*,
left: int,
right: int,
) -> TensorNetworkContract one chosen pair of axes between two tensors.
Parameters
rhs(TensorExpression, Tensor, or TensorNetwork) Tensor to contract with this tensor.left, right(int) Zero-based axis positions in this tensor and rhs, respectively. The representations must be compatible under contraction.
Returns
TensorExpression or TensorNetworkA symbolic tensor unless rhs carries component data, in which case a lazy TensorNetwork is returned.
Notes
Other axes remain external. Axis numbers refer to axes.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
contracted = A.contract_ports(A, left=1, right=0)
contracted.rank
2derivative
TensorExpression.derivative(x: _ScalarInput) -> TensorExpressionDifferentiate scalar coefficients, preserving tensor zeros and ports. Formal derivatives of unknown tensor functions are not supported by the network executor. Differentiate their component expressions with Tensor.map_components() instead, or supply a TensorName derivative callback.
Parameters
x(Expression) Scalar differentiation variable.
Returns
TensorExpressionDerivative with the same ordered external ports, even when zero.
Examples
from symbolica import S
from symbolica.community.tensor import Representation, TensorName
x = S("x")
A = TensorName("A")(Representation.euc(3))("i")
assert (x**2 * A).derivative(x) == 2*x*A
assert A.derivative(x).rank == A.rankdirac_adjoint
TensorExpression.dirac_adjoint(*, preserve_indices: builtins.bool = False) -> TensorExpressionConstruct the Dirac adjoint of a spinor tensor expression.
Parameters
preserve_indices(bool, default False) Keep external labels on their original physical legs. False uses matrix-adjoint ordering and exchanges open-chain endpoints.
Returns
TensorExpressionThe complex conjugate with reversed spinor chains and the gamma^0 boundary factors required by a Dirac adjoint.
Raises
DiracAdjointError: The index structure does not admit a consistent Dirac adjoint.
Notes
The expression must use the registered Dirac representation and tensor forms. This operation is specialized to Dirac spinors; it is not an ordinary transpose of arbitrary tensor components.
Examples
from symbolica.community.tensor import TensorName, Representation
spinor = TensorName("psi")(Representation.bis(4)("a"))
spinor.dirac_adjoint().rank
1dirac_gamma
TensorExpression.dirac_gamma(minkowski_dimension: builtins.int | Expression | str) -> TensorExpressionConstruct the Dirac gamma matrices for Clifford algebra.
Parameters
minkowski_dimension(int, Expression, or str) Dimension of the Minkowski vector index, for example 4 or a symbol D.
Returns
TensorExpressionA rank-3 symbolic tensor with distinct unresolved axes. Call the result with index labels to fill those axes in the order described below.
Notes
The axes are (spinor row, spinor column, Lorentz index), with four components on each spinor axis. The anticommutator obeys {gamma^mu, gamma^nu} = 2 g^{mu,nu} I. This helper is unrelated to the scalar gamma special function. Explicit library matrices are four-dimensional.
Examples
from symbolica.community.tensor import TensorExpression, Representation
tensor = TensorExpression.dirac_gamma(4)
tensor.rank
3expand
TensorExpression.expand(
var: typing.Optional[_ScalarInput] = None,
via_poly: typing.Optional[builtins.bool] = None,
) -> TensorExpressionDistribute scalar products and powers over sums.
Parameters
var(scalar expression, optional) Restrict expansion to terms involving this expression. None expands throughout the expression.via_poly(bool, optional) Use Symbolica’s polynomial-based expansion when True. Defaults to False.
Returns
TensorExpressionExpanded algebra with a checked tensor interface.
Notes
Label unresolved axes before expansion when their identities cannot be tracked through a rewritten sum. Expansion can enlarge expressions. Tensor simplifiers do not generally require expanding the whole expression first.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
from symbolica import S
x = S("x")
expanded = ((x + 1)**2 * A("i", "j")).expand()
expanded.rank
2expand_num
TensorExpression.expand_num() -> TensorExpressionDistribute numerical coefficients over sums without expanding symbolic products. The result remains a TensorExpression with the same ordered ports and metadata.
Returns
TensorExpressionRewritten scalar algebra with the original tensor interface and metadata.
Examples
from symbolica import S
from symbolica.community.tensor import TensorName, Representation
x, y = S("x", "y")
A = TensorName("A")(Representation.euc(3))("i")
result = (2 * (x + y) * A).expand_num()
assert result == (2*x + 2*y) * Aexpand_projectors
TensorExpression.expand_projectors() -> TensorExpressionExpand normalized factor groups into their permutation sums.
Returns
TensorExpressionTensor algebra with symmetric, antisymmetric, and cyclic groups expanded. Other sums and products remain factored.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
from symbolica.community.tensor import FactorProjector, trace
expression = trace(space, FactorProjector.symmetric(A, A))
expression.expand_projectors().is_scalar
Truefactor
TensorExpression.factor(
complex: builtins.bool = False,
extension: typing.Optional[typing.Sequence[_ScalarInput]] = None,
) -> TensorExpressionFactor scalar algebra while retaining ordered tensor ports and data metadata. Tensor leaves are treated as symbolic indeterminates; no tensor identity is applied.
Parameters
complex(bool, default False) Factor over the complex rationals rather than the rationals.extension(list of Expression, optional) Algebraic numbers defining the coefficient field, as in Expression.factor.
Returns
TensorExpressionFactored expression with the original tensor interface, including typed zeros.
Examples
from symbolica import S
from symbolica.community.tensor import TensorName, Representation
x = S("x")
A = TensorName("A")(Representation.euc(3))("i")
factored = ((x**2 + 2*x + 1) * A).factor()
assert factored == (x + 1)**2 * Aflat
TensorExpression.flat(rep: Representation) -> TensorExpressionConstruct the metric map for raising or lowering an index.
Parameters
rep(Representation) Space of both axes.
Returns
TensorExpressionA rank-2 symbolic tensor with distinct unresolved axes. Call the result with index labels to fill those axes in the order described below.
Notes
This map accounts for the signs in the representation metric.
Examples
from symbolica.community.tensor import TensorExpression, Representation
tensor = TensorExpression.flat(Representation.mink(4))
tensor.rank
2format_tensor
TensorExpression.format_tensor(
show_dimensions: typing.Optional[builtins.bool] = None,
*,
settings: typing.Optional[DisplaySettings] = None,
) -> builtins.strProduce compact plain-text tensor notation.
Parameters
show_dimensions(bool, optional) Override settings.show_dimensions for this call. None retains the selected settings, whose default omits dimensions.settings(DisplaySettings, optional) Tensor notation and display choices. Defaults to DisplaySettings().
Returns
strReadable tensor text, suitable for logs or terminal output.
Notes
Only ports layout and default spacing are supported in this source format. Use to_html() or to_svg() for other layouts and custom gaps.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
output = A.format_tensor()formatted
TensorExpression.formatted(
show_dimensions: typing.Optional[builtins.bool] = None,
*,
settings: typing.Optional[DisplaySettings] = None,
notation_source: typing.Optional[builtins.str] = None,
) -> FormattedOutputCreate a lazy rich display value for a notebook.
Parameters
show_dimensions(bool, optional) Override settings.show_dimensions for this call. None retains the selected settings, whose default omits dimensions.settings(DisplaySettings, optional) Tensor notation and display choices. Defaults to DisplaySettings().notation_source(str, optional) Custom Typst notation source used by the rich renderer. This is Typst code, not a filename; omit it for the supplied tensor notation.
Returns
FormattedOutputSmall expressions render once per backend; large notebook displays use bounded pages.
Notes
Automatic representations of large expressions are bounded previews. Paging retains factorization and ordered ports; explicit exports remain complete. Settings are captured here; custom printers run on the first request for each backend. Create a new formatted value after changing printers.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
output = A.formatted()g
TensorExpression.g(
rep: Representation | Slot,
other: Representation | Slot | None = None,
) -> TensorExpressionConstruct the metric pairing, optionally with explicit indices.
Parameters
rep(Representation or Slot) First axis. A representation leaves it unresolved; a slot supplies both its representation and its index.other(Representation or Slot, optional) Second axis. Defaults to an unresolved axis in the first axis’s representation, even when the first argument is a slot.
Returns
TensorExpressionThe metric with supplied indices in argument order. Representations remain unresolved for later indexing. Matching compatible indices contract, just as when indexing an existing metric.
Raises
ValueError: If the two spaces are neither equal nor dual partners, including when their dimensions differ. TypeError If an argument is not a Representation or Slot.
Examples
from symbolica.community.tensor import TensorExpression, Representation
r = Representation.mink(4)
metric = TensorExpression.g(r("mu"), r("nu"))
metric == TensorExpression.g(r)("mu", "nu")
True
partly_indexed = TensorExpression.g(r("mu"), r)
partly_indexed("nu") == metric
True
f = Representation.cof(3)
identity = TensorExpression.g(f("i"), f.dual()("j"))
identity.rank
2gamma0
TensorExpression.gamma0(spinor_dimension: builtins.int | Expression | str) -> TensorExpressionConstruct the time-component Dirac matrix gamma^0.
Parameters
spinor_dimension(int, Expression, or str) Number of spinor components.
Returns
TensorExpressionA rank-2 symbolic tensor with distinct unresolved axes. Call the result with index labels to fill those axes in the order described below.
Notes
The two axes are spinor row and column. The HEP libraries provide four-component matrices in the Weyl basis.
Examples
from symbolica.community.tensor import TensorExpression, Representation
tensor = TensorExpression.gamma0(4)
tensor.rank
2gamma5
TensorExpression.gamma5(spinor_dimension: builtins.int | Expression | str) -> TensorExpressionConstruct the Dirac chirality matrix gamma^5.
Parameters
spinor_dimension(int, Expression, or str) Number of spinor components.
Returns
TensorExpressionA rank-2 symbolic tensor with distinct unresolved axes. Call the result with index labels to fill those axes in the order described below.
Notes
The axes are spinor row and column. The HEP libraries provide the four-component Weyl-basis chirality matrix.
Examples
from symbolica.community.tensor import TensorExpression, Representation
tensor = TensorExpression.gamma5(4)
tensor.rank
2index
TensorExpression.index(
*indices: _IndexInput,
intern: typing.Optional[typing.Literal['indices', 'flattened']] = None,
) -> TensorExpressionAssign labels to the unresolved external axes.
Parameters
*indices(int, str, Expression, Slot, or AUTO) One label per unresolved axis, in logical order. AUTO leaves the corresponding axis unchanged. A Slot must have the matching representation. Repeated compatible labels cause contraction.intern({“indices”, “flattened”} or None, optional) Encode compound index labels before checking the tensor structure. “indices” retains reversible payloads; “flattened” creates readable names. Both preserve index tags and leave scalar arguments and tensor heads intact. None leaves labels unchanged and requires ordinary atomic index labels.
Returns
TensorExpressionAn indexed expression.
Notes
Existing explicit labels are left in place. Use reindex to replace them.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
indexed = A.index("i", "j")
indexed.rank
2is_expanded
TensorExpression.is_expanded(var: typing.Optional[_ScalarInput] = None) -> builtins.boolTest whether products and powers are expanded, optionally with respect to var. The expression and its tensor interface are unchanged.
Parameters
var(Expression, optional) Restrict the expansion check to this indeterminate.
Returns
boolTrue if no further arithmetic distribution is needed for the requested scope.
Examples
from symbolica import S
from symbolica.community.tensor import TensorExpression
x = S("x")
value = TensorExpression((x + 1)**2)
assert not value.is_expanded()
assert value.expand().is_expanded(x)is_one
TensorExpression.is_one() -> builtins.boolTest whether the expression is exactly the scalar one.
Returns
boolTrue for scalar one; an identity tensor is not the scalar one.
Examples
from symbolica.community.tensor import TensorExpression
assert TensorExpression(1).is_one()is_zero
TensorExpression.is_zero() -> builtins.boolTest whether the expression is exactly zero, including zeros with nonzero tensor rank. This does not perform algebraic simplification.
Returns
boolTrue for an exact symbolic zero, irrespective of rank.
Examples
from symbolica.community.tensor import TensorName, Representation
A = TensorName("A")(Representation.euc(3))("i")
assert (0 * A).is_zero()
assert (0 * A).rank == 1levi_civita
TensorExpression.levi_civita(rep: Representation, rank: builtins.int = 4) -> TensorExpressionConstruct the totally antisymmetric Levi-Civita tensor.
Parameters
rep(Representation) Space of every axis.rank(int, default 4) Number of axes, independent of the representation dimension.
Returns
TensorExpressionA symbolic tensor withrankdistinct unresolved axes.
Notes
This constructs symbolic epsilon syntax. It does not populate a component library; rank and space dimension need not be equal for symbolic work.
Examples
from symbolica.community.tensor import TensorExpression, Representation
tensor = TensorExpression.levi_civita(Representation.euc(3), rank=3)
tensor.rank
3list_dangling
TensorExpression.list_dangling() -> builtins.list[Expression]List the external indices that are not summed over.
Returns
list of ExpressionRepresentation-aware index expressions, in logical order when all axes are labeled. Dual indices retain their dual wrapper.
Notes
For unresolved axes, prefer structure.axes to inspect the interface.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
len(A("i", "j").list_dangling())
2map
TensorExpression.map(
op: Transformer,
n_cores: typing.Optional[builtins.int] = None,
stats_to_file: typing.Optional[builtins.str] = None,
) -> TensorExpressionApply a Symbolica Transformer and retain the validated tensor interface.
Parameters
op(Transformer) Transformations to apply, including user callbacks.n_cores(int, optional) Number of cores for Symbolica’s term mapping.stats_to_file(str, optional) JSON output file for the transformer’s statistics.
Returns
TensorExpressionTransformed expression with its original ordered tensor interface.
Examples
from symbolica import S, T
from symbolica.community.tensor import Representation, TensorName
x = S("x")
A = TensorName("A")(Representation.euc(3))("i")
result = ((x + 1)**2 * A).map(T().expand())
assert result == ((x + 1)**2 * A).expand()nterms
TensorExpression.nterms() -> builtins.intCount top-level additive terms without expanding the expression. Unlike len(tensor), this counts symbolic terms rather than tensor components.
Returns
intNumber of terms in the outermost sum, or one for a non-sum.
Examples
from symbolica import S
from symbolica.community.tensor import TensorExpression
x = S("x")
value = TensorExpression((x + 1)**2)
assert value.nterms() == 1
assert value.expand().nterms() == 3outer
TensorExpression.outer(rhs: TensorExpression | Expression) -> TensorExpression
TensorExpression.outer(rhs: typing.Union[Tensor, TensorNetwork]) -> TensorNetworkForm an outer product without implicit contractions between the operands.
Parameters
rhs(TensorExpression, Tensor, or TensorNetwork) Tensor whose axes follow this tensor’s axes.
Returns
TensorExpression or TensorNetworkSymbolic operands return TensorExpression. If rhs carries component data, the result is a TensorNetwork.
Notes
Use this when compatible unresolved axes should remain independent. Choose explicit distinct labels if you need to refer to them separately.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
product = A.outer(A)
product.rank
4paged
TensorExpression.paged(
page_size: builtins.int = 25,
*,
settings: typing.Optional[DisplaySettings] = None,
notation_source: typing.Optional[builtins.str] = None,
) -> typing.AnyCreate a bounded, interactive MathML viewer in marimo or Jupyter.
Only the current page is rendered. Nested expressions retain their factorization, and omitted subexpressions can be opened independently. Requires the optional notebook-display dependencies for live navigation.
Parameters
page_size(int, default 25) Maximum entries shown on a page: 25, 100, 250, or 500. Rendering may show fewer entries when an individual expression is large.settings(DisplaySettings, optional) Tensor notation, index labels, and other presentation preferences.notation_source(str, optional) Custom Typst notation source, with the same meaning as in to_html().
Returns
objectNotebook viewer retaining the expression and rendering pages on demand. Display it in marimo or Jupyter to navigate its widget.
Examples
from symbolica.community.tensor import TensorExpression
viewer = TensorExpression(1).paged(page_size=25)permute_axes
TensorExpression.permute_axes(axes: typing.Sequence[builtins.int]) -> TensorExpressionReorder the external axes in logical component order.
Parameters
axes(sequence of int) Each current axis position exactly once, in the desired new order. For a matrix, [1, 0] exchanges the two axes.
Returns
TensorExpressionA new tensor view with the reordered interface.
Notes
This permutes axes; it does not conjugate component values.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
transposed = A.permute_axes([1, 0])
transposed.shape
(2, 2)projm
TensorExpression.projm(spinor_dimension: builtins.int | Expression | str) -> TensorExpressionConstruct the left-chiral Dirac projector (I - gamma^5)/2.
Parameters
spinor_dimension(int, Expression, or str) Number of spinor components.
Returns
TensorExpressionA rank-2 symbolic tensor with distinct unresolved axes. Call the result with index labels to fill those axes in the order described below.
Notes
The two axes are spinor row and column. This is a projector on spinors, not a FactorProjector for permuting tensor factors.
Examples
from symbolica.community.tensor import TensorExpression, Representation
tensor = TensorExpression.projm(4)
tensor.rank
2projp
TensorExpression.projp(spinor_dimension: builtins.int | Expression | str) -> TensorExpressionConstruct the right-chiral Dirac projector (I + gamma^5)/2.
Parameters
spinor_dimension(int, Expression, or str) Number of spinor components.
Returns
TensorExpressionA rank-2 symbolic tensor with distinct unresolved axes. Call the result with index labels to fill those axes in the order described below.
Notes
The two axes are spinor row and column. This is a projector on spinors, not a FactorProjector for permuting tensor factors.
Examples
from symbolica.community.tensor import TensorExpression, Representation
tensor = TensorExpression.projp(4)
tensor.rank
2reindex
TensorExpression.reindex(
*indices: _IndexInput,
intern: typing.Optional[typing.Literal['indices', 'flattened']] = None,
) -> TensorExpressionAssign labels to all external axes.
Parameters
*indices(int, str, Expression, Slot, or AUTO) One label per external axis, in logical order. AUTO leaves the corresponding axis unchanged. A Slot must have the matching representation. Repeated compatible labels cause contraction.intern({“indices”, “flattened”} or None, optional) Encode compound index labels before checking the tensor structure. “indices” retains reversible payloads; “flattened” creates readable names. Both preserve index tags and leave scalar arguments and tensor heads intact. None leaves labels unchanged and requires ordinary atomic index labels.
Returns
TensorExpressionAn indexed expression.
Notes
Existing labels are replaced as well as unresolved axes.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
indexed = A.reindex("i", "j")
indexed.rank
2rename_indices
TensorExpression.rename_indices(
mapping: dict[int | str | Expression | Slot, _IndexInput],
*,
intern: typing.Optional[typing.Literal['indices', 'flattened']] = None,
) -> TensorExpressionRename selected external labels without changing the tensor rank.
Parameters
mapping(dict) Old label to new label. A Slot key also restricts the representation. Keys must identify existing external axes. Each axis may be renamed once; renaming must preserve the external interface.intern({“indices”, “flattened”} or None, optional) Encode compound index labels before checking the tensor structure. “indices” retains reversible payloads; “flattened” creates readable names. Both preserve index tags and leave scalar arguments and tensor heads intact. None leaves labels unchanged and requires ordinary atomic index labels.
Returns
TensorExpressionA new value with renamed axes; the original is unchanged.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
indexed = A.index("i", "j")
renamed = indexed.rename_indices({"i": "k"})
renamed.rank
2replace
TensorExpression.replace(
pattern: TensorRule | list[TensorRule] | _ScalarInput,
rhs: typing.Optional[_ReplacementInput] = None,
cond: typing.Optional[PatternRestriction | Condition] = None,
non_greedy_wildcards: typing.Optional[typing.Sequence[Expression]] = None,
min_level: builtins.int = 0,
max_level: typing.Optional[builtins.int] = None,
level_is_tree_depth: builtins.bool = False,
partial: builtins.bool = True,
allow_new_wildcards_on_rhs: builtins.bool = False,
rhs_cache_size: typing.Optional[builtins.int] = None,
repeat: builtins.bool = False,
once: builtins.bool = False,
bottom_up: builtins.bool = False,
nested: builtins.bool = False,
) -> TensorExpressionReplace symbolic patterns or apply whole-tensor replacement rules.
Parameters
pattern(Expression, TensorRule, or list of TensorRule) Symbolica pattern when rhs is supplied. Without rhs, apply prepared TensorRules in priority order, leaving scalar key arguments opaque.rhs(Expression, HeldExpression, or callable, optional) Symbolica replacement, including callbacks. The result must preserve the tensor’s ordered interface. Use reindex() to change external labels.cond(PatternRestriction or Condition, optional) Restriction on a symbolic match.non_greedy_wildcards(list of Expression, optional) Wildcards whose matches should be selected non-greedily.min_level, max_level(int, optional) Inclusive traversal bounds, starting at zero.level_is_tree_depth(bool, default False) Count expression-tree levels rather than function nesting.partial(bool, default True) Allow matches inside larger expressions.allow_new_wildcards_on_rhs(bool, default False) Allow wildcard symbols that do not occur in the pattern.rhs_cache_size(int, optional) Cache repeated symbolic replacements; zero disables caching.repeat, once, bottom_up, nested(bool, default False) Symbolica’s replacement traversal controls. Prepared TensorRules own their conditions and cache settings and do not accept these options.
Returns
TensorExpressionRewritten value retaining its checked tensor interface and metadata.
Examples
from symbolica import S
from symbolica.community.tensor import Representation, TensorName, TensorRule
A = TensorName("M")(Representation.euc(2))("i")
x, y = S("x", "y")
assert (x * A).replace(x, y) == y * A
assert A.replace(TensorRule(A, 2 * A)) == 2 * Areplace_multiple
TensorExpression.replace_multiple(
replacements: typing.Sequence[Replacement],
repeat: builtins.bool = False,
once: builtins.bool = False,
bottom_up: builtins.bool = False,
nested: builtins.bool = False,
) -> TensorExpressionApply simultaneous Symbolica replacements and validate the resulting tensor.
Parameters
replacements(list of Replacement) Symbolica replacements, including their conditions and callbacks.repeat, once, bottom_up, nested(bool, default False) Traversal controls with the same meaning as Expression.replace_multiple.
Returns
TensorExpressionRewritten value preserving ordered ports, metadata, and typed zeros.
Examples
from symbolica import S, Replacement
from symbolica.community.tensor import Representation, TensorName
x, y = S("x", "y")
A = TensorName("A")(Representation.euc(3))("i")
assert (x*A).replace_multiple([Replacement(x, y)]) == y*Asigma
TensorExpression.sigma(minkowski_dimension: builtins.int | Expression | str) -> TensorExpressionConstruct the antisymmetric Dirac sigma tensor.
Parameters
minkowski_dimension(int, Expression, or str) Dimension of each Minkowski vector index.
Returns
TensorExpressionA rank-4 symbolic tensor with distinct unresolved axes. Call the result with index labels to fill those axes in the order described below.
Notes
The logical axes are (mu, nu, spinor row, spinor column). Both spinor axes have dimension four.
Examples
from symbolica.community.tensor import TensorExpression, Representation
tensor = TensorExpression.sigma(4)
tensor.rank
4simplify_algebra
TensorExpression.simplify_algebra(
*,
gamma: builtins.bool = True,
color: builtins.bool = True,
epsilon: builtins.bool = False,
contract: typing.Literal['fully', 'minimal', 'dots', 'selected', 'none'] = 'fully',
representations: typing.Optional[typing.Sequence[Representation | RepresentationName]] = None,
collect_coefficients: builtins.bool = True,
gamma_output: typing.Optional[typing.Literal['reduced', 'chains']] = None,
gamma_ordering: typing.Optional[typing.Literal['repeated_pairs', 'canonical']] = None,
gamma_evaluate_traces: typing.Optional[builtins.bool] = None,
gamma0: typing.Optional[builtins.bool] = None,
gamma_conjugate: typing.Optional[builtins.bool] = None,
gamma_expand_three_gamma_epsilon: typing.Optional[builtins.bool] = None,
color_evaluate_traces: typing.Optional[builtins.bool] = None,
color_expand_fierz: typing.Optional[builtins.bool] = None,
color_substitute_cof_dimension_invariants: typing.Optional[builtins.bool] = None,
max_steps_per_domain: typing.Optional[builtins.int] = None,
) -> TensorExpressionReduce enabled tensor identities and their required index contractions.
Gamma and color identities are enabled by default; epsilon identities are opt-in. The default also completes supported structural contractions, so a second contract() call is normally unnecessary. The input is unchanged.
Parameters
gamma, color(bool, default True) Enable Dirac/Clifford and color identities, respectively. Each family authorizes the structural contractions required to apply its identities. Set the other families to False when requesting only one family.epsilon(bool, default False) Enable supported Levi-Civita pair contractions and their prerequisites. These can generate determinant sums. Epsilon tensors emitted by gamma reduction do not implicitly enable this option. Intrinsic antisymmetry normalization during construction is independent of this setting.contract({“fully”, “dots”, “minimal”, “selected”, “none”}, default “fully”) Structural work in addition to enabled identities and their prerequisites: - “fully”: contract compatible metrics/identities and vectors, collect matrix chains, and close compatible chains into trace notation. - “dots”: the same work, plus canonical dot notation for scalar products. - “minimal”: perform structural contractions that do not multiply out independent sum alternatives. Boundary substitutions through existing sums and contractions within their branches are allowed. Products of sums stay factored when contracting them would require distribution. - “selected”: the same structural operations, restricted to connections in representations. This does not restrict identity prerequisites. - “none”: no additional structural pass. Enabled identities still get their prerequisite contractions; this does not disable all contraction. These modes do not enable identity families. In particular, collecting a trace does not evaluate it, and contracting a color delta does not apply a generator or Fierz identity. “minimal” restricts additional structural work; enabled algebra identities retain their prerequisites and can still introduce sums. It is not a global ban on expansion.representations(sequence of Representation or RepresentationName, optional) Required with contract=“selected” and rejected with the other modes. Select connecting representation families, including their duals, rather than whole tensor factors. For example, Representation.mink(4) selects the Minkowski family, including symbolic-D instances; it does not change dimensions. Each connection must still have compatible dimensions and orientation. [] permits no additional index contractions or trace closure. Identity prerequisites and existing constructor normalization are unaffected.collect_coefficients(bool, default True) Collect generated exact coefficients in contracted Dirac traces and their bound vector factors so equal terms combine and cancel. Includes Symbolica’s expand_num() distribution of numerical factors over sums inside those generated coefficients. False retains their nested, factored output. Other family kernels retain their existing coefficient normalization. This is not global expansion: unrelated input sums and scalar prefactors remain factorized. It neither expands free Dirac traces nor reverses simplification already performed.gamma_output({“reduced”, “chains”}, optional) Defaults to “reduced”: apply supported Clifford and trace identities. “chains” collects Dirac chains/traces without Clifford reduction or trace evaluation, even if gamma_evaluate_traces=True. Explicit gamma0 and gamma_conjugate preparation still applies when requested.gamma_ordering({“repeated_pairs”, “canonical”}, optional) Ordering for reduced open Dirac chains. The default “repeated_pairs” brings repeated indices together without fully sorting unrelated matrices. “canonical” orders the chain and can introduce metric-term sums through anticommutation. It is inactive for gamma_output=“chains”.gamma_evaluate_traces(bool, optional) Evaluate supported closed Dirac traces with reduced output; defaults to True. False retains trace notation while other enabled identities remain available. Trace normalization follows the spinor representation dimension.gamma0(bool, optional) Apply gamma-zero factoring before chain collection; defaults to False. This controls the preparation pass, not every gamma-zero identity already included in reduced Dirac algebra.gamma_conjugate(bool, optional) Rewrite explicitly complex-conjugated Dirac matrices before collection; defaults to False. This does not conjugate the input tensor.gamma_expand_three_gamma_epsilon(bool, optional) With reduced output, expand three compatible four-dimensional gammas in a gamma5/epsilon basis; defaults to False. This can introduce sums and epsilon tensors, but does not enable epsilon identities.color_evaluate_traces(bool, optional) Evaluate supported closed color traces; defaults to True. False retains unevaluated traces, but enabled Fierz identities may still join or change them. It does not disable the rest of color algebra.color_expand_fierz(bool, optional) Apply fundamental Fierz identities between different open chains or traces; defaults to True. This may introduce sums. False disables these cross-chain expansions, not every color identity or source of sums.color_substitute_cof_dimension_invariants(bool, optional) Write supported color invariants in terms of the fundamental SU(N) dimension, with T_F=1/2; defaults to False, retaining symbolic invariants. In the supported fundamental/adjoint spaces this gives C_F=(N**2-1)/(2*N) and C_A=N. The dimension comes from the representation: this does not set every color space to SU(3) or reduce arbitrary groups.max_steps_per_domain(int or None, default None) Optional nonnegative limit on successful planner transformations in each active expression domain. None imposes no automatic work limit. This is not a bound on time, memory, terms, or work inside one kernel. Zero leaves eligible work untouched and reports Capped; an already completed request can still report Complete. Unfinished results remain exact.
Returns
TensorExpressionA typed result carrying its checked interface and reduction_status. No alias wrapper or separate materialization step is required.
Raises
ValueError: An option value is invalid, representations is missing or used with the wrong mode, a family-specific option is supplied for a disabled family, or a rewrite cannot produce a valid tensor interface.
Notes
Select the families together; the shared planner schedules identities and contractions until no further permitted work is found. Under “fully” and “dots”, a closed color delta produces its dimension even with color=False. Under “none”, an unrelated Lorentz numerator can remain indexed and factored after its color sector is reduced. Use contract() for structural work alone.
This is not a global arithmetic expansion. Planning starts with a shallow view of factor interfaces and opens selected regions when needed. Necessary local distribution and identity-generated sums are allowed; unrelated sums and scalar coefficients stay factored. Request expand() explicitly when the final output must be a fully expanded polynomial.
Dimensions belong to the tensor representations. Set them before reduction, for example with with_lorentz_dimension(D). Ordinary Clifford contractions support compatible symbolic Lorentz dimensions. Four-dimensional gamma5, axial-trace and epsilon-basis rules are not a general D-dimensional gamma5 prescription; changing D after evaluation cannot recover lost dimension factors.
Family-specific None values use the defaults documented above. Even an explicitly supplied False option requires its family to be enabled. Reusable configurations are ordinary dictionaries passed with **options.
Inspect reduction_status on the returned reduction result. Complete means no eligible work remains under these settings, not under disabled families or other output requirements. Deferred retains exact work the current implementation could not finish. Capped means an explicit limit stopped it. Rerunning a Complete result with the same settings is stable. Capped or Deferred results can be passed back for further work, without a guarantee that an unsupported Deferred case will progress. contraction_complete is a separate structural certificate and can be False for a Complete “none” result.
See Also
contract : Structural contractions without enabling identities. to_dots : Change surviving scalar-product notation without contracting indices. expand : Explicit arithmetic distribution. undo_trace : Unfold an existing trace without evaluating it.
Examples
A closed Dirac word evaluates to 4*D even with no additional structural pass. The spinor dimension remains four while the Lorentz dimension is D.
from symbolica import E, S
from symbolica.community import tensor as sp
D = S("algebra_docs::D")
gamma = sp.TensorExpression.dirac_gamma(4).with_lorentz_dimension(D)
word = gamma("a", "b", "mu") * gamma("b", "a", "mu")
result = word.simplify_algebra(color=False, contract="none")
assert result.to_expression() == 4 * D
assert result.reduction_status == sp.ReductionStatus.CompleteRetain nested identity output when that form is preferable. Both requests represent the same tensor and leave unrelated scalar prefactors factored.
nested = word.simplify_algebra(color=False, collect_coefficients=False)
assert (nested - result).expand().to_expression() == 0Color-only reduction with explicit SU(3) invariants gives T^a T^a = 4/3 I. Omit the invariant-substitution option to retain symbolic Casimirs.
fundamental = sp.Representation.cof(3)
identity = sp.TensorExpression.g(fundamental, fundamental.dual())
T = sp.TensorExpression.color_t(8, 3)
pair = T("a", "i", "j") * T("a", "j", "k")
color_only = dict(gamma=False, color=True, contract="none",
color_substitute_cof_dimension_invariants=True)
assert pair.simplify_algebra(**color_only) == E("4/3") * identity("i", "k")Structural color-delta contraction is independent of color identities. With both identity families disabled, “none” preserves this product; “fully” and a matching “selected” filter produce its dimension.
cycle = identity("i", "j") * identity("j", "i")
structural = dict(gamma=False, color=False)
assert cycle.simplify_algebra(**structural, contract="none") == cycle
assert cycle.simplify_algebra(**structural).to_expression() == 3
selected = cycle.simplify_algebra(**structural, contract="selected",
representations=[fundamental.name])
assert selected.to_expression() == 3
assert cycle.simplify_algebra(**structural, contract="selected",
representations=[]) == cycle“dots” includes scalar-product notation conversion. Epsilon reduction is separately enabled; here the Euclidean identity epsilon_ijk epsilon_ijk = 6 is evaluated without gamma or color identities.
lorentz = sp.Representation.mink(4)
p = sp.TensorName.vector("algebra_docs::p")(lorentz)
q = sp.TensorName.vector("algebra_docs::q")(lorentz)
dotted = (p("mu") * q("mu")).simplify_algebra(**structural, contract="dots")
assert dotted == sp.dot(p, q)
epsilon = sp.TensorExpression.levi_civita(sp.Representation.euc(3), rank=3)
product = epsilon("i", "j", "k") * epsilon("i", "j", "k")
assert product.simplify_algebra(**structural, epsilon=True).to_expression() == 6Minimal contraction leaves a product of tensor sums exact and factorized. It can report Complete even though full contraction would do more work. The equivalent structural-only request is contract(expand=False).
metric = sp.TensorExpression.g(lorentz)
A = sp.TensorName("algebra_docs::A")(lorentz, lorentz)
factored = (metric("mu", "nu") + A("mu", "nu")) * (p("mu") + q("mu"))
minimal = factored.simplify_algebra(**structural, contract="minimal")
assert minimal == factored
assert minimal.reduction_status == sp.ReductionStatus.Complete
assert minimal == factored.contract(expand=False)
assert minimal != factored.contract()An explicit limit preserves the exact remaining expression. Continue by calling the same operation without a limit; no manual expansion is needed.
pending = cycle.simplify_algebra(**structural, max_steps_per_domain=0)
assert pending.reduction_status == sp.ReductionStatus.Capped
assert pending == cycle
assert pending.simplify_algebra(**structural).to_expression() == 3to_dots
TensorExpression.to_dots() -> TensorExpressionWrite compact metric products using dot notation.
Returns
TensorExpressionAn equivalent value in the requested notation.
Notes
This changes notation; it does not itself contract explicit vector indices. Use contract() first when those contractions are needed.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
converted = A.to_dots()to_expression
TensorExpression.to_expression() -> ExpressionReturn ordinary Symbolica algebra without the tensor interface.
Returns
ExpressionThe underlying expression. Axis metadata is no longer carried by the result; operations on it are ordinary Symbolica operations.
Notes
TensorExpression already inherits Expression. Convert when deliberately requesting ordinary Symbolica behavior, including replacements that change the tensor interface, rather than its tensor-aware overrides.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
raw = A.to_expression()to_html
TensorExpression.to_html(
show_dimensions: typing.Optional[builtins.bool] = None,
*,
settings: typing.Optional[DisplaySettings] = None,
notation_source: typing.Optional[builtins.str] = None,
) -> builtins.strRender the tensor as an HTML fragment.
Parameters
show_dimensions(bool, optional) Override settings.show_dimensions for this call. None retains the selected settings, whose default omits dimensions.settings(DisplaySettings, optional) Tensor notation and display choices. Defaults to DisplaySettings().notation_source(str, optional) Custom Typst notation source used by the rich renderer. This is Typst code, not a filename; omit it for the supplied tensor notation.
Returns
strSelf-contained output fragment for an HTML-capable notebook or page.
Notes
Mathematical rendering uses the embedded Typst compiler. The returned string is not automatically displayed; pass it to the notebook’s HTML or SVG display facility.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
output = A.to_html()to_latex
TensorExpression.to_latex(
max_line_length: typing.Optional[builtins.int] = None,
*,
settings: typing.Optional[DisplaySettings] = None,
) -> builtins.strProduce LaTeX for the symbolic tensor expression.
Parameters
max_line_length(int, optional) Requested line-length bound for the printer. None leaves it unbounded.settings(DisplaySettings, optional) Index labels, dimensions and invariant notation. Defaults to DisplaySettings(). Only ports layout and default spacing are supported.
Returns
strLaTeX tensor notation, including the enclosing math delimiters.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
source = A.to_latex()to_network
TensorExpression.to_network(library: typing.Optional[TensorLibrary] = None) -> TensorNetworkBuild an executable network for this symbolic tensor.
Parameters
library(TensorLibrary, optional) Component definitions. Defaults to the built-in four-dimensional Dirac and SU(3) library. Unregistered tensors receive symbolic components.
Returns
TensorNetworkA new network with the same external axes. Construction does not execute its contractions.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
network = A.to_network()
network.rank
2to_svg
TensorExpression.to_svg(
show_dimensions: typing.Optional[builtins.bool] = None,
*,
settings: typing.Optional[DisplaySettings] = None,
notation_source: typing.Optional[builtins.str] = None,
) -> builtins.strRender static mathematical tensor notation to SVG.
Parameters
show_dimensions(bool, optional) Override settings.show_dimensions for this call. None retains the selected settings, whose default omits dimensions.settings(DisplaySettings, optional) Tensor notation and display choices. Defaults to DisplaySettings().notation_source(str, optional) Custom Typst notation source used by the rich renderer. This is Typst code, not a filename; omit it for the supplied tensor notation.
Returns
strSVG markup suitable for embedding or saving to a file.
Notes
Mathematical rendering uses the embedded Typst compiler. The returned string is not automatically displayed; pass it to the notebook’s HTML or SVG display facility.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
output = A.to_svg()to_tensor
TensorExpression.to_tensor(
library: typing.Optional[TensorLibrary] = None,
*,
function_library: typing.Optional[TensorFunctionLibrary] = None,
) -> TensorEvaluate this expression and return its components.
Parameters
library(TensorLibrary, optional) Component definitions. Defaults to the built-in four-dimensional Dirac and SU(3) library. Unregistered tensors receive symbolic components.function_library(TensorFunctionLibrary, optional) Numerical implementations of broadcast functions. Defaults to the built-in function library.
Returns
TensorResulting components in logical axis order. Dimensions must be concrete.
Notes
The original expression and the supplied libraries are unchanged.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
A.to_tensor().shape
(2, 2)to_typst
TensorExpression.to_typst(
show_dimensions: typing.Optional[builtins.bool] = None,
*,
settings: typing.Optional[DisplaySettings] = None,
) -> builtins.strProduce static Typst math source.
Parameters
show_dimensions(bool, optional) Override settings.show_dimensions for this call. None retains the selected settings, whose default omits dimensions.settings(DisplaySettings, optional) Tensor notation and display choices. Defaults to DisplaySettings().
Returns
strTypst source without an enclosing document; no compilation is performed.
Notes
Only ports layout and default spacing are supported in this source format. Use to_html() or to_svg() for other layouts and custom gaps.
Static Typst output remains available independently of the HTML explorer.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
output = A.to_typst()together
TensorExpression.together() -> TensorExpressionCombine scalar denominators into one fraction, retaining ordered ports and metadata. This is ordinary rational algebra and performs no tensor contractions.
Returns
TensorExpressionSingle rational expression with the original tensor interface.
Examples
from symbolica import S
from symbolica.community.tensor import TensorExpression
x, y = S("x", "y")
assert TensorExpression(1/x + 1/y).together().to_expression() == (x + y)/(x*y)trace
TensorExpression.trace(
*,
channel: typing.Optional[tuple[builtins.int, builtins.int]] = None,
) -> TensorExpressionClose a pair of matrix axes on this tensor.
Parameters
channel(tuple of int and int, optional) (input_axis, output_axis) to contract. If omitted, the matrix channel must be uniquely determined by the representations. Specify it when more than one pairing is possible.
Returns
TensorExpressionThe traced tensor; spectator axes remain external.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
A.trace(channel=(0, 1)).is_scalar
Trueundo_chain
TensorExpression.undo_chain() -> TensorExpressionExpose collected chain factors with fresh compatible dummy indices.
Returns
TensorExpressionEquivalent algebra in the requested notation.
Notes
This changes notation without distributing polynomial sums or requesting Dirac/color identities. Use undo_trace().undo_chain() to expose indexed trace factors.
Examples
from symbolica.community.tensor import Representation, TensorName, chain, trace
space = Representation.euc(2)
A = TensorName("M")(space, space)
expression = chain(space("i"), space("j"), A, A)
opened = expression.undo_chain()undo_dots
TensorExpression.undo_dots() -> TensorExpressionWrite dot products as explicit indexed contractions.
Returns
TensorExpressionAn equivalent value in the requested notation.
Notes
Other compact forms and factored sums are retained. This does not evaluate component data or expand a polynomial.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
converted = A.undo_dots()undo_trace
TensorExpression.undo_trace() -> TensorExpressionOpen compact traces as closed chains without evaluating them.
Returns
TensorExpressionEquivalent algebra in the requested notation.
Notes
This changes notation without distributing polynomial sums or requesting Dirac/color identities. Use undo_trace().undo_chain() to expose indexed trace factors.
Examples
from symbolica.community.tensor import Representation, TensorName, chain, trace
space = Representation.euc(2)
A = TensorName("M")(space, space)
expression = trace(space, A, A)
opened = expression.undo_trace()with_lorentz_dimension
TensorExpression.with_lorentz_dimension(dimension: builtins.int | Expression | str) -> TensorExpressionReplace four-dimensional Minkowski index spaces by a supplied dimension.
Parameters
dimension(int, Expression, or str) New Lorentz dimension, such as a symbol D. An Expression must be a single symbol.
Returns
TensorExpressionUpdated explicit slots and compact representation arguments.
Notes
Spinor and color dimensions, scalar coefficients, and Minkowski spaces with dimensions other than four are unchanged. Apply this before performing contractions that have already replaced four-dimensional traces by numbers.
Examples
from symbolica import S
from symbolica.community.tensor import TensorExpression
gamma = TensorExpression.dirac_gamma(4).with_lorentz_dimension(S("D"))
gamma.shape[:2]
(4, 4)with_name
TensorExpression.with_name(name: TensorName | builtins.str | Expression | TensorExpression) -> TensorExpressionAssign a data identity without rewriting the symbolic computation.
Parameters
name(TensorName, str, Expression, or TensorExpression) New tensor name. A rank-zero atomic TensorExpression may also supply scalar key arguments, for example TensorName(“B”)(7).
Returns
TensorExpressionA new value with the requested identity and the same axes.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
named = A.with_name("named_matrix")
named.rank
2wrap_indices
TensorExpression.wrap_indices(
header: Expression,
*,
dummies_only: builtins.bool = False,
) -> TensorExpressionGive explicit indices a scope that separates them from other copies.
Parameters
header(Expression) A single Symbolica symbol naming the scope.dummies_only(bool, default False) Scope only contracted indices, leaving external labels unchanged.
Returns
TensorExpressionScoped indices with the same internal contraction relationships.
Notes
Applying the same outer scope twice is idempotent; different scopes nest. Alphabet display uses primed labels for scoped copies. This is useful when multiplying independently summed expressions or an amplitude and its adjoint.
Examples
from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(2)
A = TensorName("M")(space, space)
from symbolica import S
scoped = A("i", "j").wrap_indices(S("bra"))
scoped.rank
2