Skip to content

qr

QR decomposition returning orthogonal and upper triangular tensors.

qr

qr(T: Tensor, axis: int | str) -> Tuple[Tensor, Tensor]

Perform a symmetry-preserving QR decomposition separating one axis from all others.

Parameters:

Name Type Description Default
T Tensor

Tensor to be decomposed.

required
axis int | str

Axis to separate from all others. Can be an integer axis or itag. This axis forms the left partition (Q), all others form the right partition (R).

required

Returns:

Type Description
tuple[Tensor, Tensor]

Pair (Q, R) where:

  • Q has indices (left_index, bond_index) and is orthogonal
  • R has indices (bond_index.flip(), *right_indices) and is upper triangular

Raises:

Type Description
ValueError

If axis specification is invalid or ambiguous.

Notes

QR decomposition factors a tensor into an orthogonal matrix Q and an upper triangular matrix R such that T = Q @ R. Unlike SVD, no truncation is applied.

The decomposition is performed block-wise, preserving symmetry structure. For each charge sector, blocks with the same left charge are concatenated horizontally, QR decomposed together, and then R is split back into individual blocks.

Examples:

>>> # Basic QR decomposition
>>> Q, R = qr(T, axis=0)
>>> 
>>> # Using itag
>>> Q, R = qr(T, axis="physical")

Description

Performs block-wise QR decomposition, factorizing a tensor into:

  • Q: Orthogonal tensor (Q†Q = I)
  • R: Upper triangular tensor

Such that T = Q @ R. Unlike SVD, no truncation is applied.

The decomposition is performed block-wise, preserving symmetry structure. For each charge sector, blocks with the same left charge are concatenated horizontally, QR decomposed together, and then R is split back into individual blocks.

Parameters

T

Tensor to be decomposed.

axis

Axis to separate from all others. Can be:

  • Integer position (e.g., 0)
  • String itag (e.g., "physical")

This axis forms the left partition (Q), all others form the right partition (R).

Returns

tuple[Tensor, Tensor]: Pair (Q, R) where:

  • Q has indices (left_index, bond_index) and is orthogonal
  • R has indices (bond_index.flip(), *right_indices) and is upper triangular

Import

from nicole.decomp import qr

(Not exported in public API - use decomp(..., mode="QR") for most cases)

Usage Examples

from nicole.decomp import qr

# Basic QR decomposition
Q, R = qr(T, axis=0)

# Using itag
Q, R = qr(T, axis="physical")

# Verify orthogonality: Q†Q = I
from nicole import contract
QdagQ = contract(Q.conj(), Q)

See Also

Notes

  • Use decomp(..., mode="QR") for most cases with additional options (flow, itag customization)
  • Use qr() directly when you need simple, low-level QR decomposition
  • No truncation is applied in QR decomposition
  • QR is useful for obtaining canonical forms without compression