Skip to content

NormalMPO

MPO subclass that tracks the overall scale factor separately from the unit-normed internal tensors.

NormalMPO

NormalMPO(
    tensors: List[Tensor],
    scale: float = 1.0,
    bc: str = "OBC",
    center: Optional[int] = None,
)

Bases: MPO

MPO with a separately tracked overall scale factor.

Represents the physical operator as _scale × mpo, where the internal MPO satisfies mpo.norm() ≈ 1 after compact() or from_mpo(). All arithmetic operations (+, @, *) preserve this representation, updating _scale analytically without altering the unit-norm convention until compact() is called explicitly.

Parameters:

Name Type Description Default
tensors List[Tensor]

Non-empty list of site tensors, each with 4 axes (left_bond, right_bond, phys_in, phys_out).

required
scale float

Overall scale factor. Defaults to 1.0.

1.0
bc str

Boundary condition: 'OBC' (default) or 'PBC'.

'OBC'
center Optional[int]

Orthogonality center site index, or None if unspecified.

None

Attributes

scale property

scale: float

Overall scale factor (read-only).

Functions

from_mpo classmethod

from_mpo(mpo: MPO) -> NormalMPO

Create a NormalMPO from a plain MPO.

The input MPO is not modified. The returned object has mpo.norm() ≈ 1 and scale == original_frobenius_norm.

Parameters:

Name Type Description Default
mpo MPO

Source MPO. May have any canonical form.

required

Returns:

Type Description
NormalMPO

Normalized copy with center=0.

Raises:

Type Description
ValueError

If the source MPO has numerically zero norm.

compact

compact(trunc: Optional[dict] = None) -> None

Compress bond dimensions in-place, keeping _scale consistent.

Performs the same two-sweep canonicalization as MPO.compact(), but folds the extracted norm into _scale instead of redistributing it across the site tensors. After the call, the internal MPO is approximately unit-normed and _scale absorbs the physical magnitude.

Bond arrows may be reoriented by the QR/SVD sweeps; this method restores the standard IN/OUT convention via capcup after the sweeps, so that subsequent trace(), __add__, and __matmul__ calls work correctly.

Parameters:

Name Type Description Default
trunc Optional[dict]

Truncation options forwarded to canonical() during the right-to-left compression sweep. Defaults to {'thresh': 1e-14}.

None

trace

trace() -> float

Compute the MPO trace \(\operatorname{Tr}[\rho]\).

Performs a left-to-right transfer-matrix sweep. At each site the physical indices (phys_in and phys_out, sharing itag s{i:02d} with opposite directions) are traced using Nicole's trace function, yielding a 2-leg bond tensor. Adjacent bond tensors are chained with einsum.

Returns:

Type Description
float

_scale × Tr[internal_mpo].

Notes

Representation. A NormalMPO stores the physical operator as _scale × mpo, where after compact() or from_mpo() the internal MPO satisfies norm() == 1. Keeping the scale separate prevents numerical over/underflow when iterating a Taylor series whose terms span many orders of magnitude.

Arithmetic. The operators @, +, *, and * (right) build new raw tensors and update _scale analytically without performing any canonicalization. Call compact() explicitly afterward to restore the unit-norm invariant and truncate bond dimension.

Dtype preservation. All arithmetic keeps real-valued (float64) tensors real. In __add__, the per-site scale factor is |α|^{1/L}, with the sign of the relative weight α absorbed into the first site, avoiding complex roots when α < 0.

See Also

  • MPO — base class.
  • thermal_mpo — constructs exp(-βH) as a NormalMPO.
  • observe — accepts a NormalMPO as state; computes Tr[ρ O] / Tr[ρ].