API Reference

Every public entry point, grouped by module. ttnumpy is the one most code needs: it re-exports the container, the constructors and the solvers, so import ttnumpy as tt reaches all of them.

Tensor trains and solvers

The public surface: the TensorTrain container, the constructors, the three linear solvers and the types they report with.

Public tensor-train API for TTNumPy.

class ttnumpy.LocalSolver(value)[source]

Bases: str, Enum

Local-system solver selection shared by the sweep solvers.

AUTO picks MINRES or GMRES from the symmetric flag; DIRECT forces the explicit LU solve.

AUTO = 'auto'
DIRECT = 'direct'
GMRES = 'gmres'
MINRES = 'minres'
class ttnumpy.SolverInfo(residuals=<factory>, num_sweeps_run=0, stop_reason=StopReason.MAX_SWEEPS, max_bonds=<factory>, local_solves=0, local_fallbacks=0, local_inexact=0)[source]

Bases: object

Convergence information collected during an iterative TT solve.

Shared by the MALS, ALS and AMEn solvers.

Parameters:
property converged: bool

Whether the run stopped because residual_tol was reached.

local_fallbacks: int = 0

Iterative local solves that missed local_rtol and were redone exactly on the explicit matrix.

local_inexact: int = 0

Iterative local solves that missed local_rtol and were accepted as they stood, because the dense fallback was not allowed.

local_solves: int = 0

Iterative local solves over the whole run.

max_bonds: List[int]

Maximum bond dimension of the solution after each completed sweep. Populated by the rank-adaptive solvers (MALS and AMEn); left empty by ALS, whose ranks are fixed.

num_sweeps_run: int = 0

Number of sweeps actually performed.

residuals: List[float]

Relative residual ||A @ x - b|| / ||b|| after each completed sweep. Empty if residual tracking was disabled.

stop_reason: StopReason = 'max_sweeps'

Why the iteration ended (see StopReason).

class ttnumpy.StopReason(value)[source]

Bases: str, Enum

Why an iterative TT solve stopped.

A str mixin so info.stop_reason == "converged" comparisons and JSON serialization keep working with the plain value.

CONVERGED = 'converged'

The relative residual reached residual_tol.

MAX_SWEEPS = 'max_sweeps'

All max_sweeps sweeps were run.

STAGNATED = 'stagnated'

A sweep improved the residual by less than stagnation_factor.

class ttnumpy.TensorTrain(cores)[source]

Bases: object

Tensor Train (TT) type.

Contains TT initialization and basic operations. Supports Tensor Train Matrix (TTM) format. Both TT and TTM are treated as rank-4 tensors:

ranks[i] x row_modes[i] x col_modes[i] x ranks[i+1],

where, for TT, the column dimension is 1.

Reference: - Matrix product state basics https://arxiv.org/abs/1008.3477; - Tensor train https://epubs.siam.org/doi/abs/10.1137/090752286

Parameters:

cores (List[ndarray])

add(other, truncate=True)[source]

Sum of two tensor trains.

Resulting tensor train will have bond dimensions equal to sum of bond dimensions of summands.

Parameters:
  • other (TensorTrain) – Tensor train to be added;

  • truncate (bool) – If True, truncate resulting tensor train after addition (default=True).

Raises:
Returns:

Sum of two tensor trains.

Return type:

TensorTrain

compress_svd(error=0.0, max_rank=None, canonical='auto', inplace=False)[source]

Compress the tensor train with an SVD-based truncation.

Parameters:
  • error (float) – Allowed truncation error. Defaults to 0.0.

  • max_rank (Optional[int]) – Optional bound for the bond dimension.

  • canonical (Literal['left', 'right', 'auto']) – Canonical form to use. "left" performs a left-to-right SVD sweep, "right" performs a right-to-left sweep, and "auto" chooses the direction from orth_center.

  • inplace (bool) – If True, modify this tensor train in place.

Raises:

ValueError – If canonical is not ‘left’, ‘right’ or ‘auto’.

Return type:

TensorTrain

Returns:

Tensor train after SVD compression.

conj(inplace=False)[source]

Conjugate tensor train.

Parameters:

inplace (bool) – If True, perform operation inplace (default=False).

Returns:

Conjugated tensor train.

Return type:

TensorTrain

copy()[source]

Create a copy of tensor train.

Return type:

TensorTrain

dot(other, truncate=False)[source]

Matrix product of two tensor trains.

Four types of products are supported: - Matrix-vector product: TTM @ TT; - Matrix product: TTM @ TTM; - Outer product: TT @ TT.transpose(); - Inner product: TT.transpose() @ TT.

There is no implicit transposition: column modes of the left operand must match row modes of the right operand. The inner product is returned as a TT with all physical dimensions equal to 1; use get_full_tensor() to extract the scalar. Note that complex operands are not conjugated (matmul semantics).

Parameters:
  • other (TensorTrain) – Tensor train to be multiplied;

  • truncate (bool) – If True, truncate resulting tensor train after multiplication (default=True).

Raises:
Returns:

Matrix product of two tensor trains.

Return type:

TensorTrain

get_element(element_index)[source]

Get one element from tensor train.

All physical indices must be given in the element_index argument. If tensor train is in TTM format, element_index must contain tuples of index pairs.

Parameters:

element_index (List[Union[int, Tuple[int]]]) – list of physical indices for each core. For TTM, each index must be a tuple of (row_index, col_index).

Raises:

DimensionMismatch – If number of given indices is not equal to number of cores or if tensor train is in TTM format, but given indices are not tuples of (row_index, col_index).

Returns:

element of the tensor train at the given index.

Return type:

float

get_full_tensor()[source]

Collapse train into full tensor.

For TT format, resulting tensor will have shape (row_dim_1, row_dim_2, …). For TTM format, resulting tensor will have shape (row_dim_1, row_dim_2, …, col_dim_1, col_dim_2, …).

Return type:

ndarray

is_ttm()[source]

Check whether tensor train is an operator.

Return type:

bool

multiply(other, truncate=False)[source]

Element-wise product of two tensor trains or tensor train and scalar.

Parameters:
  • other (Union[int, float, complex, TensorTrain]) – Tensor train or scalar to be multiplied;

  • truncate (bool) – If True, truncate resulting tensor train after multiplication (default=False).

Raises:
  • TypeError – If other is not TensorTrain type or scalar;

  • DimensionMismatch – If tensor trains have different physical dimensions.

Return type:

TensorTrain

orthonormalize(canonical='left', center_position=None, inplace=False)[source]

Orthonormalization of tensor train with QR decomposition.

Parameters:
  • canonical (Literal['left', 'right', 'mix']) – type of final canonical form. “left” for left-orthonormalization, “right” for right-orthonormalization, “mix” for mixed method (default).

  • center_position (Optional[int]) – position of the center core, up to which TT will be orthonormalized. If None (default), center position will be in the middle of the tensor train.

  • inplace (bool) – If True, perform operation inplace (default=False).

Raises:

ValueError – If center_position is out of range or canonical is unknown.

Returns:

Orthonormalized tensor train. orth_center is set only when the resulting train is in a valid canonical form: a partial “left”/”right” sweep on a train without a known orthogonal center leaves orth_center unset.

Return type:

TensorTrain

physical_dims()[source]

Get list of physical dimensions.

Return type:

List

qtt_to_tt(physical_indexes, error=1e-12, max_rank=None)[source]

Convert a quantized tensor train back to a standard TT.

Parameters:
  • physical_indexes (Union[List[int], List[Tuple[int]]]) – Original TT physical dimensions.

  • error (float) – Allowed truncation error after reconstruction.

  • max_rank (Optional[int]) – Optional maximum TT rank after reconstruction.

Returns:

Reconstructed standard tensor train.

Return type:

TensorTrain

Raises:

DimensionMismatch – If the QTT dimensions do not match the original TT dimensions.

transpose(cores_ind=None, conjugate=False, inplace=False)[source]

Transpose tensor train.

Parameters:
  • cores_ind (Optional[List[int]]) – indices of cores that should be transposed. If cores_ind=None (default), all cores are transposed.

  • conjugate (bool) – If True, conjugate tensor train matrix.

  • inplace (bool) – If True, perform operation inplace (default=False).

Returns:

Transposed tensor train.

Return type:

TensorTrain

truncate(error=1e-15, max_rank=None, canonical='auto', inplace=False)[source]

Round tensor train to minimal ranks.

Default strategy is left-to-right orthonormalization using QR decomposition, then right-to-left truncation using SVD decomposition. If orth_center is set and orth_direction is “auto”, orthonormalization will start from orth_center position to the closest boundary, so direction of sweeps might change.

Example

If orth_center is in the left half of the tensor train, right-to-left orthonormalization will be performed first, then left-to-right truncation.

Parameters:
  • error (float) – Allowed error of truncation;

  • max_rank (Optional[int]) – If given, set a bound for bond dimension;

  • canonical (Literal['auto', 'left', 'right']) – Type of final canonical form. If “auto” (default), direction will be chosen based on orth_center position.

  • inplace (bool) – If True, perform operation inplace (default=False).

Raises:

ValueError – If canonical is not ‘auto’, ‘left’ or ‘right’.

Returns:

Truncated tensor train.

Return type:

TensorTrain

tt_norm()[source]

Calculate Frobenius norm of tensor train.

For TTM, norm is calculated as norm of the corresponding TT, so it is not the operator norm, but rather the Frobenius norm of the corresponding matrix.

If orth_center is set, the norm is the norm of the center core and no orthogonalization is performed.

Return type:

float

tt_to_qtt(mode_size=2, error=1e-12, max_rank=None)[source]

Convert tensor train to quantized tensor train (QTT) format.

Each core with mode m decomposes into log_{mode_size}(m) cores with mode_size physical dimensions. For example, a core with shape (r_i, 16, r_{i+1}) will decompose into 4 cores with shapes (r_i, 2, 1, new_bond), …, (new_bond, 2, 1, r_{i+1}), where new_bond is determined by SVD truncation with given error and max_rank.

Parameters:
  • mode_size (int) – size of quantized modes (default=2);

  • error (float) – Allowed error of truncation (default=1e-12);

  • max_rank (Optional[int]) – If given, set a bound for bond dimension.

Returns:

Tensor train in QTT format. The result is left-canonical with orth_center at the last core.

Return type:

TensorTrain

Raises:
  • DimensionMismatch – If any of the row modes is not a power of mode_size or if tensor train is in TTM format and any of the column modes is not a power of mode_size.

  • ValueError – If mode_size is less than 2 or max_rank is not a positive integer.

class ttnumpy.TensorTrainType(value)[source]

Bases: Enum

Type of Tensor Train

TT = 'Tensor Train'
TTM = 'Tensor Train Matrix'
class ttnumpy.TruncationMode(value)[source]

Bases: str, Enum

How a solved local system is truncated to pick the next bond.

RESIDUAL = 'residual'

Smallest rank whose local residual stays within the per-truncation budget (truncation_tol).

THRESHOLD = 'threshold'

Drop singular values below error_threshold times the largest.

ttnumpy.als(A, b, x0=None, inplace=False, max_sweeps=4, residual_tol=None, stagnation_factor='auto', local_solver='auto', direct_solve_size=1000, local_rtol=None, allow_dense_fallback=False, symmetric=False, return_info=False)[source]

Alternating Least Squares (ALS) method for solving Ax = b.

Sweeps over single cores, solving a projected system for each and moving the orthogonality centre along. The bond dimensions never grow, so x0 must already carry enough rank to represent the solution; amen() adds the residual enrichment that lifts this restriction.

Local systems are solved directly (LU on the explicit matrix) while small; above direct_solve_size unknowns they are solved matrix-free with a warm-started Krylov method held to local_rtol.

Parameters:
  • A (TensorTrain) – Operator in TTM format.

  • b (TensorTrain) – Right-hand side in TT format.

  • x0 (Optional[TensorTrain]) – Initial guess in TT format; its ranks are kept throughout. Defaults to an all-ones train with the ranks of b.

  • inplace (bool) – If True, modify x0 in place instead of copying it.

  • max_sweeps (int) – Maximum number of sweeps.

  • residual_tol (Optional[float]) – Target relative residual for early stopping. None disables it (and, with it, the local_rtol derivation below).

  • stagnation_factor (Union[float, str, None]) – Stop when a sweep improves the residual by less than this factor; must be in (0, 1]. “auto” (default) enables the check with factor 0.9 when residuals are tracked anyway (residual_tol set or return_info=True) and disables it otherwise. An explicit float always enables the check; None disables it.

  • local_solver (Union[str, LocalSolver]) – Krylov method for large local systems. “auto” picks MINRES when symmetric is True and GMRES otherwise; “minres”/”gmres” force one; “direct” always uses the explicit LU solve.

  • direct_solve_size (int) – Local systems with at most this many rows are solved directly.

  • local_rtol (Optional[float]) – Relative tolerance the iterative local solves are held to. None derives it from residual_tol when that is set, and otherwise uses a fixed default.

  • allow_dense_fallback (bool) – If True, a local solve that misses local_rtol is redone exactly on the explicit matrix, at the cost of building it. False by default, which keeps the inexact iterate and the memory bound.

  • symmetric (bool) – Declare A symmetric so “auto” can use MINRES.

  • return_info (bool) – If True, also return a SolverInfo with per-sweep residuals, the stop reason, and how the iterative local solves ended (local_solves, local_fallbacks, local_inexact).

Returns:

Solution x, or a tuple (x, SolverInfo) if return_info is True.

Return type:

TensorTrain

ttnumpy.amen(A, b, x0=None, inplace=False, kickrank=4, error_threshold=1e-07, max_rank=None, max_sweeps=1, residual_tol=None, residual_damp=2.0, stagnation_factor='auto', local_solver='auto', direct_solve_size=1000, local_rtol=None, allow_dense_fallback=False, symmetric=False, return_info=False, seed=None)[source]

Alternating Minimal Energy (AMEn) method for solving Ax = b.

One-site sweep as in als(), except that each solved core is SVD-truncated and then widened with a low-rank approximation of the residual b - A x, so the bond dimensions adapt instead of staying fixed. The residual approximation is a separate rank-kickrank train maintained by projection and refitted core by core as the sweep proceeds. The enrichment leaves the represented solution unchanged; it enlarges the subspace the next local solve optimises over.

Parameters:
  • A (TensorTrain) – Operator in TTM format.

  • b (TensorTrain) – Right-hand side in TT format.

  • x0 (Optional[TensorTrain]) – Initial guess in TT format. Defaults to an all-ones train with the ranks of b; unlike als() a poor guess is fine, since enrichment grows the ranks as needed.

  • inplace (bool) – If True, modify x0 in place instead of copying it.

  • kickrank (int) – Bond dimension of the residual train, and the maximum rank added to each bond per enrichment. Typical values 2-4.

  • error_threshold (float) – Relative SVD cutoff for the truncation of each solved core; only used when residual_tol is None. Singular values below error_threshold * sigma_1 are dropped before the enrichment is appended.

  • residual_damp (float) – Allowed growth factor of the local residual due to truncation when residual_tol is set (reasonable values 2 to 5); see mals() for when it has any effect. Must be >= 1. Ignored in the error_threshold cutoff mode.

  • max_rank (Optional[int]) – Hard cap on every bond dimension, matching mals(). The solved core is truncated to at most max_rank and the enrichment then fills only the remaining slots below it, so a bond that reaches max_rank is enriched by less than kickrank (by nothing once the solution alone fills the cap). None leaves the ranks unbounded.

  • max_sweeps (int) – Maximum number of sweeps. Ranks grow by at most 2 * kickrank per sweep (less near max_rank), so starting from a low-rank guess the solver needs several sweeps to build up the rank it needs.

  • residual_tol (Optional[float]) – Target relative residual for early stopping, and (as in mals()) the switch to residual-based core truncation, which makes it the single accuracy knob and ignores error_threshold. None disables both. The stopping test uses it whole; the truncations of a sweep share it, since their errors add in quadrature.

  • stagnation_factor (Union[float, str, None]) – Stop when a sweep improves the residual by less than this factor; must be in (0, 1]. “auto” (default) enables the check with factor 0.9 when residuals are tracked anyway (residual_tol set or return_info=True) and disables it otherwise. An explicit float always enables the check; None disables it.

  • local_solver (Union[str, LocalSolver]) – Krylov method for large local systems. “auto” picks MINRES when symmetric is True and GMRES otherwise; “minres”/”gmres” force one; “direct” always uses the explicit LU solve.

  • direct_solve_size (int) – Local systems with at most this many rows are solved directly.

  • local_rtol (Optional[float]) – Relative tolerance the iterative local solves are held to. None derives it from residual_tol when that is set, and otherwise uses a fixed default.

  • allow_dense_fallback (bool) – If True, a local solve that misses local_rtol is redone exactly on the explicit matrix, at the cost of building it; see mals(). False by default, which keeps the inexact iterate and the memory bound.

  • symmetric (bool) – Declare A symmetric so “auto” can use MINRES.

  • return_info (bool) – If True, also return a SolverInfo with per-sweep residuals, per-sweep maximum bond dimensions (max_bonds), the stop reason, and how the iterative local solves ended (local_solves, local_fallbacks, local_inexact).

  • seed (Optional[int]) – Seed for the random initial residual train, for reproducible runs.

Returns:

Solution x, or a tuple (x, SolverInfo) if return_info is True.

Return type:

TensorTrain

Raises:
  • ValueError – If kickrank or max_rank is not positive, residual_damp is below 1, or an argument shared with als() is invalid.

  • DimensionMismatch – If A, b and x0 are not shape-compatible.

Example

Solve a QTT-structured system from the default guess, letting the ranks grow until the residual target is met:

x, info = amen(
    A, b, residual_tol=1e-8, max_sweeps=20,
    symmetric=True, return_info=True,
)
print(info.stop_reason, info.residuals[-1], info.max_bonds)
Reference:

Dolgov & Savostyanov, SIAM J. Sci. Comput. 36(5), 2014, https://doi.org/10.1137/140953289.

ttnumpy.canonical_tt(physical_indexes, max_rank)[source]

Create a full-rank tensor train consisting of tensor products of the canonical basis.

Tensor train is created in the following format: A^1 A^2 … A^{n//2} B^{n//2+1} … B^{n} where A^i are left-orthogonal cores and B^i are right-orthogonal cores. For odd n, the middle core is left-orthogonal.

Bond k (connecting cores k-1 and k) is set to min(max_rank, prod(dims[:k]), prod(dims[k:])), i.e. it is capped by the number of basis states on either side of the cut, so the left and right halves always meet with matching bond dimensions.

Parameters:
  • physical_indexes (List[int]) – List of physical dimensions for each core. Tensor Train Matrix format is not supported.

  • max_rank (int) – Maximum rank of the TT decomposition.

Returns:

Canonical tensor train.

Return type:

TensorTrain

ttnumpy.eye(physical_indexes)[source]

Create an identity tensor train.

Parameters:

physical_indexes (List[int]) – List of physical dimensions for each core. Row and column dimensions are the same. All ranks are 1.

Returns:

Identity tensor train.

Return type:

TensorTrain

ttnumpy.mals(A, b, x0=None, inplace=False, max_rank=None, max_sweeps=2, residual_tol=None, residual_damp=2.0, stagnation_factor='auto', error_threshold=1e-07, local_solver='auto', direct_solve_size=1000, local_rtol=None, allow_dense_fallback=False, symmetric=False, return_info=False)[source]

Modified Alternating Least Squares (MALS) method for solving Ax = b.

Sweeps over pairs of neighbouring cores, solving a small projected system for each pair and adapting the ranks in the decimation step. After each full sweep the relative residual ||A @ x - b|| / ||b|| is measured in TT arithmetic; the iteration stops when it reaches residual_tol, stagnates, or max_sweeps is exhausted.

Truncation works in one of two modes:

  • residual_tol set (recommended): residual-based truncation. Each decimation keeps the smallest rank whose local residual stays within budget, so residual_tol is the single accuracy parameter and error_threshold is ignored.

  • residual_tol None: cutoff discarding singular values below error_threshold * sigma_1. This controls the error of the solution, but leaves the residual bounded only by cond(A) * error_threshold.

Local systems are solved directly (LU on the explicit matrix) while small; above direct_solve_size unknowns they are solved matrix-free with a warm-started Krylov method. A Krylov solve that misses local_rtol is accepted as it stands, which keeps the memory bounded and leaves the outer sweep to correct it; allow_dense_fallback trades that for exactness.

Parameters:
  • A (TensorTrain) – Operator in TTM format.

  • b (TensorTrain) – Right-hand side in TT format.

  • x0 (Optional[TensorTrain]) – Initial guess for the solution in TT format.

  • inplace (bool) – If True, modify x0 in place instead of copying it.

  • max_rank (Optional[int]) – Maximum allowed bond dimension.

  • max_sweeps (int) – Maximum number of sweeps.

  • residual_tol (Optional[float]) – Target relative residual; enables residual-based truncation and early stopping. None disables both. The stopping test uses it whole; the truncations of a sweep share it, since their errors add in quadrature.

  • residual_damp (float) – Allowed growth factor of the local residual due to truncation (reasonable values 2 to 5). Must be >= 1. It scales the local solve’s own residual, which the direct path drives to machine precision, so it changes nothing there – only a loosely solved iterative system is affected.

  • stagnation_factor (Union[float, str, None]) – Stop when a sweep improves the residual by less than this factor; must be in (0, 1]. “auto” (default) enables the check with factor 0.9 when residuals are tracked anyway (residual_tol set or return_info=True) and disables it otherwise, so pure error_threshold runs do not pay a per-sweep residual evaluation. An explicit float always enables the check (and with it the residual tracking); None disables it.

  • error_threshold (float) – Relative SVD truncation threshold; only used when residual_tol is None.

  • local_solver (Union[str, LocalSolver]) – Krylov method for large local systems. “auto” picks MINRES when symmetric is True and GMRES otherwise; “minres”/”gmres” force one; “direct” always uses the explicit LU solve.

  • direct_solve_size (int) – Local systems with at most this many rows are solved directly.

  • local_rtol (Optional[float]) – Relative tolerance the iterative local solves are held to. None derives it from residual_tol when that is set, and otherwise uses a fixed default.

  • allow_dense_fallback (bool) – If True, a local solve that misses local_rtol is redone exactly on the explicit matrix. False by default and the inexact iterate is kept instead.

  • symmetric (bool) – Declare A symmetric so “auto” can use MINRES.

  • return_info (bool) – If True, also return a SolverInfo with per-sweep residuals, per-sweep maximum bond dimensions (max_bonds), the stop reason, and how the iterative local solves ended (local_solves, local_fallbacks, local_inexact).

Returns:

Solution x, or a tuple (x, SolverInfo) if return_info is True.

Return type:

TensorTrain

Reference:

Oseledets & Dolgov, SIAM J. Sci. Comput. 34(5), 2012, https://doi.org/10.1137/110833142 (sections 3.3-3.4 and 4).

ttnumpy.ones(physical_indexes, ranks=1)[source]

Create a tensor train filled with ones.

Parameters:
  • physical_indexes (Union[List[int], List[Tuple[int]]]) – List of physical dimensions for each core. For Tensor Train Matrix, each physical dimension should be a tuple of (row_dim, col_dim).

  • ranks (Union[int, List[int]]) – List of TT ranks. Defaults to [1, …, 1].

Returns:

Tensor train filled with ones.

Return type:

TensorTrain

ttnumpy.rand(physical_indexes, ranks=1, seed=None)[source]

Create a random tensor train.

Parameters:
  • physical_indexes (Union[List[int], List[Tuple[int]]]) – List of physical dimensions for each core. For Tensor Train Matrix, each physical dimension should be a tuple of (row_dim, col_dim).

  • ranks (Union[int, List[int]]) – List of TT ranks. Defaults to [1, …, 1].

Returns:

Random tensor train.

Return type:

TensorTrain

ttnumpy.relative_residual(A, b, x, b_norm=None)[source]

Relative residual ||A @ x - b|| / ||b||, computed in TT arithmetic.

The residual is formed as a tensor train and its norm is taken via orthogonalization, so nothing is densified. Taking the norm of the difference (rather than expanding it into scalar products) stays accurate for small residuals.

Parameters:
  • A (TensorTrain) – Operator in TTM format.

  • b (TensorTrain) – Right-hand side in TT format.

  • x (TensorTrain) – Candidate solution in TT format.

  • b_norm (Optional[float]) – Precomputed ||b||, to avoid recomputation inside loops.

Returns:

||A @ x - b|| / ||b||, or ||A @ x - b|| if ||b|| == 0.

Return type:

float

ttnumpy.tt_svd(tensor, error=0.0, max_rank=None, physical_indexes=None, ttm=False)[source]

TT-SVD algorithm for constructing a tensor train. Perform singular value decomposition of a tensor and decompose it into tensor train format.

Parameters:
  • tensor (ndarray) – n-dimensional array. If physical_indexes is None, tensor indexes will be treated as physical indexes.

  • error (float) – Error of tensor approximation. All singular values lower than error * ||A|| * (n-1)^{-1/2}, where ||.|| is the Frobenius norm.

  • max_rank (Optional[int]) – If given, set a bound for bond dimension

  • physical_indexes (Union[List[int], List[Tuple[int]], None]) – physical indices for tensor train format. For TTM, rows and columns must be paired: [(i_1, j_1), (i_2, j_2), …]

  • ttm (bool) – If True, decompose tensor as tensor train matrix (MPO). In the TTM case, tensor indices are considered as follows: A(i_1, i_2, …, i_n, j_1, …, j_n)

Returns:

Approximation of the tensor in tensor train format with the given error.

Return type:

TensorTrain

Raises:

AmbiguousFormat – If tensor is rank 1 and physical indexes are not provided or if tensor is Tensor Train Matrix, but physical indexes are not provided

Reference:

TT-SVD (algorithm No. 1) https://epubs.siam.org/doi/abs/10.1137/090752286

ttnumpy.zeros(physical_indexes, ranks=1)[source]

Create a tensor train filled with zeros.

Parameters:
  • physical_indexes (Union[List[int], List[Tuple[int]]]) – List of physical dimensions for each core. For Tensor Train Matrix, each physical dimension should be a tuple of (row_dim, col_dim).

  • ranks (Union[int, List[int]]) – List of TT ranks. Defaults to [1, …, 1].

Returns:

Tensor train filled with zeros.

Return type:

TensorTrain

Exceptions

Raised by the container and its constructors on malformed input. They live in ttnumpy.tensor_train and are not re-exported from ttnumpy, so import them from their defining module.

exception ttnumpy.tensor_train.DimensionMismatch(msg='Dimension mismatch')[source]

Bases: Exception

Exception for dimension errors.

exception ttnumpy.tensor_train.WrongTTFormat(msg='Wrong tensor train format')[source]

Bases: Exception

Exception for error in tensor train structure.

exception ttnumpy.tensor_train.WrongTTType(msg='Wrong tensor train type')[source]

Bases: Exception

Exception for error in tensor train type.

exception ttnumpy.tensor_train.AmbiguousFormat(msg='Not enough information to define object')[source]

Bases: Exception

Exception for insufficient information leading to ambiguous format.

Solver internals

The three solvers are implemented in the ttnumpy.solvers package — one module per method (als, mals, amen) over a shared common module holding the environments, the local solves and the stopping machinery — and are re-exported from ttnumpy above. Two-site and one-site local systems live in two_site and one_site respectively.

Low-level utilities

Norms, orthonormalization and SVD-based truncation, used by the container and the solvers. Most code should prefer the TensorTrain methods that wrap these.

Module for utility functions on tensor trains.

ttnumpy.utils.left_orthonormalize(cores, start, end)[source]

Left orthonormalize tensor train cores.

Parameters:
  • cores (List[ndarray]) – Tensor train cores.

  • start (int) – Start position for orthonormalization.

  • end (int) – End position for orthonormalization.

Return type:

List[ndarray]

Returns:

Orthonormalized tensor train cores.

ttnumpy.utils.left_svd(cores, error, max_rank=None)[source]

Left svd truncation of tensor train cores.

Parameters:
  • cores (List[ndarray]) – Tensor train cores.

  • error (float) – Truncation threshold.

  • max_rank (Optional[int]) – Maximum rank after truncation.

Return type:

List[ndarray]

Returns:

Truncated tensor train cores.

ttnumpy.utils.right_orthonormalize(cores, start, end)[source]

Right orthonormalize tensor train cores.

Parameters:
  • cores (List[ndarray]) – Tensor train cores.

  • start (int) – Start position for orthonormalization.

  • end (int) – End position for orthonormalization.

Return type:

List[ndarray]

Returns:

Orthonormalized tensor train cores.

ttnumpy.utils.right_svd(cores, error, max_rank=None)[source]

Right svd truncation of tensor train cores.

Parameters:
  • cores (List[ndarray]) – Tensor train cores.

  • error (float) – Truncation threshold.

  • max_rank (Optional[int]) – Maximum rank after truncation.

Return type:

List[ndarray]

Returns:

Truncated tensor train cores.

ttnumpy.utils.tensor_norm(tensor)[source]

Frobenius tensor norm.

Return type:

float

Parameters:

tensor (ndarray)

ttnumpy.utils.truncated_bond(singular_values, delta, max_rank=None)[source]

Smallest bond dimension whose discarded tail stays within delta.

Returns the smallest r satisfying

\[\sqrt{\sum_{i > r} \sigma_i^2} \le \delta,\]

floored at 1 and capped by max_rank. This is the criterion the TT-SVD error bound assumes: the Frobenius norm of what is thrown away is what enters the bound, so bounding it per split bounds the global error by the sum in quadrature over the splits.

Parameters:
  • singular_values (ndarray) – Singular values in descending order.

  • delta (float) – Largest acceptable Frobenius norm of the discarded tail.

  • max_rank (Optional[int]) – Maximum rank after truncation.

Raises:

ValueError – If max_rank is not a positive integer.

Return type:

int

Returns:

Bond dimension after truncation.

Logging

Application-facing logging setup. The library attaches no handlers of its own; call setup_logging() once from a script or CLI, or configure the ttnumpy logger directly.

Application-facing logging setup for the ttnumpy package.

The package uses exactly two loggers, both direct children of the root logger. Reach them with the plain stdlib call and the names below:

  • PACKAGE_LOGGER_NAME (ttnumpy) – everything the library emits.

  • TEST_LOGGER_NAME (ttnumpy-test) – test code. The hyphen matters: logger hierarchy splits on dots, so ttnumpy-test is a separate root and raising the library’s verbosity never raises the tests’.

Module identity is not lost by sharing one logger name. A filter installed at the bottom of this module stamps every record with the dotted path of the file that emitted it, so a line still reads [ttnumpy.solvers.common].

Library code attaches no handlers. Applications opt in by calling setup_logging() once from a script or CLI; it configures the ttnumpy logger, never the root logger.

class ttnumpy.logger_config.LevelFormatter(formatters, default_formatter=None)[source]

Bases: Formatter

A logging formatter that selects a different formatter per logging level.

Parameters:
format(record)[source]

Format the specified record using the appropriate formatter based on the record’s level.

Parameters:

record (logging.LogRecord) – The log record to format.

Returns:

The formatted log message.

Return type:

str

ttnumpy.logger_config.reset_logging()[source]

Undo setup_logging(), restoring the quiet library default.

Removes the handler installed by setup_logging(), restores propagation, and clears the explicit level.

Returns:

The ttnumpy package logger.

Return type:

logging.Logger

ttnumpy.logger_config.resolve_level(level=None)[source]

Translate the accepted level spellings into a logging level number.

Accepts a level name ("DEBUG"), a logging constant (logging.DEBUG), or a legacy verbosity count (0 WARNING, 1 INFO, 2 or more DEBUG). None reads TTNUMPY_LOG_LEVEL from the environment and falls back to WARNING.

Parameters:

level (Union[int, str, None]) – The level to resolve.

Returns:

The corresponding logging level number.

Return type:

int

Raises:

ValueError – If the level is not a recognised name or number.

ttnumpy.logger_config.set_level(level=None)[source]

Set the verbosity of the ttnumpy logger without touching its handlers.

Parameters:

level (Union[int, str, None]) – Any level accepted by resolve_level().

Returns:

The logging level number that was applied.

Return type:

int

ttnumpy.logger_config.setup_logging(level=None, *, stream=None, capture_warnings=False)[source]

Send ttnumpy log records to a stream handler.

Safe to call repeatedly: the handler installed by a previous call is replaced rather than stacked, and handlers attached by the host application are left alone. The root logger is never modified, so third-party libraries keep whatever verbosity they already had.

Parameters:
  • level (Union[int, str, None]) – Any level accepted by resolve_level(). None reads TTNUMPY_LOG_LEVEL and falls back to WARNING.

  • stream – Destination stream. Defaults to sys.stderr.

  • capture_warnings (bool) – Route warnings through logging. This is a process-wide setting, so it stays off unless asked for. Enable it only when the application has configured the root logger: warnings are logged to py.warnings, which sits outside the ttnumpy tree, and logging.captureWarnings() gives it a NullHandler, so without a root handler the warnings are discarded rather than shown.

Returns:

The configured ttnumpy package logger.

Return type:

logging.Logger

Benchmarks

The benchmark harness: the Poisson problem in both sparse and TT form, and the runner that times the TT solvers against SciPy, PyAMG and PETSc. This is research and CI tooling rather than library API.

The Poisson benchmark problem: QTT Laplacian, assembly and TT solve.

Builds -Delta u = rhs on a square with homogeneous Dirichlet boundaries in both the forms the benchmarks need: a sparse matrix with a dense right-hand side for the classical backends, and a TT operator with a TT right-hand side for MALS and AMEn.

class benchmarks.poisson_problem.PoissonProblem(N, K, h, laplacian_tt, rhs_qtt, rhs, exact, laplacian, mode_size=2)[source]

Bases: object

Discrete Poisson problem on the unit square.

K = 2**N is the number of interior points per axis and h the grid spacing. rhs holds the right-hand side sampled on the interior grid and flattened in C order ([y, x], y slow); rhs_qtt is its TT form. laplacian is always the sparse matrix, while laplacian_tt is the TTM only when the problem was built with tt_format=True and the sparse matrix again otherwise. exact is the sparse direct reference solution, or None under compute_reference=False. mode_size is the tensorization of the TT operator and right-hand side; the grid, the operator and the solution do not depend on it.

Parameters:
K: int
N: int
exact: ndarray | None
h: float
laplacian: csr_matrix
laplacian_tt: TensorTrain | csr_matrix
mode_size: int = 2
rhs: ndarray
rhs_qtt: TensorTrain
benchmarks.poisson_problem.build_poisson_problem(L=1.0, N=3, rhs=1.0, rhs_tt_error=1e-12, tt_format=False, compute_reference=True, mode_size=2)[source]

Build \(-\Delta u = \mathrm{rhs}\) on \((0, L)^2\), Dirichlet.

The grid has K = 2**N interior points per axis with spacing h = L / (K + 1), so the interior nodes are x_i = y_i = (i + 1) * h.

Parameters:
  • L (float) – Side length of the square domain.

  • N (int) – QTT depth per axis.

  • rhs (Union[float, ndarray, Callable[[ndarray, ndarray], ndarray]]) – A constant, an array of samples on the interior grid (shape (K, K) indexed [y, x] or flat (K**2,)), or a vectorized callable f(x, y) evaluated on the interior nodes.

  • rhs_tt_error (float) – Relative error of the tt_svd compression of the sampled right-hand side.

  • tt_format (bool) – Also build the Laplacian as a TTM, which solve_poisson_tt() requires.

  • compute_reference (bool) – Solve the sparse system directly to fill exact. Turn it off on grids where spsolve dominates.

  • mode_size (int) – Tensorization of the operator and the right-hand side, leaving the grid alone: 2 is QTT, 2**k fuses k QTT cores per core (fold_cores()), and 2**N leaves one core per grid axis.

Return type:

PoissonProblem

Returns:

The assembled problem.

Raises:

ValueError – If rhs has an unusable shape, or if the base-2 logarithm of mode_size does not divide N.

benchmarks.poisson_problem.create_laplace_2d(N, h, mode_size=2, dtype=<class 'numpy.float64'>)[source]

Build the 2D finite-difference Laplacian as a QTT matrix.

Parameters:
  • N (int) – QTT depth per axis; the grid has 2**N points per axis.

  • h (float) – Grid spacing.

  • mode_size (int) – Mode size of the returned cores; a power of two whose base-2 logarithm divides N.

  • dtype – dtype of the returned cores.

Returns:

The Laplacian operator in TTM format.

Raises:

ValueError – If mode_size is not an admissible power of two.

benchmarks.poisson_problem.fold_cores(train, group)[source]

Fuse every group adjacent cores into one core.

Only the tensorization changes; the represented tensor does not. Mode sizes multiply, so group cores of mode size 2 become one core of mode size 2**group. Accepts both TT and TTM trains.

Parameters:
  • train (TensorTrain) – Train to fold.

  • group (int) – Cores per fused core; 1 returns a copy.

Return type:

TensorTrain

Returns:

The same tensor with n_cores // group cores.

Raises:

ValueError – If group is not positive or does not divide the core count.

benchmarks.poisson_problem.folding_group(mode_size, cores_per_axis)[source]

Number of QTT cores fused into one core of mode_size.

Parameters:
  • mode_size (int) – Requested mode size; must be a power of two.

  • cores_per_axis (int) – QTT cores addressing a single grid axis.

Return type:

int

Returns:

log2(mode_size).

Raises:

ValueError – If mode_size is not a power of two of at least 2, or if it does not divide the cores of one axis, which would fuse cores of two different axes into a single mode.

benchmarks.poisson_problem.solve_poisson_tt(problem, *, solver='mals', error_threshold=0.0001, max_rank=50, max_sweeps=1, residual_tol=None, kickrank=4, seed=None, return_info=False)[source]

Solve a prebuilt Poisson problem with one of the TT solvers.

Parameters:
  • problem (PoissonProblem) – Problem to solve; must carry tt_format=True.

  • solver (str) – "mals", "amen" or "als".

  • error_threshold (float) – Relative singular-value cutoff for MALS and AMEn.

  • max_rank (int | None) – Bond dimension cap for MALS and AMEn; None for no cap.

  • max_sweeps (int) – Sweep budget.

  • residual_tol (Optional[float]) – Target relative residual; None selects threshold-mode truncation.

  • kickrank (int) – Enrichment rank; used by "amen" only.

  • seed (Optional[int]) – Seed for AMEn’s random residual train, for reproducible runs.

  • return_info (bool) – Return (solution, SolverInfo) instead of the solution alone.

Return type:

TensorTrain | tuple[TensorTrain, SolverInfo]

Returns:

The solution, or (solution, SolverInfo) when return_info.

Raises:
  • TypeError – If the problem is not in TT format.

  • ValueError – If solver is not a known solver name.

Benchmarks for the Poisson equation solvers.

class benchmarks.poisson.TTSolverSettings(tolerance=1e-05, max_rank=None, max_sweeps=20, kickrank=4, mode_size=2, seed=0)[source]

Bases: object

TT solver parameters used by the benchmarks.

Parameters:
  • tolerance (float)

  • max_rank (int | None)

  • max_sweeps (int)

  • kickrank (int)

  • mode_size (int)

  • seed (int | None)

kickrank: int = 4
max_rank: int | None = None
max_sweeps: int = 20
mode_size: int = 2
seed: int | None = 0
tolerance: float = 1e-05
benchmarks.poisson.benchmark_petsc_poisson(n=3, problem=None, tolerance=1e-05)[source]

Solve the same Poisson system with PETSc CG and GAMG if petsc4py is installed.

Return type:

dict[str, Any] | None

Parameters:
benchmarks.poisson.benchmark_scipy_poisson(n=3, problem=None, preconditioned=False, tolerance=1e-05)[source]

Solve the same Poisson system with SciPy sparse CG.

With preconditioned=True, PyAMG smoothed aggregation is used and the AMG hierarchy setup is part of the timed region, consistent with the PETSc backend where GAMG setup happens inside ksp.solve. Falls back to plain CG when pyamg is not installed.

Return type:

dict[str, Any]

Parameters:
benchmarks.poisson.benchmark_tt_poisson(n=3, problem=None, tt_settings=TTSolverSettings(tolerance=1e-05, max_rank=None, max_sweeps=20, kickrank=4, mode_size=2, seed=0), solver='mals')[source]

Solve the manufactured Poisson problem with one of the TT solvers.

Problem construction (matrix assembly, reference solve, rhs compression) happens outside the timed region; only the TT solve is timed.

Return type:

dict[str, Any]

Parameters:
benchmarks.poisson.compare_poisson_solvers(n=3, tt_settings=TTSolverSettings(tolerance=1e-05, max_rank=None, max_sweeps=20, kickrank=4, mode_size=2, seed=0), compute_reference=True)[source]

Run every Poisson solver and collect timing and accuracy metrics.

The problem is built once and shared, so every backend solves the exact same system and none of them is charged for problem construction. Each TT solver gets its own entry; all iterative solvers are held to tt_settings.tolerance.

Return type:

dict[str, Any]

Parameters:
benchmarks.poisson.main(argv=None)[source]

Run Poisson benchmarks from the command line.

Return type:

int

Parameters:

argv (list[str] | None)

benchmarks.poisson.print_poisson_benchmark_suite_table(report)[source]

Print the benchmark suite table for multiple grid sizes.

Return type:

None

Parameters:

report (dict[str, Any])

benchmarks.poisson.write_poisson_benchmark_report(report, output_dir)[source]

Write the benchmark report to JSON and Markdown files.

Return type:

dict[str, Path]

Parameters: