Tensor

Tensor

Tensor()

A tensor class that can be either dense or sparse with flexible data types.

The tensor can store data as floats, complex numbers, or symbolic expressions. Tensors have an associated structure that defines their shape and index properties.

Examples

from symbolica.community.spenso import Tensor, TensorIndices, Representation
structure = TensorIndices(Representation.euc(4)(1))
data = [1.0, 2.0, 3.0, 4.0]
tensor = Tensor.dense(structure, data)
sparse_tensor = Tensor.sparse(structure, float)

Methods

Name Description
__getitem__ Get tensor elements at the specified range of indices.
__iter__ Iterator.
__len__
__repr__
__setitem__ Set tensor element(s) at the specified index or indices.
__str__
dense Create a new dense tensor with the given structure and data.
evaluator Create an optimized evaluator for symbolic tensor expressions
one Create a scalar tensor with value 1.0.
scalar Extract the scalar value from a rank-0 (scalar) tensor.
sparse Create a new sparse empty tensor with the given structure and data type.
structure
to_dense Convert this tensor to dense storage format
to_sparse Convert this tensor to sparse storage format
zero Create a scalar tensor with value 0.0.

__getitem__

__getitem__ has 3 variants:

__getitem__ returning typing.Any

Tensor.__getitem__(item: builtins.slice | builtins.int | builtins.list[builtins.int]) -> typing.Any

__getitem__ returning builtins.list[Expression | builtins.complex | float]

Tensor.__getitem__(item: builtins.slice) -> builtins.list[Expression | builtins.complex | float]

Get tensor elements at the specified range of indices.

Parameters

  • item (slice) Slice object defining the range of indices

Returns

  • list of float, complex, or Expression The tensor elements at the specified range

__getitem__ returning Expression | builtins.complex | float

Tensor.__getitem__(item: typing.Sequence[builtins.int] | builtins.int) -> Expression | builtins.complex | float

Get tensor element at the specified index or indices.

Parameters

  • item (int or list of int) Index specification (int for flat index, list of int for coordinates)

Returns

  • float, complex, or Expression The tensor element at the specified index

__iter__

Tensor.__iter__() -> typing.Iterator[typing.Any]

Iterator

__len__

Tensor.__len__() -> builtins.int

__repr__

Tensor.__repr__() -> builtins.str

__setitem__

__setitem__ has 2 variants:

__setitem__ with item: typing.Any, value: typing.Any

Tensor.__setitem__(item: typing.Any, value: typing.Any) -> None

Set tensor element(s) at the specified index or indices.

Parameters

  • item (int or list of int) Index specification (int for flat index, list of int for coordinates)
  • value (float, complex, or Expression) The value to set

Examples

from symbolica.community.spenso import Tensor, TensorIndices, Representation as R
structure = TensorIndices(R.euc(2)(2), R.euc(2)(1))
tensor = Tensor.sparse(structure, float)
tensor[0] = 4.0
tensor[1, 1] = 1.0

__setitem__ with item: builtins.int | typing.Sequence[builtins.int], value: Expression | builtins.complex | float

Tensor.__setitem__(
    item: builtins.int | typing.Sequence[builtins.int],
    value: Expression | builtins.complex | float,
) -> None

Set tensor element at the specified index.

Parameters

  • item (int or list of int) Index specification (int for flat index, list of int for coordinates)
  • value (float, complex, or Expression) The value to set

Examples

from symbolica.community.spenso import Tensor, TensorIndices, Representation
rep = Representation.euc(2)
structure = TensorIndices(rep(1), rep(2))
tensor = Tensor.sparse(structure, float)
tensor[0] = 1.0
tensor[1, 1] = 2.0

__str__

Tensor.__str__() -> builtins.str

dense

Tensor.dense(
    structure: TensorIndices | builtins.list[Slot],
    data: typing.Sequence[Expression] | typing.Sequence[builtins.float] | typing.Sequence[builtins.complex],
) -> Tensor

Create a new dense tensor with the given structure and data.

Parameters

  • structure (TensorIndices or list of Slots) The tensor structure defining shape and index properties
  • data (list of float, complex, or Expression) The tensor data in row-major order

Returns

  • Tensor A new dense tensor with the specified data

Examples

from symbolica import S
from symbolica.community.spenso import Tensor, TensorIndices, Representation as R
structure = TensorIndices(R.euc(2)(1), R.euc(2)(2))
data = [1.0, 2.0, 3.0, 4.0]
tensor = Tensor.dense(structure, data)
x, y = S("x", "y")
sym_data = [x, y, x * y, x + y]
sym_tensor = Tensor.dense(structure, sym_data)

evaluator

Tensor.evaluator(
    constants: typing.Mapping[Expression, Expression],
    funs: typing.Mapping[tuple[Expression, builtins.str, typing.Sequence[Expression]], Expression],
    params: typing.Sequence[Expression],
    iterations: builtins.int = ...,
    n_cores: builtins.int = ...,
    verbose: builtins.bool = ...,
) -> TensorEvaluator

Create an optimized evaluator for symbolic tensor expressions.

Create an optimized evaluator for symbolic tensor expressions.

Compiles the symbolic expressions in this tensor into an optimized evaluation tree that can efficiently compute numerical values for different parameter inputs.

Parameters

  • constants (dict) Dict mapping symbolic expressions to their constant numerical values
  • funs (dict) Dict mapping function signatures to their symbolic definitions
  • params (list of Expression) List of symbolic parameters that will be varied during evaluation
  • iterations (int, optional) Number of optimization iterations for Horner scheme (default: 100)
  • n_cores (int, optional) Number of CPU cores to use for optimization (default: 4)
  • verbose (bool, optional) Whether to print optimization progress (default: False)

Returns

  • TensorEvaluator An optimized evaluator for efficient numerical evaluation

Examples

from symbolica import S
from symbolica.community.spenso import Tensor, TensorIndices, Representation as R
x, y = S("x", "y")
structure = TensorIndices(R.euc(2)(1))
tensor = Tensor.dense(structure, [x * y, x + y])
evaluator = tensor.evaluator(constants={}, funs={}, params=[x, y], iterations=50)
results = evaluator.evaluate_complex([[1.0, 2.0], [3.0, 4.0]])

one

Tensor.one() -> Tensor

Create a scalar tensor with value 1.0.

Returns

  • Tensor A scalar tensor containing the value 1.0

Examples

from symbolica.community.spenso import Tensor
one = Tensor.one()

scalar

Tensor.scalar() -> Expression

Extract the scalar value from a rank-0 (scalar) tensor.

Returns

  • Expression The scalar expression contained in this tensor

Raises

  • RuntimeError: If the tensor is not a scalar

Examples

from symbolica.community.spenso import Tensor
scalar_tensor = Tensor.one()
value = scalar_tensor.scalar()

sparse

Tensor.sparse(structure: TensorIndices | builtins.list[Slot], type_info: type) -> Tensor

Create a new sparse empty tensor with the given structure and data type.

Parameters

  • structure (TensorIndices or list of Slots) The tensor structure defining shape and index properties
  • type_info (type) The data type - either float or Expression class

Returns

  • Tensor A new sparse tensor with all elements initially zero

Examples

from symbolica.community.spenso import Tensor, TensorIndices, Representation as R
structure = TensorIndices(R.euc(3)(1), R.euc(3)(2))
sparse_float = Tensor.sparse(structure, float)
sparse_sym = Tensor.sparse(structure, symbolica.Expression)

structure

Tensor.structure() -> TensorIndices

to_dense

Tensor.to_dense() -> None

Convert this tensor to dense storage format.

Convert this tensor to dense storage format.

Converts sparse tensors to dense format in-place. Dense tensors are unchanged. This allocates memory for all tensor elements.

Examples

from symbolica.community.spenso import Tensor, TensorIndices, Representation as R
structure = TensorIndices(R.euc(4)(2))
tensor = Tensor.sparse(structure, float)
tensor[0] = 1.0
tensor.to_dense()

to_sparse

Tensor.to_sparse() -> None

Convert this tensor to sparse storage format.

Convert this tensor to sparse storage format.

Converts dense tensors to sparse format in-place, only storing non-zero elements. This can save memory for tensors with many zero elements.

Examples

from symbolica.community.spenso import Tensor, TensorIndices, Representation as R
structure = TensorIndices(R.euc(2)(2), R.euc(2)(1))
data = [1.0, 0.0, 0.0, 2.0]
tensor = Tensor.dense(structure, data)
tensor.to_sparse()

zero

Tensor.zero() -> Tensor

Create a scalar tensor with value 0.0.

Returns

  • Tensor A scalar tensor containing the value 0.0

Examples

from symbolica.community.spenso import Tensor
zero = Tensor.zero()