Tensor network algorithms (C code)

Virtual bonds

Auxiliary data structures and functions concerning virtual bonds.

Enums

enum singular_value_distr

Singular value distribution mode.

Values:

enumerator SVD_DISTR_LEFT
enumerator SVD_DISTR_RIGHT

Functions

int split_block_sparse_matrix_svd(const struct block_sparse_tensor *a, const double tol, const bool relative_thresh, const ct_long max_vdim, const bool renormalize, const enum singular_value_distr svd_distr, struct block_sparse_tensor *a0, struct block_sparse_tensor *a1, struct trunc_info *info)

Split a block-sparse matrix by singular value decomposition, and truncate small singular values based on the specified tolerance and maximum bond dimension.

int split_block_sparse_matrix_svd_isometry(const struct block_sparse_tensor *a, const double tol, const bool relative_thresh, const ct_long max_vdim, struct block_sparse_tensor *u, struct trunc_info *info)

Compute the left isometry after splitting a block-sparse matrix by singular value decomposition and truncating small singular values based on the specified tolerance and maximum bond dimension.

Chain topology

Higher-level tensor network operations on a chain topology.

Functions

void create_dummy_operator_block_right(const struct block_sparse_tensor *a, const struct block_sparse_tensor *b, const struct block_sparse_tensor *w, struct block_sparse_tensor *r)

Create a dummy right operator block.

void create_dummy_operator_block_left(const struct block_sparse_tensor *a, const struct block_sparse_tensor *b, const struct block_sparse_tensor *w, struct block_sparse_tensor *l)

Create a dummy left operator block.

void contraction_operator_step_right(const struct block_sparse_tensor *a, const struct block_sparse_tensor *b, const struct block_sparse_tensor *w, const struct block_sparse_tensor *r, struct block_sparse_tensor *r_next)

Contraction step from right to left, with a matrix product operator sandwiched in between.

To-be contracted tensor network:

   ╭───────╮         ╭─────────╮
   │       │         │         │
─>─0   b*  2─>─   ─>─2         │
   │       │         │         │
   ╰───1───╯         │         │
       │             │         │
       ^             │         │
       │             │         │
   ╭───1───╮         │         │
   │       │         │         │
─<─0   w   3─<─   ─<─1    r    3─<─
   │       │         │         │
   ╰───2───╯         │         │
       │             │         │
       ^             │         │
       │             │         │
   ╭───1───╮         │         │
   │       │         │         │
─<─0   a   2─<─   ─<─0         │
   │       │         │         │
   ╰───────╯         ╰─────────╯

void contraction_operator_step_left(const struct block_sparse_tensor *a, const struct block_sparse_tensor *b, const struct block_sparse_tensor *w, const struct block_sparse_tensor *l, struct block_sparse_tensor *l_next)

Contraction step from left to right, with a matrix product operator sandwiched in between.

To-be contracted tensor network:

   ╭─────────╮         ╭───────╮
   │         │         │       │
   │         3─>─   ─>─0   b*  2─>─
   │         │         │       │
   │         │         ╰───1───╯
   │         │             │
   │         │             ^
   │         │             │
   │         │         ╭───1───╮
   │         │         │       │
─<─0    l    2─<─   ─<─0   w   3─<─
   │         │         │       │
   │         │         ╰───2───╯
   │         │             │
   │         │             ^
   │         │             │
   │         │         ╭───1───╮
   │         │         │       │
   │         1─<─   ─<─0   a   2─<─
   │         │         │       │
   ╰─────────╯         ╰───────╯

void compute_right_operator_blocks(const struct mps *psi, const struct mps *chi, const struct mpo *op, struct block_sparse_tensor *r_list)

Compute all partial contractions from the right. ‘r_list’ must point to an array of (uninitialized) tensors of length ‘nsites’ at input.

void mpo_inner_product(const struct mps *chi, const struct mpo *op, const struct mps *psi, void *ret)

Compute the inner product between an MPO and two MPS, <chi | op | psi>.

void apply_local_hamiltonian(const struct block_sparse_tensor *a, const struct block_sparse_tensor *w, const struct block_sparse_tensor *l, const struct block_sparse_tensor *r, struct block_sparse_tensor *b)

Apply a local Hamiltonian operator.

To-be contracted tensor network:

         .....................................
        '                                     '
   ╭────:────╮                           ╭────:────╮
   │    :    │                           │    :    │
   │    :    3─>─  0               2  ─>─2    :    │
   │    :    │                           │    :    │
   │    :    │                           │    :    │
   │    :    │             1             │    :    │
   │    :    │             ^             │    :    │
   │    :    │             │             │    :    │
   │    '....│.........╭───1───╮.........│....'    │
   │         │         │       │         │         │
─<─0    l    2─<─   ─<─0   w   3─<─   ─<─1    r    3─<─
   │         │         │       │         │         │
   │         │         ╰───2───╯         │         │
   │         │             │             │         │
   │         │             ^             │         │
   │         │             │             │         │
   │         │         ╭───1───╮         │         │
   │         │         │       │         │         │
   │         1─<─   ─<─0   a   2─<─   ─<─0         │
   │         │         │       │         │         │
   ╰─────────╯         ╰───────╯         ╰─────────╯
The dotted outline marks the output tensor. The outer virtual bonds are contracted as well.

void compute_local_hamiltonian_environment(const struct block_sparse_tensor *a, const struct block_sparse_tensor *b, const struct block_sparse_tensor *l, const struct block_sparse_tensor *r, struct block_sparse_tensor *dw)

Evaluate the network environment of a local Hamiltonian operator.

To-be contracted tensor network:

   ╭─────────╮         ╭───────╮         ╭─────────╮
   │         │         │       │         │         │
   │         3─>─   ─>─0   b*  2─>─   ─>─2         │
   │         │         │       │         │         │
   │     ....│.........╰───1───╯.........│....     │
   │    '    │             │             │    '    │
   │    :    │             ^             │    :    │
   │    :    │             1             │    :    │
   │    :    │                           │    :    │
   │    :    │                           │    :    │
─<─0    l    2─<─  0               3  ─<─1    r    3─<─
   │    :    │                           │    :    │
   │    :    │                           │    :    │
   │    :    │             2             │    :    │
   │    :    │             ^             │    :    │
   │    :    │             │             │    :    │
   │    '....│.........╭───1───╮.........│....'    │
   │         │         │       │         │         │
   │         1─<─   ─<─0   a   2─<─   ─<─0         │
   │         │         │       │         │         │
   ╰─────────╯         ╰───────╯         ╰─────────╯
The dotted outline marks the output tensor. The outer virtual bonds are contracted as well.

void apply_mpo_direct(const struct mpo *op, const struct mps *psi, struct mps *op_psi)

Apply an operator represented as MPO to a state in MPS form, based on a direct contraction of physical axes and grouping of virtual bonds.

int apply_mpo_cbc(const struct mpo *op, const struct mps *psi, const double tol, const ct_long max_vdim, struct mps *op_psi)

Apply an operator represented as MPO to a state in MPS form using the Cholesky-based compression (CBC) method described in “Efficient application of tensor network operators to tensor network states”.

Reference: Richard M. Milbradt, Shuo Sun, Christian B. Mendl, Johnnie Gray, Garnet K.-L. Chan Efficient application of tensor network operators to tensor network states arXiv:2601.19650

Tree topology

Higher-level tensor network operations on a tree topology.

Functions

void ttno_inner_product(const struct ttns *chi, const struct ttno *op, const struct ttns *psi, void *ret)

Compute the inner product between a TTNO and two TTNS, <chi | op | psi>.

void ttno_subtrees_inner_products(const struct ttns *chi, const struct ttno *op, const struct ttns *psi, const int i_root, struct block_sparse_tensor *avg_bonds)

Compute the inner products on all subtrees oriented towards ‘i_root’ between a TTNO and two TTNS, <chi | op | psi>.

At input, ‘avg_bonds’ must be an array of length “number of sites”. After the function call, avg_bonds[i] for i != i_root will be a degree 3 tensor with axes corresponding to the virtual bonds towards ‘i_root’ of the operator sandwich ordered (bond of psi, bond of op, bond of chi), and avg_bonds[i_root] a degree 0 tensor containing the overall inner product value.

void local_ttno_inner_product(const struct block_sparse_tensor *chi, const struct block_sparse_tensor *op, const struct block_sparse_tensor *psi, const struct abstract_graph *topology, const int i_site, const int i_parent, struct block_sparse_tensor *avg_bonds)

Compute the local inner product <chi | op | psi> at ‘i_site’ given the averages of the connected child nodes. The virtual bonds towards the parent node (if any) remain open. The output is stored in avg_bonds[i_site].

void apply_local_ttno_tensor(const struct block_sparse_tensor *op, const struct block_sparse_tensor *psi, const struct abstract_graph *topology, const int i_site, const struct block_sparse_tensor *envs, struct block_sparse_tensor *ret)

Apply a local operator op |psi> at ‘i_site’ and contract with the environment tensors on the connected bonds towards ‘i_site’. The environment tensor on the i-th virtual bond is ‘envs[i]’.

DMRG algorithm

DMRG algorithm.

Functions

void dmrg_singlesite_default_options(struct dmrg_singlesite_options *options)

Set default single-site DMRG options.

void delete_dmrg_singlesite_info(struct dmrg_singlesite_info *info)

Delete the single-site DMRG information (free memory).

int dmrg_singlesite(const struct mpo *hamiltonian, const struct dmrg_singlesite_options *options, struct mps *psi, struct dmrg_singlesite_info *info)

Run the single-site DMRG algorithm: Approximate the ground state as MPS via left and right sweeps and local single-site optimizations. The input ‘psi’ is used as the starting state and is updated in-place during the optimization. Its virtual bond dimensions cannot increase.

void dmrg_twosite_default_options(struct dmrg_twosite_options *options)

Set default two-site DMRG options.

void delete_dmrg_twosite_info(struct dmrg_twosite_info *info)

Delete the two-site DMRG information (free memory).

int dmrg_twosite(const struct mpo *hamiltonian, const struct dmrg_twosite_options *options, struct mps *psi, struct dmrg_twosite_info *info)

Run the two-site DMRG algorithm: Approximate the ground state as MPS via left and right sweeps and local two-site optimizations. The input ‘psi’ is used as the starting state and is updated in-place during the optimization.

struct dmrg_singlesite_options
#include <dmrg.h>

Options for running the single-site DMRG algorithm.

Public Members

double delta_en_tol

stopping criterion based on relative energy difference between sweeps: abs(delta_en / max(en, 1)) < delta_en_tol

int max_num_sweeps

maximum number of sweeps

int maxiter_lanczos

maximum number of Lanczos iterations

struct dmrg_singlesite_info
#include <dmrg.h>

Statistical information obtained while running the single-site DMRG algorithm.

Public Members

double *en_sweeps

energy after each sweep

int num_sweeps

number of sweeps

struct dmrg_twosite_options
#include <dmrg.h>

Options for running the two-site DMRG algorithm.

Public Members

double delta_en_tol

stopping criterion based on relative energy difference between sweeps: abs(delta_en / max(en, 1)) < delta_en_tol

int max_num_sweeps

maximum number of sweeps

int maxiter_lanczos

maximum number of Lanczos iterations

double tol_split

tolerance for splitting a temporarily merged MPS tensor pair

ct_long max_vdim

maximum virtual bond dimension

struct dmrg_twosite_info
#include <dmrg.h>

Statistical information obtained while running the two-site DMRG algorithm.

Public Members

double *entropy

von Neumann entropy of each (inner) virtual bond, at the last sweep

double *en_sweeps

energy after each sweep

int num_sweeps

number of sweeps

Gradients

Gradient computation for operators.

Functions

void operator_average_coefficient_gradient(const struct mpo_assembly *assembly, const struct mps *psi, const struct mps *chi, void *avr, void *dcoeff)

Compute the value and gradient of <chi | op | psi> with respect to the internal MPO coefficients.

BUG integration

Basis-Update and Galerkin (BUG) integration for tree tensor networks.

Functions

void bug_flow_update_basis(const struct ttno *hamiltonian, const int i_site, const int i_parent, const struct block_sparse_tensor *avg_bonds, const struct block_sparse_tensor *env_parent, const struct block_sparse_tensor *s0, const void *prefactor, const double dt, struct ttns *state, struct block_sparse_tensor *avg_bonds_augmented, struct block_sparse_tensor *augment_maps)

Update and augment the basis matrix of a subtree for the Schrödinger differential equation with Hamiltonian given as TTNO. ‘state’ is updated in-place; ‘avg_bonds’ contains the operator averages of the initial state and ‘avg_bonds_augmented’ is filled with the averages after the basis update.

TTNO-adapted Algorithm 5 in “Rank-adaptive time integration of tree tensor networks”.

Augmentation by identity blocks is necessary to activate all possible quantum number sectors.

void bug_flow_update_connecting_tensor(const struct block_sparse_tensor *op, const struct block_sparse_tensor *c0, const struct abstract_graph *topology, const int i_site, const int i_parent, const struct block_sparse_tensor *avg_bonds_augmented, const struct block_sparse_tensor *env_parent, const void *prefactor, const double dt, struct block_sparse_tensor *c1)

Update the (already augmented) connecting tensor of a tree node for a Schrödinger differential equation with Hamiltonian given as TTNO.

TTNO-adapted Algorithm 6 in “Rank-adaptive time integration of tree tensor networks”.

int bug_tree_time_step(const struct ttno *hamiltonian, const int i_root, const void *prefactor, const double dt, const double tol_compress, const ct_long max_vdim, struct ttns *state)

Perform a rank-augmenting TTN integration step for a Schrödinger differential equation with Hamiltonian given as TTNO. The ‘state’ is updated in-place.

Tensor hypercontraction

Tensor hypercontraction (THC) representation of a molecular Hamiltonian and corresponding utility functions (see arXiv:2409.12708).

Functions

int construct_thc_spin_molecular_hamiltonian(const struct dense_tensor *tkin, const struct dense_tensor *thc_kernel, const struct dense_tensor *thc_transform, struct thc_spin_molecular_hamiltonian *hamiltonian)

Construct the tensor hypercontraction representation of a molecular Hamiltonian.

void delete_thc_spin_molecular_hamiltonian(struct thc_spin_molecular_hamiltonian *hamiltonian)

Delete the tensor hypercontraction representation of a molecular Hamiltonian (free memory).

int apply_thc_spin_molecular_hamiltonian(const struct thc_spin_molecular_hamiltonian *hamiltonian, const struct mps *psi, const double tol, const ct_long max_vdim, struct mps *h_psi)

Apply a molecular Hamiltonian in tensor hypercontraction representation to a state in MPS form.

int thc_spin_molecular_hamiltonian_to_matrix(const struct thc_spin_molecular_hamiltonian *hamiltonian, struct block_sparse_tensor *mat)

Generate the matrix representation of the tensor hypercontraction molecular Hamiltonian on the full Hilbert space.

struct thc_spin_molecular_hamiltonian
#include <thc.h>

Tensor hypercontraction (THC) representation of a molecular Hamiltonian, assuming a spin orbital basis.

Public Members

struct dense_tensor tkin

coefficients of the kinetic (one-body) term, must be symmetric

struct dense_tensor thc_kernel

kernel matrix of the THC representation, must be symmetric

struct dense_tensor thc_transform

transformation matrix (from kernel to orbital space) of the THC representation

struct dense_tensor en_kin

eigenvalues of the kinetic coefficient matrix (real-valued)

struct dense_tensor u_kin

eigenvectors of the kinetic coefficient matrix

struct mpo *mpo_kin

elementary quadratic MPOs for the kinetic term

struct mpo *mpo_thc

elementary quadratic MPOs for the interaction term in THC representation