mdopt.utils package

Submodules

mdopt.utils.utils module

This module contains miscellaneous utilities.

mdopt.utils.utils.create_random_mpo(num_sites: int, bond_dimensions: List[int], phys_dim: int, which: str = 'uniform') List[ndarray]

Creates a random complex-valued Matrix Product Operator.

Parameters:
  • num_sites (int) – The number of sites for the MPO. This will be equal to the number of tensors.

  • bond_dimensions (List[int]) – A list of bond dimensions.

  • phys_dim (int) – Physical dimension of the tensors.

  • which (str) – Specifies the distribution from which the matrix elements are being taken. Options: “uniform”, “normal”, “randint”.

Returns:

mpo – The resulting MPO.

Return type:

List[np.ndarray]

Notes

The bond_dimensions argument should be given as a list of right virtual dimensions without the last trivial virtual dimension. Thus, the length of the list is num_sites - 1.

The distributions available: uniform(0,1), normal, random integer {0,1}.

Each tensor in the MPO list has legs (vL, vR, pU, pD), where v stands for “virtual”, p – for “physical”, and L, R, U, D – for “left”, “right”, “up”, “down” accordingly.

mdopt.utils.utils.kron_tensors(tensor_1: ndarray, tensor_2: ndarray, conjugate_second: bool = False, merge_physicals: bool = True) ndarray

Computes a kronecker product of 2 MPS tensors.

Parameters:
  • tensor_1 (np.ndarray) – The first tensor of the product.

  • tensor_2 (np.ndarray) – The second tensor of the product.

  • conjugate_second (bool) – Whether to complex-conjugate the second tensor.

  • merge_physicals (bool) – Whether to merge physical indices.

Returns:

The resulting kronecker product.

Return type:

product

Raises:
  • ValueError – If the first MPS tensor is not three-dimensional.

  • ValueError – If the second MPS tensor is not three-dimensional.

Notes

This function acts according to the following diagram:

   tensor_2
      i
      |                      i
j ---( )--- k                |
                -->    jl---( )---kn
l ---( )--- n                |
      |                      m
      m
   tensor_1

The legs of the resulting tensor are indexed as (jl, m, i, kn). Indices i and m can be merged if merge_physicals=True.

mdopt.utils.utils.mpo_from_matrix(matrix: ndarray, num_sites: int, interlaced: bool = True, orthogonalise: bool = False, phys_dim: int = 2, chi_max: int = 10000) List[ndarray]

Creates an MPO from a matrix.

Parameters:
  • matrix (np.ndarray) – The matrix to convert to an MPO. Can be given with either physical legs grouped together or merged (see notes).

  • num_sites (int) – The number of sites in the MPO.

  • interlaced (bool) – Whether the matrix’ legs are interlaced or not.

  • orthogonalise (bool) – Whether to make the MPO tensors isometric with respect to 2 physical legs and one virtual.

  • phys_dim (int) – Local dimension of the physical legs.

  • chi_max (int) – Maximum bond dimension allowed in the MPO.

Returns:

mpo – The resulting Matrix Product Operator.

Return type:

List[np.ndarray]

Raises:

ValueError – If the matrix’ shape does not correspond to phys_dim and num_sites.

Notes

If interlaced==True, the matrix’ legs are considered to go as (p0U, p0D, p1U, p1D, ...), which means physical legs sticking up and down with site number. If interlaced==False, the matrix’ legs are considered to go as (p0D, p1D, ..., p0U, p1U, ...), which means listing first all physical legs sticking down with the site number, and then all physical legs sticking up. This is done to adjust the matrix to the @ numpy-native matrix-vector multiplication.

If orthogonalise==True, the singular values at each bond are being carried further to the orthogonality centre thus making all the tensors except the latter isometric. The orthogonality centre is then isometric up to a multiplier which would be its norm. If orthogonalise==False, the singular values at each bond are being splitted by taking the square root and distribbuted to both MPO tensors at each bond thus leaving all the tensors nonisometric. There is no orthogonality centre in this case.

An example of a matrix with ungrouped legs on three sites:

  p0U p1U p2U
 __|___|___|__
|            |
|____________|
   |   |   |
  p0D p1D p2D

Each tensor in the mpo list has legs (vL, vR, pU, pD), where v stands for “virtual”, p – for “physical”, and L, R, U, D – for “left”, “right”, “up”, “down” accordingly.

mdopt.utils.utils.mpo_to_matrix(mpo: List[ndarray], interlace: bool = False, group: bool = False) ndarray

Creates a matrix from an MPO.

Parameters:
  • mpo (List[np.ndarray]) – The MPO to convert to a matrix.

  • interlace (bool) – Whether to interlace the matrix’ legs or not.

  • group (bool) – Whether to group the matrix’ legs or not, see the notes. Grouping means merging all the up legs into one leg and the same for the down legs.

Returns:

matrix – The resulting matrix.

Return type:

np.ndarray

Raises:

ValueError – If any of the MPO tensors is not four-dimensional.

Notes

If interlace==True, the matrix’ legs will go as (p0U, p0D, p1U, p1D, ...), which means physical legs sticking up and down with the site number. If interlace==False, the matrix’ legs will go as (p0D, p1D, ..., p0U, p1U, ...), which means listing first all physical legs sticking down with the site number, and then all physical legs sticking up. This is done to adjust the matrix to the @ numpy-native matrix-vector multiplication. Note, grouping (if wanted) is being done after the interlacing.

An example of a matrix with ungrouped legs on three sites:

  p0U p1U p2U
 __|___|___|__
|            |
|____________|
   |   |   |
  p0D p1D p2D

Each tensor in the MPO list has legs (vL, vR, pU, pD), where v stands for “virtual”, p – for “physical”, and L, R, U, D – for “left”, “right”, “up”, “down” accordingly. Warning: will cause memory overflow for number of sites > ~20.

mdopt.utils.utils.split_two_site_tensor(tensor: ndarray, chi_max: int = 10000, cut: float32 = 1e-12, renormalise: bool = False, strategy: str = 'svd') Tuple

Split a two-site MPS tensor according to the following diagram (in case of the SVD strategy, similarly but without the singular vals for the others):

                                      m         n
i ---(tensor)--- l     ->    i ---(A)---diag(S)---(B)--- l
      |   |                        |               |
      j   k                        j               k
Parameters:
  • tensor (np.ndarray) – Two-site tensor (i, j, k, l).

  • chi_max (int) – Maximum number of singular values to keep.

  • cut (np.float32) – Discard any singular values smaller than eps.

  • renormalise (bool) – Whether to renormalise the singular value spectrum after the cut.

  • strategy (str) – Which strategy to use for the splitting. Available options: svd, qr, rq.

Returns:

  • a_l (np.ndarray) – Left isometry (i, j, m).

  • singular_values (np.ndarray) – List of singular values.

  • b_r (np.ndarray) – Right isometry (n, k, l).

Raises:

ValueError – If the tensor is not four-dimensional.

mdopt.utils.utils.svd(mat: ndarray, cut: float32 = 1e-12, chi_max: int = 10000, renormalise: bool = False) Tuple[ndarray, list, ndarray]

Performs Singular Value Decomposition with different features.

Parameters:
  • mat (np.ndarray) – Matrix provided as a tensor with 2 dimensions.

  • cut (np.float32) – Singular values smaller than this will be discarded.

  • chi_max (int) – Maximum number of singular values to keep.

  • renormalise (bool) – Whether to renormalise the singular value spectrum after the cut.

Returns:

  • u_l (np.ndarray) – Unitary matrix having left singular vectors as columns.

  • singular_values (np.ndarray) – The singular values, sorted in non-increasing order.

  • v_r (np.ndarray) – Unitary matrix having right singular vectors as rows.

Raises:

ValueError – If the np.ndarray provided is not two-dimensional.

Module contents