TensorExpression

Symbolica documentation for getting started, symbolic expressions, numerical evaluation, pattern matching, and APIs in Python and Rust.

TensorExpression

class TensorExpression

A 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
2

Attributes

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 Expression Scalar 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)
True

axes

TensorExpression.axes: tuple[Slot | Representation, ...]

External axes in the current component and port-position order.

Returns

  • tuple of Slot or Representation Indexed 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]
True

contraction_complete

TensorExpression.contraction_complete: builtins.bool

Whether symbolic metric/vector contraction is certified complete.

Returns

  • bool False also covers a value not yet contracted or stopped before completion.

Examples

from symbolica.community.tensor import TensorExpression
TensorExpression(3).contract().contraction_complete
True

is_scalar

TensorExpression.is_scalar: builtins.bool

Whether the tensor has no external axes.

Returns

  • bool True 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
False

name

TensorExpression.name: typing.Optional[TensorName]

Optional name identifying stored tensor data.

Returns

  • TensorName or None Composite 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.name

rank

TensorExpression.rank: builtins.int

Number of external tensor axes.

Returns

  • int Zero for a scalar.

Examples

from symbolica.community.tensor import Representation, TensorName, TensorExpression
space = Representation.euc(3)
A = TensorName("A")(space, space)
A.rank
2

reduction_status

TensorExpression.reduction_status: ReductionStatus

Report completion under the last reduction settings and budget.

Returns

  • ReductionStatus Complete, 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
True

shape

TensorExpression.shape: tuple[int | Expression, ...]

Dimensions in logical axis order.

Returns

  • tuple of int or Expression Concrete 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: TensorStructure

Canonical external signature of the whole expression.

Returns

  • TensorStructure Immutable 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]) -> TensorNetwork

Add 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 TensorNetwork Symbolic 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.bool

Test 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,
) -> TensorExpression

Assign 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

  • TensorExpression An 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__() -> TensorExpression

Copy the expression and its tensor metadata.

Returns

  • TensorExpression A 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) -> TensorExpression

Copy the tensor’s immutable expression, ordered axes, and data metadata.

Parameters

  • memo (dict) Copy bookkeeping maintained by Python’s copy module.

Returns

  • TensorExpression Independent 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.bool

Compare 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 int Coordinates 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.int

Hash 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.int

Count all components in the tensor shape.

Returns

  • int Product 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]) -> _ProductT

Multiply 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 result The 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) -> TensorExpression

Multiply 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 TensorNetwork Symbolic 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]) -> TensorNetwork

Multiply 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 TensorNetwork Symbolic 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.bool

Test 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 * A

Parameters

  • other (object) TensorExpression to compare. Values without an ordered tensor interface are unequal.

__neg__

TensorExpression.__neg__() -> TensorExpression

Negate every tensor component.

Returns

  • TensorExpression Negated 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,
) -> TensorExpression

Wrap 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

  • TensorExpression A 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,
) -> TensorExpression

Raise 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

  • TensorExpression Powered 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]) -> TensorNetwork

Implement reflected addition.

Parameters

  • lhs (scalar expression, TensorExpression, Tensor, or TensorNetwork) Other operand. Component data are retained in a lazy network.

Returns

  • TensorExpression or TensorNetwork Symbolic 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.NoReturn

Reject 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.str

Return 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]) -> TensorNetwork

Implement reflected multiplication.

Parameters

  • lhs (scalar expression, TensorExpression, Tensor, or TensorNetwork) Other operand. Component data are retained in a lazy network.

Returns

  • TensorExpression or TensorNetwork Symbolic 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,
) -> TensorExpression

Use 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

  • TensorExpression Scalar 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]) -> TensorNetwork

Implement reflected subtraction.

Parameters

  • lhs (scalar expression, TensorExpression, Tensor, or TensorNetwork) Other operand. Component data are retained in a lazy network.

Returns

  • TensorExpression or TensorNetwork Symbolic 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]) -> TensorNetwork

Implement reflected division.

Parameters

  • lhs (scalar expression, TensorExpression, Tensor, or TensorNetwork) Other operand. Component data are retained in a lazy network.

Returns

  • TensorExpression or TensorNetwork Symbolic 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.str

Return 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]) -> TensorNetwork

Subtract 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 TensorNetwork Symbolic 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) -> TensorExpression

Preserve the tensor type when a Symbolica expression multiplies this tensor.

Parameters

  • lhs (Expression) Left operand; a tensor expression retains its tensor structure.

Returns

  • TensorExpression The same ordered product as lhs * 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]) -> TensorNetwork

Divide 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 TensorNetwork Symbolic 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.Any

Return marimo’s notebook presentation with bounded pages for large expressions.

Returns

  • object Rich 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.Any

Return 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

  • object MIME bundle for the complete small expression or paged large expression.

_repr_pretty_

TensorExpression._repr_pretty_(pretty: typing.Any, cycle: builtins.bool) -> None

apart

TensorExpression.apart(*variables: symbolica.core.Expression) -> TensorExpression

Decompose 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

  • TensorExpression Partial 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() -> TensorExpression

Cancel common numerator and denominator factors, retaining ordered ports and metadata. This is ordinary rational algebra and performs no tensor contractions.

Returns

  • TensorExpression Rational 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)*A

canonize

TensorExpression.canonize() -> TensorExpression

Canonicalize tensor factors and dummy-index labels.

Returns

  • TensorExpression An 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
2

charge_conjugation

TensorExpression.charge_conjugation(spinor_dimension: builtins.int | Expression | str) -> TensorExpression

Construct the Dirac charge-conjugation matrix.

Parameters

  • spinor_dimension (int, Expression, or str) Number of spinor components.

Returns

  • TensorExpression A 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
2

collect

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,
) -> TensorExpression

Collect 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

  • TensorExpression Collected 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() -> TensorExpression

Group terms with equal numerical coefficients, retaining ordered ports and metadata.

Returns

  • TensorExpression Expression 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() -> TensorExpression

Collect common factors from nested sums without applying tensor identities. Ordered ports, unresolved axes, tensor zeros, and data metadata are retained.

Returns

  • TensorExpression Rewritten 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)*A

collect_horner

TensorExpression.collect_horner(vars: typing.Optional[typing.Sequence[Expression]] = None) -> TensorExpression

Rewrite 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

  • TensorExpression Horner-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() -> TensorExpression

Extract common numerical coefficients from sums, retaining ordered ports and metadata. This reverses numerical distribution performed by expand_num().

Returns

  • TensorExpression Expression 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)*A

collect_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,
) -> TensorExpression

Collect 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

  • TensorExpression Collected 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) -> TensorExpression

Construct 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

  • TensorExpression A 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
3

color_t

TensorExpression.color_t(
    adjoint_dimension: builtins.int | Expression | str,
    fundamental_dimension: builtins.int | Expression | str,
) -> TensorExpression

Construct 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

  • TensorExpression A 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
3

components

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 complex Components 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())
4

compose

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],
) -> TensorNetwork

Multiply 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 TensorNetwork Symbolic 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
2

contract

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,
) -> TensorExpression

Contract 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

  • TensorExpression A 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() == collected

A 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 * Nc

Minimal 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() == full

An 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() == Nc

contract_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,
) -> TensorNetwork

Contract 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 TensorNetwork A 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
2

derivative

TensorExpression.derivative(x: _ScalarInput) -> TensorExpression

Differentiate 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

  • TensorExpression Derivative 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.rank

dirac_adjoint

TensorExpression.dirac_adjoint(*, preserve_indices: builtins.bool = False) -> TensorExpression

Construct 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

  • TensorExpression The 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
1

dirac_gamma

TensorExpression.dirac_gamma(minkowski_dimension: builtins.int | Expression | str) -> TensorExpression

Construct 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

  • TensorExpression A 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
3

expand

TensorExpression.expand(
    var: typing.Optional[_ScalarInput] = None,
    via_poly: typing.Optional[builtins.bool] = None,
) -> TensorExpression

Distribute 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

  • TensorExpression Expanded 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
2

expand_num

TensorExpression.expand_num() -> TensorExpression

Distribute numerical coefficients over sums without expanding symbolic products. The result remains a TensorExpression with the same ordered ports and metadata.

Returns

  • TensorExpression Rewritten 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) * A

expand_projectors

TensorExpression.expand_projectors() -> TensorExpression

Expand normalized factor groups into their permutation sums.

Returns

  • TensorExpression Tensor 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
True

factor

TensorExpression.factor(
    complex: builtins.bool = False,
    extension: typing.Optional[typing.Sequence[_ScalarInput]] = None,
) -> TensorExpression

Factor 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

  • TensorExpression Factored 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 * A

flat

TensorExpression.flat(rep: Representation) -> TensorExpression

Construct the metric map for raising or lowering an index.

Parameters

  • rep (Representation) Space of both axes.

Returns

  • TensorExpression A 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
2

format_tensor

TensorExpression.format_tensor(
    show_dimensions: typing.Optional[builtins.bool] = None,
    *,
    settings: typing.Optional[DisplaySettings] = None,
) -> builtins.str

Produce 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

  • str Readable 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,
) -> FormattedOutput

Create 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

  • FormattedOutput Small 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,
) -> TensorExpression

Construct 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

  • TensorExpression The 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
2

gamma0

TensorExpression.gamma0(spinor_dimension: builtins.int | Expression | str) -> TensorExpression

Construct the time-component Dirac matrix gamma^0.

Parameters

  • spinor_dimension (int, Expression, or str) Number of spinor components.

Returns

  • TensorExpression A 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
2

gamma5

TensorExpression.gamma5(spinor_dimension: builtins.int | Expression | str) -> TensorExpression

Construct the Dirac chirality matrix gamma^5.

Parameters

  • spinor_dimension (int, Expression, or str) Number of spinor components.

Returns

  • TensorExpression A 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
2

index

TensorExpression.index(
    *indices: _IndexInput,
    intern: typing.Optional[typing.Literal['indices', 'flattened']] = None,
) -> TensorExpression

Assign 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

  • TensorExpression An 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
2

is_expanded

TensorExpression.is_expanded(var: typing.Optional[_ScalarInput] = None) -> builtins.bool

Test 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

  • bool True 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.bool

Test whether the expression is exactly the scalar one.

Returns

  • bool True 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.bool

Test whether the expression is exactly zero, including zeros with nonzero tensor rank. This does not perform algebraic simplification.

Returns

  • bool True 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 == 1

levi_civita

TensorExpression.levi_civita(rep: Representation, rank: builtins.int = 4) -> TensorExpression

Construct 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

  • TensorExpression A symbolic tensor with rank distinct 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
3

list_dangling

TensorExpression.list_dangling() -> builtins.list[Expression]

List the external indices that are not summed over.

Returns

  • list of Expression Representation-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())
2

map

TensorExpression.map(
    op: Transformer,
    n_cores: typing.Optional[builtins.int] = None,
    stats_to_file: typing.Optional[builtins.str] = None,
) -> TensorExpression

Apply 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

  • TensorExpression Transformed 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.int

Count top-level additive terms without expanding the expression. Unlike len(tensor), this counts symbolic terms rather than tensor components.

Returns

  • int Number 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() == 3

outer

TensorExpression.outer(rhs: TensorExpression | Expression) -> TensorExpression
TensorExpression.outer(rhs: typing.Union[Tensor, TensorNetwork]) -> TensorNetwork

Form 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 TensorNetwork Symbolic 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
4

paged

TensorExpression.paged(
    page_size: builtins.int = 25,
    *,
    settings: typing.Optional[DisplaySettings] = None,
    notation_source: typing.Optional[builtins.str] = None,
) -> typing.Any

Create 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

  • object Notebook 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]) -> TensorExpression

Reorder 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

  • TensorExpression A 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) -> TensorExpression

Construct the left-chiral Dirac projector (I - gamma^5)/2.

Parameters

  • spinor_dimension (int, Expression, or str) Number of spinor components.

Returns

  • TensorExpression A 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
2

projp

TensorExpression.projp(spinor_dimension: builtins.int | Expression | str) -> TensorExpression

Construct the right-chiral Dirac projector (I + gamma^5)/2.

Parameters

  • spinor_dimension (int, Expression, or str) Number of spinor components.

Returns

  • TensorExpression A 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
2

reindex

TensorExpression.reindex(
    *indices: _IndexInput,
    intern: typing.Optional[typing.Literal['indices', 'flattened']] = None,
) -> TensorExpression

Assign 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

  • TensorExpression An 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
2

rename_indices

TensorExpression.rename_indices(
    mapping: dict[int | str | Expression | Slot, _IndexInput],
    *,
    intern: typing.Optional[typing.Literal['indices', 'flattened']] = None,
) -> TensorExpression

Rename 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

  • TensorExpression A 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
2

replace

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,
) -> TensorExpression

Replace 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

  • TensorExpression Rewritten 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 * A

replace_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,
) -> TensorExpression

Apply 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

  • TensorExpression Rewritten 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*A

sigma

TensorExpression.sigma(minkowski_dimension: builtins.int | Expression | str) -> TensorExpression

Construct the antisymmetric Dirac sigma tensor.

Parameters

  • minkowski_dimension (int, Expression, or str) Dimension of each Minkowski vector index.

Returns

  • TensorExpression A 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
4

simplify_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,
) -> TensorExpression

Reduce 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

  • TensorExpression A 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.Complete

Retain 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() == 0

Color-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() == 6

Minimal 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() == 3

to_dots

TensorExpression.to_dots() -> TensorExpression

Write compact metric products using dot notation.

Returns

  • TensorExpression An 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() -> Expression

Return ordinary Symbolica algebra without the tensor interface.

Returns

  • Expression The 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.str

Render 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

  • str Self-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.str

Produce 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

  • str LaTeX 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) -> TensorNetwork

Build 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

  • TensorNetwork A 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
2

to_svg

TensorExpression.to_svg(
    show_dimensions: typing.Optional[builtins.bool] = None,
    *,
    settings: typing.Optional[DisplaySettings] = None,
    notation_source: typing.Optional[builtins.str] = None,
) -> builtins.str

Render 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

  • str SVG 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,
) -> Tensor

Evaluate 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

  • Tensor Resulting 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.str

Produce 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

  • str Typst 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() -> TensorExpression

Combine scalar denominators into one fraction, retaining ordered ports and metadata. This is ordinary rational algebra and performs no tensor contractions.

Returns

  • TensorExpression Single 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,
) -> TensorExpression

Close 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

  • TensorExpression The 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
True

undo_chain

TensorExpression.undo_chain() -> TensorExpression

Expose collected chain factors with fresh compatible dummy indices.

Returns

  • TensorExpression Equivalent 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() -> TensorExpression

Write dot products as explicit indexed contractions.

Returns

  • TensorExpression An 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() -> TensorExpression

Open compact traces as closed chains without evaluating them.

Returns

  • TensorExpression Equivalent 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) -> TensorExpression

Replace 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

  • TensorExpression Updated 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) -> TensorExpression

Assign 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

  • TensorExpression A 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
2

wrap_indices

TensorExpression.wrap_indices(
    header: Expression,
    *,
    dummies_only: builtins.bool = False,
) -> TensorExpression

Give 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

  • TensorExpression Scoped 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