Models#

MPS#

MPS#

class tensorkrowch.models.MPS(n_features=None, phys_dim=None, bond_dim=None, boundary='obc', tensors=None, in_features=None, out_features=None, n_batches=1, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Class for Matrix Product States. This is the base class from which UMPS, MPSLayer and UMPSLayer inherit.

Matrix Product States are formed by:

  • mats_env: Environment of matrix nodes with axes ("left", "input", "right").

  • left_node, right_node: Vector nodes with axes ("right",) and ("left",), respectively. These are used to close the boundary in the case boudary is "obc". Otherwise, both are None.

The base MPS class enables setting various nodes as either input or output nodes. This feature proves useful when computing marginal or conditional distributions. The assignment of roles can be altered dynamically, allowing input nodes to transition to output nodes, and vice versa.

Input nodes will be connected to data nodes at their "input" edges, and contracted against them when calling contract(). Output nodes, on the other hand, will remain disconnected. If marginalize_output = True in contract(), the open indices of the output nodes can be marginalized so that the output is a single scalar (or a vector with only batch dimensions). If marginalize_output = False the result will be a tensor with as many dimensions as output nodes where in the MPS, plus the corresponding batch dimensions.

If all input nodes have the same physical dimensions, the input data tensor can be passed as a single tensor. Otherwise, it would have to be passed as a list of tensors with different sizes.

Parameters
  • n_features (int, optional) – Number of nodes that will be in mats_env. That is, number of nodes without taking into account left_node and right_node.

  • phys_dim (int, list[int] or tuple[int], optional) – Physical dimension(s). If given as a sequence, its length should be equal to n_features.

  • bond_dim (int, list[int] or tuple[int], optional) – Bond dimension(s). If given as a sequence, its length should be equal to n_features (if boundary = "pbc") or n_features - 1 (if boundary = "obc"). The i-th bond dimension is always the dimension of the right edge of the i-th node.

  • boundary ({"obc", "pbc"}) – String indicating whether periodic or open boundary conditions should be used.

  • tensors (list[torch.Tensor] or tuple[torch.Tensor], optional) – Instead of providing n_features, phys_dim, bond_dim and boundary, a list of MPS tensors can be provided. In such case, all mentioned attributes will be inferred from the given tensors. All tensors should be rank-3 tensors, with shape (bond_dim, phys_dim, bond_dim). If the first and last elements are rank-2 tensors, with shapes (phys_dim, bond_dim), (bond_dim, phys_dim), respectively, the inferred boundary conditions will be “obc”. Also, if tensors contains a single element, it can be rank-1 (“obc”) or rank-3 (“pbc”).

  • in_features (list[int] or tuple[int], optional) – List of indices indicating the positions of the MPS nodes that will be considered as input nodes. These nodes will have a neighbouring data node connected to its "input" edge when the set_data_nodes() method is called. in_features is the complementary set of out_features, so it is only required to specify one of them.

  • out_features (list[int] or tuple[int], optional) – List of indices indicating the positions of the MPS nodes that will be considered as output nodes. These nodes will be left with their "input" edges open when contrating the network. If marginalize_output is set to True in contract(), the network will be connected to itself at these nodes, and contracted. out_features is the complementary set of in_features, so it is only required to specify one of them.

  • n_batches (int) – Number of batch edges of input data nodes. Usually n_batches = 1 (where the batch edge is used for the data batched) but it could also be n_batches = 2 (one edge for data batched, other edge for image patches in convolutional layers).

  • init_method ({"zeros", "ones", "copy", "rand", "randn", "randn_eye", "unit"}, optional) – Initialization method. Check initialize() for a more detailed explanation of the different initialization methods.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

Examples

MPS with the same physical dimensions:

>>> mps = tk.models.MPS(n_features=5,
...                     phys_dim=2,
...                     bond_dim=5)
>>> data = torch.ones(20, 5, 2) # batch_size x n_features x feature_size
>>> result = mps(data)
>>> result.shape
torch.Size([20])

MPS with different physical dimensions:

>>> mps = tk.models.MPS(n_features=5,
...                     phys_dim=list(range(2, 7)),
...                     bond_dim=5)
>>> data = [torch.ones(20, i)
...         for i in range(2, 7)] # n_features * [batch_size x feature_size]
>>> result = mps(data)
>>> result.shape
torch.Size([20])

MPS can also be initialized from a list of tensors:

>>> tensors = [torch.randn(5, 2, 5) for _ in range(10)]
>>> mps = tk.models.MPS(tensors=tensors)

If in_features/out_features are specified, data will only be connected to the input nodes, leaving output nodes open:

>>> mps = tk.models.MPS(tensors=tensors,
...                     out_features=[0, 3, 9])
>>> data = torch.ones(20, 7, 2) # batch_size x n_features x feature_size
>>> result = mps(data)
>>> result.shape
torch.Size([20, 2, 2, 2])
>>> mps.reset()
>>> result = mps(data, marginalize_output=True)
>>> result.shape
torch.Size([20, 20])
property n_features#

Returns number of nodes.

property phys_dim#

Returns physical dimensions.

property bond_dim#

Returns bond dimensions.

property boundary#

Returns boundary condition (“obc” or “pbc”).

property n_batches#

Returns number of batch edges of the data nodes. To change this attribute, first call unset_data_nodes() if there are already data nodes in the network.

property in_features#

Returns list of positions of the input nodes. To change this attribute, first call unset_data_nodes() if there are already data nodes in the network. When changing it, out_features will change accordingly to be the complementary.

property out_features#

Returns list of positions of the output nodes. To change this attribute, first call unset_data_nodes() if there are already data nodes in the network. When changing it, in_features will change accordingly to be the complementary.

property in_regions#

Returns a list of lists of consecutive input positions.

property out_regions#

Returns a list of lists of consecutive output positions.

property left_node#

Returns the left_node.

property right_node#

Returns the right_node.

property mats_env#

Returns the list of nodes in mats_env.

property in_env#

Returns the list of input nodes.

property out_env#

Returns the list of output nodes.

property tensors#

Returns the list of MPS tensors.

initialize(tensors=None, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Initializes all the nodes of the MPS. It can be called when instantiating the model, or to override the existing nodes’ tensors.

There are different methods to initialize the nodes:

  • {"zeros", "ones", "copy", "rand", "randn"}: Each node is initialized calling set_tensor() with the given method, device, dtype and kwargs.

  • "randn_eye": Nodes are initialized as in this paper, adding identities at the top of random gaussian tensors. In this case, std should be specified with a low value, e.g., std = 1e-9.

  • "unit": Nodes are initialized as stacks of random unitaries. This, combined (at least) with an embedding of the inputs as elements of the computational basis (discretize() combined with basis())

  • "canonical"`: MPS is initialized in canonical form with a squared norm close to the product of all the physical dimensions (if bond dimensions are bigger than the powers of the physical dimensions, the norm could vary). Th orthogonality center is at the rightmost node.

Parameters
  • tensors (list[torch.Tensor] or tuple[torch.Tensor], optional) – Sequence of tensors to set in each of the MPS nodes. If boundary is "obc", all tensors should be rank-3, except the first and last ones, which can be rank-2, or rank-1 (if the first and last are the same). If boundary is "pbc", all tensors should be rank-3.

  • init_method ({"zeros", "ones", "copy", "rand", "randn", "randn_eye", "unit", "canonical"}, optional) – Initialization method.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

set_data_nodes()[source]#

Creates data nodes and connects each of them to the "input" edge of each input node.

copy(share_tensors=False)[source]#

Creates a copy of the MPS.

Parameters

share_tensor (bool, optional) – Boolean indicating whether tensors in the copied MPS should be set as the tensors in the current MPS (True), or cloned (False). In the former case, tensors in both MPS’s will be the same, which might be useful if one needs more than one copy of an MPS, but wants to compute all the gradients with respect to the same, unique, tensors.

Return type

MPS

parameterize(set_param=True, override=False)[source]#

Parameterizes all nodes of the MPS. If there are resultant nodes in the MPS, it will be first reset().

Parameters
  • set_param (bool) – Boolean indicating whether the tensor network has to be parameterized (True) or de-parameterized (False).

  • override (bool) – Boolean indicating whether the tensor network should be parameterized in-place (True) or copied and then parameterized (False).

update_bond_dim()[source]#

Updates the bond_dim attribute of the MPS, in case it is outdated.

If bond dimensions are changed, usually due to decompositions like svd(), update_bond_dim should be called. This might modify some elements of the model, so it is recommended to do this before saving the state_dict of the model. Besides, if one wants to continue training, the parameters of the model that are passed to the optimizer should be updated also. Otherwise, the optimizer could be tracking outdated parameters that are not members of the model any more.

contract(inline_input=False, inline_mats=False, renormalize=False, marginalize_output=False, embedding_matrices=None, mpo=None)[source]#

Contracts the whole MPS.

If the MPS has input nodes, these are contracted against input data nodes.

If the MPS has output nodes, these can be left with their "input" edges open, or can be marginalized, contracting the remaining output nodes with themselves, if the argument "marginalize_output" is set to True.

In the latter case, one can add additional nodes in between the MPS-MPS contraction:

  • embedding_matrices: A list of matrices with appropiate physical dimensions can be passed, one for each output node. These matrices will connect the two "input" edges of the corresponding nodes.

  • mpo: If an MPO is passed, when calling mps(marginalize_output=True, mpo=mpo), this will perform the MPS-MPO-MPS contraction at the output nodes of the MPS. Therefore, the MPO should have as many nodes as output nodes are in the MPS.

    After contraction, the MPS will still be connected to the MPO nodes until these are manually disconnected.

    The provided MPO can also be already connected to the MPS before contraction. In this case, it is assumed that the output nodes of the MPS are connected to the "output" edges of the MPO nodes, and that the MPO nodes have been moved to the MPS, so that all nodes belong to the MPS network. In this case, each MPO node will connect the two "input" edges of the corresponding MPS nodes.

    If the MPO nodes are not trainable, they can be de-parameterized by doing mpo = mpo.parameterize(set_param=False, override=True). This should be done before the contraction, or before connecting the MPO nodes to the MPS, since the de-parameterized nodes are not the same nodes as the original ParamNodes of the MPO.

When marginalize_output = True, the contracted input nodes are duplicated using different batch dimensions. That is, if the MPS is contracted with input data with batch_size = 100, and some other (output) nodes are marginalized, the result will be a tensor with shape (100, 100) rather than just (100,).

Parameters
  • inline_input (bool) – Boolean indicating whether input data nodes should be contracted with the MPS input nodes inline (one contraction at a time) or in a single stacked contraction.

  • inline_mats (bool) – Boolean indicating whether the sequence of matrices (resultant after contracting the input data nodes) should be contracted inline or as a sequence of pairwise stacked contrations.

  • renormalize (bool) – Indicates whether nodes should be renormalized after contraction. If not, it may happen that the norm explodes or vanishes, as it is being accumulated from all nodes. Renormalization aims to avoid this undesired behavior by extracting the norm of each node on a logarithmic scale. The renormalization only occurs when multiplying sequences of matrices, once the input contractions have been already performed, including contracting against embedding matrices or MPOs when marginalize_output = True.

  • marginalize_output (bool) – Boolean indicating whether output nodes should be marginalized. If True, after contracting all the input nodes with their neighbouring data nodes, this resultant network is contracted with itself connecting output nodes to itselves at "input" edges. If False, output nodes are left with their "input" edges disconnected.

  • embedding_matrices (torch.Tensor, list[torch.Tensor] or tuple[torch.Tensor], optional) – If marginalize_output = True, a matrix can be introduced between each output node and its copy, connecting the "input" edges. This can be useful when data vectors are not represented as qubits in the computational basis, but are transformed via some Embeddings function.

  • mpo (MPO, optional) – MPO that is to be contracted with the MPS at the output nodes, if marginalize_output = True. In this case, the "output" edges of the MPO nodes will be connected to the "input" edges of the MPS output nodes. If there are no input nodes, the MPS-MPO-MPS is performed by calling mps(marginalize_output=True, mpo=mpo), without passing extra data tensors.

Return type

Node

norm(log_scale=False)[source]#

Computes the norm of the MPS.

This method internally removes all data nodes in the MPS, if any, and contracts the nodes with themselves. Therefore, this may alter the usual behaviour of contract() if the MPS is not reset() afterwards. Also, if the MPS was contracted before with other arguments, it should be reset before calling norm to avoid undesired behaviour.

Since the norm is computed by contracting the MPS, it means one can take gradients of it with respect to the MPS tensors, if it is needed.

Parameters

log_scale (bool) – Boolean indicating whether the resulting norm should be given in logarithmoc scale. Useful for cases where the norm explodes or vanishes.

reduced_density(trace_sites=[], renormalize=True)[source]#

Returns de partial density matrix, tracing out the sites specified by trace_sites: \(\rho_A\).

This method internally sets out_features = trace_sites, and calls the forward() method with marginalize_output = True. Therefore, it may alter the behaviour of the MPS if it is not reset() afterwards. Also, if the MPS was contracted before with other arguments, it should be reset before calling reduced_density to avoid undesired behaviour.

Since the density matrix is computed by contracting the MPS, it means one can take gradients of it with respect to the MPS tensors, if it is needed.

This method may also alter the attribute n_batches of the MPS.

Parameters
  • trace_sites (list[int] or tuple[int]) – Sequence of nodes’ indices in the MPS. These indices specify the nodes that should be traced to compute the density matrix. If it is empty [], the total density matrix will be returned, though this may be costly if n_features is big.

  • renormalize (bool) – Indicates whether nodes should be renormalized after contraction. If not, it may happen that the norm explodes or vanishes, as it is being accumulated from all nodes. Renormalization aims to avoid this undesired behavior by extracting the norm of each node on a logarithmic scale. The renormalization only occurs when multiplying sequences of matrices, once the input contractions have been already performed.

Examples

>>> mps = tk.models.MPS(n_features=4,
...                     phys_dim=[2, 3, 4, 5],
...                     bond_dim=5)
>>> density = mps.reduced_density(trace_sites=[0, 2])
>>> density.shape
torch.Size([3, 5, 3, 5])
entropy(middle_site, renormalize=False)[source]#

Computes the reduced von Neumann Entropy between subsystems \(A\) and \(B\), \(S(\rho_A)\), where \(A\) goes from site 0 to middle_site, and \(B\) goes from middle_site + 1 to n_features - 1.

To compute the reduced entropy, the MPS is put into canonical form with orthogonality center at middle_site. Bond dimensions are not changed if possible. Only when the bond dimension is bigger than the physical dimension multiplied by the other bond dimension of the node, it will be cropped to that size.

If the MPS is not normalized, it may happen that the computation of the reduced entropy fails due to errors in the Singular Value Decompositions. To avoid this, it is recommended to set renormalize = True. In this case, the norm of each node after the SVD is extracted in logarithmic form, and accumulated. As a result, the function will return the tuple (entropy, log_norm), which is a sort of scaled reduced entropy. This is, indeed, the reduced entropy of a distribution, since the schmidt values are normalized to sum up to 1.

The actual reduced entropy, without rescaling, could be obtained as:

\[\exp(\texttt{log_norm})^2 \cdot S(\rho_A) - \exp(\texttt{log_norm})^2 \cdot 2 \cdot \texttt{log_norm}\]
Parameters
  • middle_site (int) – Position that separates regios \(A\) and \(B\). It should be between 0 and n_features - 2.

  • renormalize (bool) – Indicates whether nodes should be renormalized after SVD/QR decompositions. If not, it may happen that the norm explodes as it is being accumulated from all nodes. Renormalization aims to avoid this undesired behavior by extracting the norm of each node on a logarithmic scale after SVD/QR decompositions are computed. Finally, the normalization factor is evenly distributed among all nodes of the MPS.

Return type

float or tuple[float, float]

canonicalize(oc=None, mode='svd', rank=None, cum_percentage=None, cutoff=None, renormalize=False)[source]#

Turns MPS into canonical form via local SVD/QR decompositions.

To specify the new bond dimensions, the arguments rank, cum_percentage or cutoff can be specified. These will be used equally for all SVD computations.

If none of them are specified, the bond dimensions won’t be modified if possible. Only when the bond dimension is bigger than the physical dimension multiplied by the other bond dimension of the node, it will be cropped to that size.

If rank is not specified, the current bond dimensions will be used as the rank. That is, the current bond dimensions will be the upper bound for the possibly new bond dimensions given by the arguments cum_percentage and/or cutoff.

Parameters
  • oc (int) – Position of the orthogonality center. It should be between 0 and n_features - 1.

  • mode ({"svd", "svdr", "qr"}) – Indicates which decomposition should be used to split a node after contracting it. See more at svd_(), svdr_(), qr_(). If mode is “qr”, operation qr_() will be performed on nodes at the left of the output node, whilst operation rq_() will be used for nodes at the right.

  • rank (int, optional) – Number of singular values to keep.

  • cum_percentage (float, optional) –

    Proportion that should be satisfied between the sum of all singular values kept and the total sum of all singular values.

    \[\frac{\sum_{i \in \{kept\}}{s_i}}{\sum_{i \in \{all\}}{s_i}} \ge cum\_percentage\]

  • cutoff (float, optional) – Quantity that lower bounds singular values in order to be kept.

  • renormalize (bool) – Indicates whether nodes should be renormalized after SVD/QR decompositions. If not, it may happen that the norm explodes as it is being accumulated from all nodes. Renormalization aims to avoid this undesired behavior by extracting the norm of each node on a logarithmic scale after SVD/QR decompositions are computed. Finally, the normalization factor is evenly distributed among all nodes of the MPS.

Examples

>>> mps = tk.models.MPS(n_features=4,
...                     phys_dim=2,
...                     bond_dim=5)
>>> mps.canonicalize(rank=3)
>>> mps.bond_dim
[3, 3, 3]
canonicalize_univocal()[source]#

Turns MPS into the univocal canonical form defined here.

UMPS#

class tensorkrowch.models.UMPS(n_features, phys_dim=None, bond_dim=None, tensor=None, in_features=None, out_features=None, n_batches=1, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Class for Uniform (translationally invariant) Matrix Product States. It is the uniform version of MPS, that is, all nodes share the same tensor. Thus this class cannot have different physical or bond dimensions for each node, and boundary conditions are always periodic ("pbc").


For a more detailed list of inherited properties and methods, check MPS.

Parameters
  • n_features (int) – Number of nodes that will be in mats_env.

  • phys_dim (int, optional) – Physical dimension.

  • bond_dim (int, optional) – Bond dimension.

  • tensor (torch.Tensor, optional) – Instead of providing phys_dim and bond_dim, a single tensor can be provided. n_features is still needed to specify how many times the tensor should be used to form a finite MPS. The tensor should be rank-3, with its first and last dimensions being equal.

  • in_features (list[int] or tuple[int], optional) – List of indices indicating the positions of the MPS nodes that will be considered as input nodes. These nodes will have a neighbouring data node connected to its "input" edge when the set_data_nodes() method is called. in_features is the complementary set of out_features, so it is only required to specify one of them.

  • out_features (list[int] or tuple[int], optional) – List of indices indicating the positions of the MPS nodes that will be considered as output nodes. These nodes will be left with their "input" edges open when contrating the network. If marginalize_output is set to True in contract(), the network will be connected to itself at these nodes, and contracted. out_features is the complementary set of in_features, so it is only required to specify one of them.

  • n_batches (int) – Number of batch edges of input data nodes. Usually n_batches = 1 (where the batch edge is used for the data batched) but it could also be n_batches = 2 (one edge for data batched, other edge for image patches in convolutional layers).

  • init_method ({"zeros", "ones", "copy", "rand", "randn", "randn_eye", "unit"}, optional) – Initialization method. Check initialize() for a more detailed explanation of the different initialization methods.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

Examples

>>> mps = tk.models.UMPS(n_features=4,
...                      phys_dim=2,
...                      bond_dim=5)
>>> for node in mps.mats_env:
...     assert node.tensor_address() == 'virtual_uniform'
...
>>> data = torch.ones(20, 4, 2) # batch_size x n_features x feature_size
>>> result = mps(data)
>>> result.shape
torch.Size([20])
initialize(tensors=None, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Initializes the common tensor of the UMPS. It can be called when instantiating the model, or to override the existing nodes’ tensors.

There are different methods to initialize the nodes:

  • {"zeros", "ones", "copy", "rand", "randn"}: The tensor is initialized calling set_tensor() with the given method, device, dtype and kwargs.

  • "randn_eye": Tensor is initialized as in this paper, adding identities at the top of a random gaussian tensor. In this case, std should be specified with a low value, e.g., std = 1e-9.

  • "unit": Tensor is initialized as a stack of random unitaries. This, combined (at least) with an embedding of the inputs as elements of the computational basis (discretize() combined with basis())

  • "canonical"`: MPS is initialized in canonical form with a squared norm close to the product of all the physical dimensions (if bond dimensions are bigger than the powers of the physical dimensions, the norm could vary).

Parameters
  • tensors (list[torch.Tensor] or tuple[torch.Tensor], optional) – Sequence of a single tensor to set in each of the MPS nodes. The tensor should be rank-3, with its first and last dimensions being equal.

  • init_method ({"zeros", "ones", "copy", "rand", "randn", "randn_eye", "unit", "canonical"}, optional) – Initialization method.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

copy(share_tensors=False)[source]#

Creates a copy of the UMPS.

Parameters

share_tensor (bool, optional) – Boolean indicating whether the common tensor in the copied UMPS should be set as the tensor in the current UMPS (True), or cloned (False). In the former case, the tensor in both UMPS’s will be the same, which might be useful if one needs more than one copy of a UMPS, but wants to compute all the gradients with respect to the same, unique, tensor.

Return type

UMPS

parameterize(set_param=True, override=False)[source]#

Parameterizes all nodes of the MPS. If there are resultant nodes in the MPS, it will be first reset().

Parameters
  • set_param (bool) – Boolean indicating whether the tensor network has to be parameterized (True) or de-parameterized (False).

  • override (bool) – Boolean indicating whether the tensor network should be parameterized in-place (True) or copied and then parameterized (False).

MPSLayer#

class tensorkrowch.models.MPSLayer(n_features=None, in_dim=None, out_dim=None, bond_dim=None, out_position=None, boundary='obc', tensors=None, n_batches=1, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Class for Matrix Product States with a single output node. That is, this MPS has \(n\) nodes, being \(n-1\) input nodes connected to data nodes (nodes that will contain the data tensors), and one output node, whose physical dimension (out_dim) is used as the label (for classification tasks).

Besides, since this class has an output edge, when contracting the whole tensor network (with input data), the result will be a vector that can be plugged into the next layer (being this other tensor network or a neural network layer).

If the physical dimensions of all the input nodes (in_dim) are equal, the input data tensor can be passed as a single tensor. Otherwise, it would have to be passed as a list of tensors with different sizes.


That is, MPSLayer is equivalent to MPS with out_features = [out_position]. However, in_features and out_features are still free to be changed if necessary, even though this may change the expected behaviour of the MPSLayer. The expected behaviour can be recovered by setting out_features = [out_position] again.


For a more detailed list of inherited properties and methods, check MPS.

Parameters
  • n_features (int, optional) – Number of nodes that will be in mats_env. That is, number of nodes without taking into account left_node and right_node. This also includes the output node, so if one wants to instantiate an MPSLayer for a dataset with n features, it should be n_features = n + 1, to account for the output node.

  • in_dim (int, list[int] or tuple[int], optional) – Input dimension(s). Equivalent to the physical dimension(s) but only for input nodes. If given as a sequence, its length should be equal to n_features - 1, since these are the input dimensions of the input nodes.

  • out_dim (int, optional) – Output dimension (labels) for the output node. Equivalent to the physical dimension of the output node.

  • bond_dim (int, list[int] or tuple[int], optional) – Bond dimension(s). If given as a sequence, its length should be equal to n_features (if boundary = "pbc") or n_features - 1 (if boundary = "obc"). The i-th bond dimension is always the dimension of the right edge of the i-th node (including output node).

  • out_position (int, optional) – Position of the output node (label). Should be between 0 and n_features - 1. If None, the output node will be located at the middle of the MPS.

  • boundary ({"obc", "pbc"}) – String indicating whether periodic or open boundary conditions should be used.

  • tensors (list[torch.Tensor] or tuple[torch.Tensor], optional) – Instead of providing n_features, in_dim, out_dim, bond_dim and boundary, a list of MPS tensors can be provided. In such case, all mentioned attributes will be inferred from the given tensors. All tensors should be rank-3 tensors, with shape (bond_dim, phys_dim, bond_dim). If the first and last elements are rank-2 tensors, with shapes (phys_dim, bond_dim), (bond_dim, phys_dim), respectively, the inferred boundary conditions will be “obc”. Also, if tensors contains a single element, it can be rank-1 (“obc”) or rank-3 (“pbc”).

  • n_batches (int) – Number of batch edges of input data nodes. Usually n_batches = 1 (where the batch edge is used for the data batched) but it could also be n_batches = 2 (e.g. one edge for data batched, other edge for image patches in convolutional layers).

  • init_method ({"zeros", "ones", "copy", "rand", "randn", "randn_eye", "unit"}, optional) – Initialization method. Check initialize() for a more detailed explanation of the different initialization methods.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

Examples

MPSLayer with same input dimensions:

>>> mps_layer = tk.models.MPSLayer(n_features=4,
...                                in_dim=2,
...                                out_dim=10,
...                                bond_dim=5)
>>> data = torch.ones(20, 3, 2) # batch_size x (n_features - 1) x feature_size
>>> result = mps_layer(data)
>>> result.shape
torch.Size([20, 10])

MPSLayer with different input dimensions:

>>> mps_layer = tk.models.MPSLayer(n_features=4,
...                                in_dim=list(range(2, 5)),
...                                out_dim=10,
...                                bond_dim=5)
>>> data = [torch.ones(20, i)
...         for i in range(2, 5)] # (n_features - 1) * [batch_size x feature_size]
>>> result = mps_layer(data)
>>> result.shape
torch.Size([20, 10])
property in_dim#

Returns input dimensions.

property out_dim#

Returns the output dimension, that is, the number of labels in the output node. Same as in_dim for input nodes.

property out_position#

Returns position of the output node (label).

property out_node#

Returns the output node.

initialize(tensors=None, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Initializes all the nodes of the MPSLayer. It can be called when instantiating the model, or to override the existing nodes’ tensors.

There are different methods to initialize the nodes:

  • {"zeros", "ones", "copy", "rand", "randn"}: Each node is initialized calling set_tensor() with the given method, device, dtype and kwargs.

  • "randn_eye": Nodes are initialized as in this paper, adding identities at the top of random gaussian tensors. In this case, std should be specified with a low value, e.g., std = 1e-9.

  • "unit": Nodes are initialized as stacks of random unitaries. This, combined (at least) with an embedding of the inputs as elements of the computational basis (discretize() combined with basis())

  • "canonical"`: MPS is initialized in canonical form with a squared norm close to the product of all the physical dimensions (if bond dimensions are bigger than the powers of the physical dimensions, the norm could vary). Th orthogonality center is at the output node.

Parameters
  • tensors (list[torch.Tensor] or tuple[torch.Tensor], optional) – Sequence of tensors to set in each of the MPS nodes. If boundary is "obc", all tensors should be rank-3, except the first and last ones, which can be rank-2, or rank-1 (if the first and last are the same). If boundary is "pbc", all tensors should be rank-3.

  • init_method ({"zeros", "ones", "copy", "rand", "randn", "randn_eye", "unit", "canonical"}, optional) – Initialization method.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

copy(share_tensors=False)[source]#

Creates a copy of the MPSLayer.

Parameters

share_tensor (bool, optional) – Boolean indicating whether tensors in the copied MPSLayer should be set as the tensors in the current MPSLayer (True), or cloned (False). In the former case, tensors in both MPSLayer’s will be the same, which might be useful if one needs more than one copy of an MPSLayer, but wants to compute all the gradients with respect to the same, unique, tensors.

Return type

MPSLayer

UMPSLayer#

class tensorkrowch.models.UMPSLayer(n_features, in_dim=None, out_dim=None, bond_dim=None, out_position=None, tensors=None, n_batches=1, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Class for Uniform (translationally invariant) Matrix Product States with an output node. It is the uniform version of MPSLayer, with all input nodes sharing the same tensor, but with a different node for the output node. Thus this class cannot have different input or bond dimensions for each node, and boundary conditions are always periodic ("pbc").


For a more detailed list of inherited properties and methods, check MPS.

Parameters
  • n_features (int) – Number of nodes that will be in mats_env. This also includes the output node, so if one wants to instantiate a UMPSLayer for a dataset with n features, it should be n_features = n + 1, to account for the output node.

  • in_dim (int, optional) – Input dimension. Equivalent to the physical dimension but only for input nodes.

  • out_dim (int, optional) – Output dimension (labels) for the output node.

  • bond_dim (int, optional) – Bond dimension.

  • out_position (int, optional) – Position of the output node (label). Should be between 0 and n_features - 1. If None, the output node will be located at the middle of the MPS.

  • tensors (list[torch.Tensor] or tuple[torch.Tensor], optional) – Instead of providing in_dim, out_dim and bond_dim, a sequence of 2 tensors can be provided, the first one will be the uniform tensor, and the second one will be the output node’s tensor. n_features is still needed to specify how many times the uniform tensor should be used to form a finite MPS. In this case, since the output node will have a different tensor, the uniform tensor will be used in the remaining n_features - 1 input nodes. Both tensors should be rank-3, with all their first and last dimensions being equal.

  • n_batches (int) – Number of batch edges of input data nodes. Usually n_batches = 1 (where the batch edge is used for the data batched) but it could also be n_batches = 2 (one edge for data batched, other edge for image patches in convolutional layers).

  • init_method ({"zeros", "ones", "copy", "rand", "randn", "randn_eye", "unit"}, optional) – Initialization method. Check initialize() for a more detailed explanation of the different initialization methods.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

Examples

>>> mps_layer = tk.models.UMPSLayer(n_features=4,
...                                 in_dim=2,
...                                 out_dim=10,
...                                 bond_dim=5)
>>> for i, node in enumerate(mps_layer.mats_env):
...     if i != mps_layer.out_position:
...         assert node.tensor_address() == 'virtual_uniform'
...
>>> data = torch.ones(20, 3, 2) # batch_size x (n_features - 1) x feature_size
>>> result = mps_layer(data)
>>> result.shape
torch.Size([20, 10])
property in_dim#

Returns input dimensions.

property out_dim#

Returns the output dimension, that is, the number of labels in the output node. Same as in_dim for input nodes.

property out_position#

Returns position of the output node (label).

property out_node#

Returns the output node.

initialize(tensors=None, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Initializes the common tensor of the UMPSLayer. It can be called when instantiating the model, or to override the existing nodes’ tensors.

There are different methods to initialize the nodes:

  • {"zeros", "ones", "copy", "rand", "randn"}: The tensor is initialized calling set_tensor() with the given method, device, dtype and kwargs.

  • "randn_eye": Tensor is initialized as in this paper, adding identities at the top of a random gaussian tensor. In this case, std should be specified with a low value, e.g., std = 1e-9.

  • "unit": Tensor is initialized as a stack of random unitaries. This, combined (at least) with an embedding of the inputs as elements of the computational basis (discretize() combined with basis())

  • "canonical"`: MPS is initialized in canonical form with a squared norm close to the product of all the physical dimensions (if bond dimensions are bigger than the powers of the physical dimensions, the norm could vary).

Parameters
  • tensors (list[torch.Tensor] or tuple[torch.Tensor], optional) – Sequence of a 2 tensors, the first one will be the uniform tensor that will be set in all input nodes, and the second one will be the output node’s tensor. Both tensors should be rank-3, with all their first and last dimensions being equal.

  • init_method ({"zeros", "ones", "copy", "rand", "randn", "randn_eye", "unit", "canonical"}, optional) – Initialization method.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

copy(share_tensors=False)[source]#

Creates a copy of the UMPSLayer.

Parameters

share_tensor (bool, optional) – Boolean indicating whether tensors in the copied UMPSLayer should be set as the tensors in the current UMPSLayer (True), or cloned (False). In the former case, tensors in both UMPSLayer’s will be the same, which might be useful if one needs more than one copy of an UMPSLayer, but wants to compute all the gradients with respect to the same, unique, tensors.

Return type

UMPSLayer

parameterize(set_param=True, override=False)[source]#

Parameterizes all nodes of the MPS. If there are resultant nodes in the MPS, it will be first reset().

Parameters
  • set_param (bool) – Boolean indicating whether the tensor network has to be parameterized (True) or de-parameterized (False).

  • override (bool) – Boolean indicating whether the tensor network should be parameterized in-place (True) or copied and then parameterized (False).

ConvMPS#

class tensorkrowch.models.ConvMPS(in_channels, bond_dim, kernel_size, stride=1, padding=0, dilation=1, boundary='obc', tensors=None, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Convolutional version of MPS, where the input data is assumed to be a batch of images.

Input data as well as initialization parameters are described in torch.nn.Conv2d.

Parameters
  • in_channels (int) – Input channels. Same as phys_dim in MPS.

  • bond_dim (int, list[int] or tuple[int]) – Bond dimension(s). If given as a sequence, its length should be equal to \(kernel\_size_0 \cdot kernel\_size_1\) (if boundary = "pbc") or \(kernel\_size_0 \cdot kernel\_size_1 - 1\) (if boundary = "obc"). The i-th bond dimension is always the dimension of the right edge of the i-th node.

  • kernel_size (int, list[int] or tuple[int]) – Kernel size used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • stride (int) –

    Stride used in torch.nn.Unfold.

  • padding (int) –

    Padding used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • dilation (int) –

    Dilation used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • boundary ({"obc", "pbc"}) – String indicating whether periodic or open boundary conditions should be used.

  • tensors (list[torch.Tensor] or tuple[torch.Tensor], optional) – To initialize MPS nodes, a list of MPS tensors can be provided. All tensors should be rank-3 tensors, with shape (bond_dim, in_channels, bond_dim). If the first and last elements are rank-2 tensors, with shapes (in_channels, bond_dim), (bond_dim, in_channels), respectively, the inferred boundary conditions will be “obc”. Also, if tensors contains a single element, it can be rank-1 (“obc”) or rank-3 (“pbc”).

  • init_method ({"zeros", "ones", "copy", "rand", "randn", "randn_eye", "unit"}, optional) – Initialization method. Check initialize() for a more detailed explanation of the different initialization methods.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

Examples

>>> conv_mps = tk.models.ConvMPS(in_channels=2,
...                              bond_dim=5,
...                              kernel_size=2)
>>> data = torch.ones(20, 2, 2, 2) # batch_size x in_channels x height x width
>>> result = conv_mps(data)
>>> result.shape
torch.Size([20, 1, 1])
forward(image, mode='flat', *args, **kwargs)#

Overrides forward() to compute a convolution on the input image.

Parameters
  • image (torch.Tensor) –

    Input batch of images with shape

    \[batch\_size \times in\_channels \times height \times width\]

  • mode ({"flat", "snake"}) – Indicates the order in which MPS should take the pixels in the image. When "flat", the image is flattened putting one row of the image after the other. When "snake", its row is put in the opposite orientation as the previous row (like a snake running through the image).

  • args – Arguments that might be used in contract().

  • kwargs – Keyword arguments that might be used in contract(), like inline_input or inline_mats.

property in_channels#

Returns in_channels. Same as phys_dim in MPS.

property kernel_size#

Returns kernel_size. Number of nodes is given by \(kernel\_size_0 \cdot kernel\_size_1\).

property stride#

Returns stride used in torch.nn.Unfold.

property padding#

Returns padding used in torch.nn.Unfold.

property dilation#

Returns dilation used in torch.nn.Unfold.

copy(share_tensors=False)[source]#

Creates a copy of the ConvMPS.

Parameters

share_tensor (bool, optional) – Boolean indicating whether tensors in the copied ConvMPS should be set as the tensors in the current ConvMPS (True), or cloned (False). In the former case, tensors in both ConvMPS’s will be the same, which might be useful if one needs more than one copy of a ConvMPS, but wants to compute all the gradients with respect to the same, unique, tensors.

Return type

ConvMPS

ConvUMPS#

class tensorkrowch.models.ConvUMPS(in_channels, bond_dim, kernel_size, stride=1, padding=0, dilation=1, tensor=None, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Convolutional version of UMPS, where the input data is assumed to be a batch of images.

Input data as well as initialization parameters are described in torch.nn.Conv2d.

Parameters
  • in_channels (int) – Input channels. Same as phys_dim in UMPS.

  • bond_dim (int) – Bond dimension.

  • kernel_size (int, list[int] or tuple[int]) –

    Kernel size used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • stride (int) –

    Stride used in torch.nn.Unfold.

  • padding (int) –

    Padding used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • dilation (int) –

    Dilation used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • tensor (torch.Tensor, optional) – To initialize MPS nodes, a MPS tensor can be provided. The tensor should be rank-3, with its first and last dimensions being equal.

  • init_method ({"zeros", "ones", "copy", "rand", "randn", "randn_eye", "unit"}, optional) – Initialization method. Check initialize() for a more detailed explanation of the different initialization methods.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

Examples

>>> conv_mps = tk.models.ConvUMPS(in_channels=2,
...                               bond_dim=5,
...                               kernel_size=2)
>>> for node in conv_mps.mats_env:
...     assert node.tensor_address() == 'virtual_uniform'
...
>>> data = torch.ones(20, 2, 2, 2) # batch_size x in_channels x height x width
>>> result = conv_mps(data)
>>> result.shape
torch.Size([20, 1, 1])
forward(image, mode='flat', *args, **kwargs)#

Overrides forward() to compute a convolution on the input image.

Parameters
  • image (torch.Tensor) –

    Input batch of images with shape

    \[batch\_size \times in\_channels \times height \times width\]

  • mode ({"flat", "snake"}) – Indicates the order in which MPS should take the pixels in the image. When "flat", the image is flattened putting one row of the image after the other. When "snake", its row is put in the opposite orientation as the previous row (like a snake running through the image).

  • args – Arguments that might be used in contract().

  • kwargs – Keyword arguments that might be used in contract(), like inline_input or inline_mats.

property in_channels#

Returns in_channels. Same as phys_dim in MPS.

property kernel_size#

Returns kernel_size. Number of nodes is given by \(kernel\_size_0 \cdot kernel\_size_1\).

property stride#

Returns stride used in torch.nn.Unfold.

property padding#

Returns padding used in torch.nn.Unfold.

property dilation#

Returns dilation used in torch.nn.Unfold.

copy(share_tensors=False)[source]#

Creates a copy of the ConvUMPS.

Parameters

share_tensor (bool, optional) – Boolean indicating whether the common tensor in the copied ConvUMPS should be set as the tensor in the current ConvUMPS (True), or cloned (False). In the former case, the tensor in both ConvUMPS’s will be the same, which might be useful if one needs more than one copy of a ConvUMPS, but wants to compute all the gradients with respect to the same, unique, tensor.

Return type

ConvUMPS

ConvMPSLayer#

class tensorkrowch.models.ConvMPSLayer(in_channels, out_channels, bond_dim, kernel_size, stride=1, padding=0, dilation=1, out_position=None, boundary='obc', tensors=None, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Convolutional version of MPSLayer, where the input data is assumed to be a batch of images.

Input data as well as initialization parameters are described in torch.nn.Conv2d.

Parameters
  • in_channels (int) – Input channels. Same as in_dim in MPSLayer.

  • out_channels (int) – Output channels. Same as out_dim in MPSLayer.

  • bond_dim (int, list[int] or tuple[int]) – Bond dimension(s). If given as a sequence, its length should be equal to \(kernel\_size_0 \cdot kernel\_size_1 + 1\) (if boundary = "pbc") or \(kernel\_size_0 \cdot kernel\_size_1\) (if boundary = "obc"). The i-th bond dimension is always the dimension of the right edge of the i-th node (including output node).

  • kernel_size (int, list[int] or tuple[int]) –

    Kernel size used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • stride (int) –

    Stride used in torch.nn.Unfold.

  • padding (int) –

    Padding used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • dilation (int) –

    Dilation used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • out_position (int, optional) – Position of the output node (label). Should be between 0 and \(kernel\_size_0 \cdot kernel\_size_1\). If None, the output node will be located at the middle of the MPS.

  • boundary ({"obc", "pbc"}) – String indicating whether periodic or open boundary conditions should be used.

  • tensors (list[torch.Tensor] or tuple[torch.Tensor], optional) – To initialize MPS nodes, a list of MPS tensors can be provided. All tensors should be rank-3 tensors, with shape (bond_dim, in_channels, bond_dim). If the first and last elements are rank-2 tensors, with shapes (in_channels, bond_dim), (bond_dim, in_channels), respectively, the inferred boundary conditions will be “obc”. Also, if tensors contains a single element, it can be rank-1 (“obc”) or rank-3 (“pbc”).

  • init_method ({"zeros", "ones", "copy", "rand", "randn", "randn_eye", "unit"}, optional) – Initialization method. Check initialize() for a more detailed explanation of the different initialization methods.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

Examples

>>> conv_mps_layer = tk.models.ConvMPSLayer(in_channels=2,
...                                         out_channels=10,
...                                         bond_dim=5,
...                                         kernel_size=2)
>>> data = torch.ones(20, 2, 2, 2) # batch_size x in_channels x height x width
>>> result = conv_mps_layer(data)
>>> result.shape
torch.Size([20, 10, 1, 1])
forward(image, mode='flat', *args, **kwargs)#

Overrides forward() to compute a convolution on the input image.

Parameters
  • image (torch.Tensor) –

    Input batch of images with shape

    \[batch\_size \times in\_channels \times height \times width\]

  • mode ({"flat", "snake"}) – Indicates the order in which MPS should take the pixels in the image. When "flat", the image is flattened putting one row of the image after the other. When "snake", its row is put in the opposite orientation as the previous row (like a snake running through the image).

  • args – Arguments that might be used in contract().

  • kwargs – Keyword arguments that might be used in contract(), like inline_input or inline_mats.

property in_channels#

Returns in_channels. Same as in_dim in MPSLayer.

property out_channels#

Returns out_channels. Same as out_dim in MPSLayer.

property kernel_size#

Returns kernel_size. Number of nodes is given by \(kernel\_size_0 \cdot kernel\_size_1 + 1\).

property stride#

Returns stride used in torch.nn.Unfold.

property padding#

Returns padding used in torch.nn.Unfold.

property dilation#

Returns dilation used in torch.nn.Unfold.

copy(share_tensors=False)[source]#

Creates a copy of the ConvMPSLayer.

Parameters

share_tensor (bool, optional) – Boolean indicating whether tensors in the copied ConvMPSLayer should be set as the tensors in the current ConvMPSLayer (True), or cloned (False). In the former case, tensors in both ConvMPSLayer’s will be the same, which might be useful if one needs more than one copy of an ConvMPSLayer, but wants to compute all the gradients with respect to the same, unique, tensors.

Return type

ConvMPSLayer

ConvUMPSLayer#

class tensorkrowch.models.ConvUMPSLayer(in_channels, out_channels, bond_dim, kernel_size, stride=1, padding=0, dilation=1, out_position=None, tensors=None, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Convolutional version of UMPSLayer, where the input data is assumed to be a batch of images.

Input data as well as initialization parameters are described in torch.nn.Conv2d.

Parameters
  • in_channels (int) – Input channels. Same as in_dim in UMPSLayer.

  • out_channels (int) – Output channels. Same as out_dim in UMPSLayer.

  • bond_dim (int) – Bond dimension.

  • kernel_size (int, list[int] or tuple[int]) –

    Kernel size used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • stride (int) –

    Stride used in torch.nn.Unfold.

  • padding (int) –

    Padding used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • dilation (int) –

    Dilation used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • out_position (int, optional) – Position of the output node (label). Should be between 0 and \(kernel\_size_0 \cdot kernel\_size_1\). If None, the output node will be located at the middle of the MPS.

  • tensors (list[torch.Tensor] or tuple[torch.Tensor], optional) – To initialize MPS nodes, a sequence of 2 tensors can be provided, the first one will be the uniform tensor, and the second one will be the output node’s tensor. Both tensors should be rank-3, with all their first and last dimensions being equal.

  • init_method ({"zeros", "ones", "copy", "rand", "randn", "randn_eye", "unit"}, optional) – Initialization method. Check initialize() for a more detailed explanation of the different initialization methods.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

Examples

>>> conv_mps_layer = tk.models.ConvUMPSLayer(in_channels=2,
...                                          out_channels=10,
...                                          bond_dim=5,
...                                          kernel_size=2)
>>> for i, node in enumerate(conv_mps_layer.mats_env):
...     if i != conv_mps_layer.out_position:
...         assert node.tensor_address() == 'virtual_uniform'
...
>>> data = torch.ones(20, 2, 2, 2) # batch_size x in_channels x height x width
>>> result = conv_mps_layer(data)
>>> result.shape
torch.Size([20, 10, 1, 1])
forward(image, mode='flat', *args, **kwargs)#

Overrides forward() to compute a convolution on the input image.

Parameters
  • image (torch.Tensor) –

    Input batch of images with shape

    \[batch\_size \times in\_channels \times height \times width\]

  • mode ({"flat", "snake"}) – Indicates the order in which MPS should take the pixels in the image. When "flat", the image is flattened putting one row of the image after the other. When "snake", its row is put in the opposite orientation as the previous row (like a snake running through the image).

  • args – Arguments that might be used in contract().

  • kwargs – Keyword arguments that might be used in contract(), like inline_input or inline_mats.

property in_channels#

Returns in_channels. Same as in_dim in UMPSLayer.

property kernel_size#

Returns kernel_size. Number of nodes is given by \(kernel\_size_0 \cdot kernel\_size_1 + 1\).

property stride#

Returns stride used in torch.nn.Unfold.

property padding#

Returns padding used in torch.nn.Unfold.

property dilation#

Returns dilation used in torch.nn.Unfold.

property out_channels#

Returns out_channels. Same as phys_dim in MPS.

copy(share_tensors=False)[source]#

Creates a copy of the ConvUMPSLayer.

Parameters

share_tensor (bool, optional) – Boolean indicating whether tensors in the copied ConvUMPSLayer should be set as the tensors in the current ConvUMPSLayer (True), or cloned (False). In the former case, tensors in both ConvUMPSLayer’s will be the same, which might be useful if one needs more than one copy of an ConvUMPSLayer, but wants to compute all the gradients with respect to the same, unique, tensors.

Return type

ConvUMPSLayer

MPSData#

MPSData#

class tensorkrowch.models.MPSData(n_features=None, phys_dim=None, bond_dim=None, boundary='obc', n_batches=1, tensors=None, init_method=None, device=None, dtype=None, **kwargs)[source]#

Class for data vectors in the form of Matrix Product States. That is, this is a class similar to MPS, but where all nodes can have additional batch edges.

Besides, since this class is intended to store data vectors, all nodes are non-parametric, and are data nodes. Also, this class does not have an inherited contract method, since it is not intended to be contracted with input data, but rather act itself as input data of another tensor network model.

Similar to MPS, MPSData is formed by:

  • mats_env: Environment of matrix nodes with axes ("batch_0", ..., "batch_n", "left", "feature", "right").

  • left_node, right_node: Vector nodes with axes ("right",) and ("left",), respectively. These are used to close the boundary in the case boudary is "obc". Otherwise, both are None.

Since MPSData is designed to store input data vectors, this can be accomplished by calling the custom add_data() method with a given list of tensors. This is in contrast to the usual way of setting nodes’ tensors in MPS and its derived classes via MPS.initialize().

Parameters
  • n_features (int, optional) – Number of nodes that will be in mats_env. That is, number of nodes without taking into account left_node and right_node.

  • phys_dim (int, list[int] or tuple[int], optional) – Physical dimension(s). If given as a sequence, its length should be equal to n_features.

  • bond_dim (int, list[int] or tuple[int], optional) – Bond dimension(s). If given as a sequence, its length should be equal to n_features (if boundary = "pbc") or n_features - 1 (if boundary = "obc"). The i-th bond dimension is always the dimension of the right edge of the i-th node.

  • boundary ({"obc", "pbc"}) – String indicating whether periodic or open boundary conditions should be used.

  • n_batches (int) – Number of batch edges of the MPS nodes. Usually n_batches = 1 (where the batch edge is used for the data batched) but it could also be n_batches = 2 (one edge for data batched, other edge for image patches in convolutional layers).

  • tensors (list[torch.Tensor] or tuple[torch.Tensor], optional) – Instead of providing n_features, phys_dim, bond_dim and boundary, a list of MPS tensors can be provided. In such case, all mentioned attributes will be inferred from the given tensors. All tensors should be rank-(n+3) tensors, with shape (batch_1, ..., batch_n, bond_dim, phys_dim, bond_dim). If the first and last elements are rank-(n+2) tensors, with shapes (batch_1, ..., batch_n, phys_dim, bond_dim), (batch_1, ..., batch_n, bond_dim, phys_dim), respectively, the inferred boundary conditions will be “obc”. Also, if tensors contains a single element, it can be rank-(n+1) (“obc”) or rank-(n+3) (“pbc”).

  • init_method ({"zeros", "ones", "copy", "rand", "randn"}, optional) – Initialization method. Check initialize() for a more detailed explanation of the different initialization methods. By default it is None, since MPSData is intended to store input data vectors in MPS form, rather than initializing its own random tensors. Check add_data() to see how to initialize MPS nodes with data tensors.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

Examples

>>> mps = tk.models.MPSData(n_features=5,
...                         phys_dim=2,
...                         bond_dim=5,
...                         boundary="pbc")
>>> # n_features * (batch_size x bond_dim x feature_size x bond_dim)
>>> data = [torch.ones(20, 5, 2, 5) for _ in range(5)]
>>> mps.add_data(data)
>>> for node in mps.mats_env:
...     assert node.shape == (20, 5, 2, 5)
property n_features#

Returns number of nodes.

property phys_dim#

Returns physical dimensions.

property bond_dim#

Returns bond dimensions.

property boundary#

Returns boundary condition (“obc” or “pbc”).

property n_batches#

Returns number of batch edges of the MPS nodes.

property left_node#

Returns the left_node.

property right_node#

Returns the right_node.

property mats_env#

Returns the list of nodes in mats_env.

property tensors#

Returns the list of MPS tensors.

initialize(init_method='randn', device=None, dtype=None, **kwargs)[source]#

Initializes all the nodes of the MPSData. It can be called when instantiating the model, or to override the existing nodes’ tensors.

There are different methods to initialize the nodes:

  • {"zeros", "ones", "copy", "rand", "randn"}: Each node is initialized calling set_tensor() with the given method, device, dtype and kwargs.

Parameters
  • init_method ({"zeros", "ones", "copy", "rand", "randn"}, optional) – Initialization method. Check add_data() to see how to initialize MPS nodes with data tensors.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

add_data(data)[source]#

Adds data to MPS data nodes. Input is a list of mps tensors.

The physical dimensions of the given data tensors should coincide with the physical dimensions of the MPS. The bond dimensions can be different.

Parameters

data (list[torch.Tensor] or tuple[torch.Tensor]) – A sequence of tensors, one for each of the MPS nodes. If boundary is "pbc", all tensors should have the same rank, with shapes (batch_0, ..., batch_n, bond_dim, phys_dim, bond_dim). If boundary is "obc", the first and last tensors should have shapes (batch_0, ..., batch_n, phys_dim, bond_dim) and (batch_0, ..., batch_n, bond_dim, phys_dim), respectively.

MPO#

MPO#

class tensorkrowch.models.MPO(n_features=None, in_dim=None, out_dim=None, bond_dim=None, boundary='obc', tensors=None, n_batches=1, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Class for Matrix Product Operators. This is the base class from which UMPO inherits.

Matrix Product Operators are formed by:

  • mats_env: Environment of matrix nodes with axes ("left", "input", "right", "output").

  • left_node, right_node: Vector nodes with axes ("right",) and ("left",), respectively. These are used to close the boundary in the case boudary is "obc". Otherwise, both are None.

In contrast with MPS, in MPO all nodes act both as input and output, with corresponding edges dedicated to that. Thus, data nodes will be connected to the "input" edge of all nodes. Upon contraction of the whole network, a resultant tensor will be formed, with as many dimensions as nodes were in the MPO.

If all nodes have the same input dimensions, the input data tensor can be passed as a single tensor. Otherwise, it would have to be passed as a list of tensors with different sizes.

Parameters
  • n_features (int, optional) – Number of nodes that will be in mats_env. That is, number of nodes without taking into account left_node and right_node.

  • in_dim (int, list[int] or tuple[int], optional) – Input dimension(s). If given as a sequence, its length should be equal to n_features.

  • out_dim (int, list[int] or tuple[int], optional) – Output dimension(s). If given as a sequence, its length should be equal to n_features.

  • bond_dim (int, list[int] or tuple[int], optional) – Bond dimension(s). If given as a sequence, its length should be equal to n_features (if boundary = "pbc") or n_features - 1 (if boundary = "obc"). The i-th bond dimension is always the dimension of the right edge of the i-th node.

  • boundary ({"obc", "pbc"}) – String indicating whether periodic or open boundary conditions should be used.

  • tensors (list[torch.Tensor] or tuple[torch.Tensor], optional) – Instead of providing n_features, in_dim, in_dim, bond_dim and boundary, a list of MPO tensors can be provided. In such case, all mentioned attributes will be inferred from the given tensors. All tensors should be rank-4 tensors, with shape (bond_dim, in_dim, bond_dim, out_dim). If the first and last elements are rank-3 tensors, with shapes (in_dim, bond_dim, out_dim), (bond_dim, in_dim, out_dim), respectively, the inferred boundary conditions will be “obc”. Also, if tensors contains a single element, it can be rank-2 (“obc”) or rank-4 (“pbc”).

  • n_batches (int) – Number of batch edges of input data nodes. Usually n_batches = 1 (where the batch edge is used for the data batched) but it could also be n_batches = 2 (one edge for data batched, other edge for image patches in convolutional layers).

  • init_method ({"zeros", "ones", "copy", "rand", "randn"}, optional) – Initialization method. Check initialize() for a more detailed explanation of the different initialization methods.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

Examples

MPO with same input/output dimensions:

>>> mpo = tk.models.MPO(n_features=5,
...                     in_dim=2,
...                     out_dim=2,
...                     bond_dim=5)
>>> data = torch.ones(20, 5, 2) # batch_size x n_features x feature_size
>>> result = mpo(data)
>>> result.shape
torch.Size([20, 2, 2, 2, 2, 2])

MPO with different input/physical dimensions:

>>> mpo = tk.models.MPO(n_features=5,
...                     in_dim=list(range(2, 7)),
...                     out_dim=list(range(7, 2, -1)),
...                     bond_dim=5)
>>> data = [torch.ones(20, i)
...         for i in range(2, 7)] # n_features * [batch_size x feature_size]
>>> result = mpo(data)
>>> result.shape
torch.Size([20, 7, 6, 5, 4, 3])
property n_features#

Returns number of nodes.

property in_dim#

Returns input dimensions.

property out_dim#

Returns output dimensions.

property bond_dim#

Returns bond dimensions.

property boundary#

Returns boundary condition (“obc” or “pbc”).

property n_batches#

Returns number of batch edges of the data nodes. To change this attribute, first call unset_data_nodes() if there are already data nodes in the network.

property left_node#

Returns the left_node.

property right_node#

Returns the right_node.

property mats_env#

Returns the list of nodes in mats_env.

property tensors#

Returns the list of MPO tensors.

initialize(tensors=None, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Initializes all the nodes of the MPO. It can be called when instantiating the model, or to override the existing nodes’ tensors.

There are different methods to initialize the nodes:

  • {"zeros", "ones", "copy", "rand", "randn"}: Each node is initialized calling set_tensor() with the given method, device, dtype and kwargs.

Parameters
  • tensors (list[torch.Tensor] or tuple[torch.Tensor], optional) – Sequence of tensors to set in each of the MPO nodes. If boundary is "obc", all tensors should be rank-4, except the first and last ones, which can be rank-3, or rank-2 (if the first and last are the same). If boundary is "pbc", all tensors should be rank-4.

  • init_method ({"zeros", "ones", "copy", "rand", "randn"}, optional) – Initialization method.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

set_data_nodes()[source]#

Creates data nodes and connects each of them to the "input" edge of each node.

copy(share_tensors=False)[source]#

Creates a copy of the MPO.

Parameters

share_tensor (bool, optional) – Boolean indicating whether tensors in the copied MPO should be set as the tensors in the current MPO (True), or cloned (False). In the former case, tensors in both MPO’s will be the same, which might be useful if one needs more than one copy of an MPO, but wants to compute all the gradients with respect to the same, unique, tensors.

Return type

MPO

parameterize(set_param=True, override=False)[source]#

Parameterizes all nodes of the MPO. If there are resultant nodes in the MPO, it will be first reset().

Parameters
  • set_param (bool) – Boolean indicating whether the tensor network has to be parameterized (True) or de-parameterized (False).

  • override (bool) – Boolean indicating whether the tensor network should be parameterized in-place (True) or copied and then parameterized (False).

update_bond_dim()[source]#

Updates the bond_dim attribute of the MPO, in case it is outdated.

If bond dimensions are changed, usually due to decompositions like svd(), update_bond_dim should be called. This might modify some elements of the model, so it is recommended to do this before saving the state_dict of the model. Besides, if one wants to continue training, the parameters of the model that are passed to the optimizer should be updated also. Otherwise, the optimizer could be tracking outdated parameters that are not members of the model any more.

contract(inline_input=False, inline_mats=False, renormalize=False, mps=None)[source]#

Contracts the whole MPO with input data nodes. The input can be in the form of an MPSData, which may be convenient for tensorizing vector-matrix multiplication in the form of MPS-MPO contraction.

If the MPO is contracted with a MPSData, MPS nodes will become part of the MPO network, and they will be connected to the "input" edges of the MPO. Thus, the MPS and the MPO should have the same number of features (n_features).

Even though it is not necessary to connect the MPSData nodes to the MPO nodes by hand before contraction, it can be done. However, one should first move the MPS nodes to the MPO network.

Also, when contracting the MPO with and MPSData, if any of the contraction arguments, inline_input or inline_mats, is set to False, the MPO (already connected to the MPS) should be reset() before contraction if new data is set into the MPSData nodes. This is because MPSData admits data tensors with different bond dimensions for each iteration, and this may cause undesired behaviour when reusing some information of previous calls to :func:~tensorkrowch.stack` with the previous data tensors.

To perform the MPS-MPO contraction, first input data tensors have to be put into the MPSData via MPSData.add_data(). Then, contraction is carried out by calling mpo(mps=mps_data), without passing the input data again, as it is already stored in the MPSData nodes.

Parameters
  • inline_input (bool) – Boolean indicating whether input data nodes should be contracted with the MPO nodes inline (one contraction at a time) or in a single stacked contraction.

  • inline_mats (bool) – Boolean indicating whether the sequence of matrices (resultant after contracting the input data nodes) should be contracted inline or as a sequence of pairwise stacked contrations.

  • renormalize (bool) – Indicates whether nodes should be renormalized after contraction. If not, it may happen that the norm explodes or vanishes, as it is being accumulated from all nodes. Renormalization aims to avoid this undesired behavior by extracting the norm of each node on a logarithmic scale. The renormalization only occurs when multiplying sequences of matrices, once the input contractions have been already performed, including contracting against MPSData.

  • mps (MPSData, optional) – MPS that is to be contracted with the MPO. New data can be put into the MPS via MPSData.add_data(), and the MPS-MPO contraction is performed by calling mpo(mps=mps_data), without passing the input data again, as it is already stored in the MPS cores.

Return type

Node

canonicalize(oc=None, mode='svd', rank=None, cum_percentage=None, cutoff=None, renormalize=False)[source]#

Turns MPO into canonical form via local SVD/QR decompositions in the same way this transformation is applied to MPS.

To specify the new bond dimensions, the arguments rank, cum_percentage or cutoff can be specified. These will be used equally for all SVD computations.

If none of them are specified, the bond dimensions won’t be modified if possible. Only when the bond dimension is bigger than the physical dimension multiplied by the other bond dimension of the node, it will be cropped to that size.

If rank is not specified, the current bond dimensions will be used as the rank. That is, the current bond dimensions will be the upper bound for the possibly new bond dimensions given by the arguments cum_percentage and/or cutoff.

Parameters
  • oc (int) – Position of the orthogonality center. It should be between 0 and n_features - 1.

  • mode ({"svd", "svdr", "qr"}) – Indicates which decomposition should be used to split a node after contracting it. See more at svd_(), svdr_(), qr_(). If mode is “qr”, operation qr_() will be performed on nodes at the left of the output node, whilst operation rq_() will be used for nodes at the right.

  • rank (int, optional) – Number of singular values to keep.

  • cum_percentage (float, optional) –

    Proportion that should be satisfied between the sum of all singular values kept and the total sum of all singular values.

    \[\frac{\sum_{i \in \{kept\}}{s_i}}{\sum_{i \in \{all\}}{s_i}} \ge cum\_percentage\]

  • cutoff (float, optional) – Quantity that lower bounds singular values in order to be kept.

  • renormalize (bool) – Indicates whether nodes should be renormalized after SVD/QR decompositions. If not, it may happen that the norm explodes as it is being accumulated from all nodes. Renormalization aims to avoid this undesired behavior by extracting the norm of each node on a logarithmic scale after SVD/QR decompositions are computed. Finally, the normalization factor is evenly distributed among all nodes of the MPO.

Examples

>>> mpo = tk.models.MPO(n_features=4,
...                     in_dim=2,
...                     out_dim=2,
...                     bond_dim=5)
>>> mpo.canonicalize(rank=3)
>>> mpo.bond_dim
[3, 3, 3]

UMPO#

class tensorkrowch.models.UMPO(n_features=None, in_dim=None, out_dim=None, bond_dim=None, tensor=None, n_batches=1, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Class for Uniform (translationally invariant) Matrix Product Operators. It is the uniform version of MPO, that is, all nodes share the same tensor. Thus this class cannot have different input/output or bond dimensions for each node, and boundary conditions are always periodic ("pbc").


For a more detailed list of inherited properties and methods, check MPO.

Parameters
  • n_features (int) – Number of nodes that will be in mats_env.

  • in_dim (int, optional) – Input dimension.

  • out_dim (int, optional) – Output dimension.

  • bond_dim (int, optional) – Bond dimension.

  • tensor (torch.Tensor, optional) – Instead of providing in_dim, out_dim and bond_dim, a single tensor can be provided. n_features is still needed to specify how many times the tensor should be used to form a finite MPO. The tensor should be rank-4, with its first and third dimensions being equal.

  • n_batches (int) – Number of batch edges of input data nodes. Usually n_batches = 1 (where the batch edge is used for the data batched) but it could also be n_batches = 2 (one edge for data batched, other edge for image patches in convolutional layers).

  • init_method ({"zeros", "ones", "copy", "rand", "randn"}, optional) – Initialization method. Check initialize() for a more detailed explanation of the different initialization methods.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

Examples

>>> mpo = tk.models.UMPO(n_features=4,
...                      in_dim=2,
...                      out_dim=2,
...                      bond_dim=5)
>>> for node in mpo.mats_env:
...     assert node.tensor_address() == 'virtual_uniform'
...
>>> data = torch.ones(20, 4, 2) # batch_size x n_features x feature_size
>>> result = mpo(data)
>>> result.shape
torch.Size([20, 2, 2, 2, 2])
initialize(tensors=None, init_method='randn', device=None, dtype=None, **kwargs)[source]#

Initializes the common tensor of the UMPO. It can be called when instantiating the model, or to override the existing nodes’ tensors.

There are different methods to initialize the nodes:

  • {"zeros", "ones", "copy", "rand", "randn"}: The tensor is initialized calling set_tensor() with the given method, device, dtype and kwargs.

Parameters
  • tensors (list[torch.Tensor] or tuple[torch.Tensor], optional) – Sequence of a single tensor to set in each of the MPO nodes. The tensor should be rank-4, with its first and third dimensions being equal.

  • init_method ({"zeros", "ones", "copy", "rand", "randn"}, optional) – Initialization method.

  • device (torch.device, optional) – Device where to initialize the tensors if init_method is provided.

  • dtype (torch.dtype, optional) – Dtype of the tensor if init_method is provided.

  • kwargs (float) – Keyword arguments for the different initialization methods. See make_tensor().

copy(share_tensors=False)[source]#

Creates a copy of the UMPO.

Parameters

share_tensor (bool, optional) – Boolean indicating whether the common tensor in the copied UMPO should be set as the tensor in the current UMPO (True), or cloned (False). In the former case, the tensor in both UMPO’s will be the same, which might be useful if one needs more than one copy of a UMPO, but wants to compute all the gradients with respect to the same, unique, tensor.

Return type

UMPO

parameterize(set_param=True, override=False)[source]#

Parameterizes all nodes of the MPO. If there are resultant nodes in the MPO, it will be first reset().

Parameters
  • set_param (bool) – Boolean indicating whether the tensor network has to be parameterized (True) or de-parameterized (False).

  • override (bool) – Boolean indicating whether the tensor network should be parameterized in-place (True) or copied and then parameterized (False).

Tree#

Tree#

class tensorkrowch.models.Tree(sites_per_layer, bond_dim, n_batches=1)[source]#

Class for Tree States. These states form a tree structure where the data nodes are in the base. All nodes have a sequence of input edges and an output edge. Thus the contraction of the Tree returns a vector node.

All nodes in the network are in self.layers, a list containing the lists of nodes in each layer (starting from the bottom).

Parameters
  • sites_per_layer (list[int] or tuple[int]) – Number of sites in each layer of the tree. All nodes in the same layer have the same shape. Number of nodes in each layer times the number of input edges these have should match the number ot output edges in the previous layer. The last element of sites_per_layer should be always 1, which corresponds to the output node.

  • bond_dim (list[list[int]] or tuple[tuple[int]]) – Bond dimensions of nodes in each layer. Each sequence corresponds to the shape of the nodes in each layer, starting from the bottom (some input edges and an output edge in the last position).

  • n_batches (int) – Number of batch edges of input data nodes. Usually n_batches = 1 (where the batch edge is used for the data batched) but it could also be n_batches = 2 (one edge for data batched, other edge for image patches in convolutional layers).

Examples

>>> tree = tk.models.Tree(sites_per_layer=[4, 2, 1],
...                       bond_dim=[[3, 3, 4], [4, 4, 2], [2, 2, 2]])
>>> data = torch.ones(20, 8, 3) # batch_size x n_features x feature_size
>>> result = tree(data)
>>> result.shape
torch.Size([20, 2])
property sites_per_layer#

Returns number of sites in each layer of the tree.

property bond_dim#

Returns bond dimensions of nodes in each layer. Each sequence corresponds to the shape of the nodes in each layer (some input edges and an output edge in the last position).

It can have two forms:

  1. [shape_all_nodes_layer_1, ..., shape_all_nodes_layer_N]

  2. [[shape_node_1_layer_1, ..., shape_node_i1_layer_1], ..., [shape_node_1_layer_N, ..., shape_node_iN_layer_N]]

property n_batches#

Returns number of batch edges of the data nodes.

initialize(std=1e-09)[source]#

Initializes all the nodes.

set_data_nodes()[source]#

Creates data nodes and connects each of them to the physical edge of an input node.

contract(inline=False)[source]#

Contracts the whole Tree Tensor Network.

Parameters

inline (bool) – Boolean indicating whether consecutive layers should be contracted inline or in parallel (using a single stacked contraction).

Return type

Node

canonicalize(mode='svd', rank=None, cum_percentage=None, cutoff=None)[source]#

Turns Tree into canonical form via local SVD/QR decompositions, moving singular values matrices or non-isometries to the upper layers.

Parameters
  • mode ({"svd", "svdr", "qr"}) – Indicates which decomposition should be used to split a node after contracting it. See more at svd_(), svdr_(), qr_(). If mode is “qr”, operation qr_() will be performed on nodes at the left of the output node, whilst operation rq_() will be used for nodes at the right.

  • rank (int, optional) – Number of singular values to keep.

  • cum_percentage (float, optional) –

    Proportion that should be satisfied between the sum of all singular values kept and the total sum of all singular values.

    \[\frac{\sum_{i \in \{kept\}}{s_i}}{\sum_{i \in \{all\}}{s_i}} \ge cum\_percentage\]

  • cutoff (float, optional) – Quantity that lower bounds singular values in order to be kept.

Examples

>>> tree = tk.models.Tree(sites_per_layer=[4, 2, 1],
...                       bond_dim=[[3, 3, 4], [4, 4, 2], [2, 2, 2]])
>>> tree.canonicalize(rank=2)
>>> tree.bond_dim
[[[3, 3, 2], [3, 3, 2], [3, 3, 2], [3, 3, 2]], [[2, 2, 2], [2, 2, 2]], [[2, 2, 2]]]

UTree#

class tensorkrowch.models.UTree(sites_per_layer, bond_dim, n_batches=1)[source]#

Class for Uniform Tree States where all nodes have the same shape. It is the uniform version of Tree, that is, all nodes share the same tensor.

All nodes in the network are in self.layers, a list containing the lists of nodes in each layer (starting from the bottom).

Parameters
  • sites_per_layer (list[int] or tuple[int]) – Number of sites in each layer of the tree. All nodes have the same shape. Number of nodes in each layer times the number of input edges these have should match the number ot output edges in the previous layer. The last element of sites_per_layer should be always 1, which corresponds to the output node.

  • bond_dim (list[int] or tuple[int]) – Bond dimensions of nodes in each layer. Since all nodes have the same shape, it is enough to pass a single sequence of dimensions (some input edges and an output edge in the last position).

  • n_batches (int) – Number of batch edges of input data nodes. Usually n_batches = 1 (where the batch edge is used for the data batched) but it could also be n_batches = 2 (one edge for data batched, other edge for image patches in convolutional layers).

Examples

>>> tree = tk.models.UTree(sites_per_layer=[4, 2, 1],
...                        bond_dim=[3, 3, 3])
>>> for layer in tree.layers:
...     for node in layer:
...         assert node.tensor_address() == 'virtual_uniform'
...
>>> data = torch.ones(20, 8, 3) # batch_size x n_features x feature_size
>>> result = tree(data)
>>> result.shape
torch.Size([20, 3])
property sites_per_layer#

Returns number of sites in each layer of the tree.

property bond_dim#

Returns bond dimensions of nodes in each layer. Since all nodes have the same shape, it is a single sequence of dimensions (some input edges and an output edge in the last position).

property n_batches#

Returns number of batch edges of the data nodes.

initialize(std=1e-09)[source]#

Initializes all the nodes.

set_data_nodes()[source]#

Creates data nodes and connects each of them to the physical edge of an input node.

contract(inline=False)[source]#

Contracts the whole Tree Tensor Network.

Parameters

inline (bool) – Boolean indicating whether consecutive layers should be contracted inline or in parallel (using a single stacked contraction).

Return type

Node

ConvTree#

class tensorkrowch.models.ConvTree(sites_per_layer, bond_dim, kernel_size, stride=1, padding=0, dilation=1)[source]#

Class for Tree States where the input data is a batch of images. It is the convolutional version of Tree.

Input data as well as initialization parameters are described in torch.nn.Conv2d.

Parameters
  • sites_per_layer (list[int] or tuple[int]) – Number of sites in each layer of the tree. All nodes in the same layer have the same shape. Number of nodes in each layer times the number of input edges these have should match the number ot output edges in the previous layer.

  • bond_dim (list[list[int]] or tuple[tuple[int]]) – Bond dimensions of nodes in each layer. Each sequence corresponds to the shape of the nodes in each layer (some input edges and an output edge in the last position).

  • kernel_size (int, list[int] or tuple[int]) –

    Kernel size used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • stride (int) –

    Stride used in torch.nn.Unfold.

  • padding (int) –

    Padding used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • dilation (int) –

    Dilation used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

Examples

>>> conv_tree = tk.models.ConvTree(sites_per_layer=[2, 1],
...                                bond_dim=[[2, 2, 3], [3, 3, 5]],
...                                kernel_size=2)
>>> data = torch.ones(20, 2, 2, 2) # batch_size x in_channels x height x width
>>> result = conv_tree(data)
>>> print(result.shape)
torch.Size([20, 5, 1, 1])
property in_channels#

Returns in_channels. Same as the first elements in bond_dim from Tree, corresponding to dimensions of the input.

property kernel_size#

Returns kernel_size, corresponding to number of data nodes.

property stride#

Returns stride used in torch.nn.Unfold.

property padding#

Returns padding used in torch.nn.Unfold.

property dilation#

Returns dilation used in torch.nn.Unfold.

forward(image, *args, **kwargs)[source]#

Overrides torch.nn.Module’s forward to compute a convolution on the input image.

Parameters
  • image (torch.Tensor) –

    Input batch of images with shape

    \[batch\_size \times in\_channels \times height \times width\]

  • args – Arguments that might be used in contract().

  • kwargs – Keyword arguments that might be used in contract(), like inline.

ConvUTree#

class tensorkrowch.models.ConvUTree(sites_per_layer, bond_dim, kernel_size, stride=1, padding=0, dilation=1)[source]#

Class for Uniform Tree States where the input data is a batch of images. It is the convolutional version of UTree.

Input data as well as initialization parameters are described in torch.nn.Conv2d.

Parameters
  • sites_per_layer (list[int] or tuple[int]) – Number of sites in each layer of the tree. All nodes have the same shape. Number of nodes in each layer times the number of input edges these have should match the number ot output edges in the previous layer.

  • bond_dim (list[int] or tuple[int]) – Bond dimensions of nodes in each layer. Since all nodes have the same shape, it is enough to pass a single sequence of dimensions (some input edges and an output edge in the last position).

  • kernel_size (int, list[int] or tuple[int]) –

    Kernel size used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • stride (int) –

    Stride used in torch.nn.Unfold.

  • padding (int) –

    Padding used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • dilation (int) –

    Dilation used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

Examples

>>> conv_tree = tk.models.ConvUTree(sites_per_layer=[2, 1],
...                                 bond_dim=[2, 2, 2],
...                                 kernel_size=2)
>>> for layer in conv_tree.layers:
...     for node in layer:
...         assert node.tensor_address() == 'virtual_uniform'
...
>>> data = torch.ones(20, 2, 2, 2) # batch_size x in_channels x height x width
>>> result = conv_tree(data)
>>> print(result.shape)
torch.Size([20, 2, 1, 1])
property in_channels#

Returns in_channels. Same as the first elements in bond_dim from UTree, corresponding to dimensions of the input.

property kernel_size#

Returns kernel_size, corresponding to number of data nodes.

property stride#

Returns stride used in torch.nn.Unfold.

property padding#

Returns padding used in torch.nn.Unfold.

property dilation#

Returns dilation used in torch.nn.Unfold.

forward(image, *args, **kwargs)[source]#

Overrides torch.nn.Module’s forward to compute a convolution on the input image.

Parameters
  • image (torch.Tensor) –

    Input batch of images with shape

    \[batch\_size \times in\_channels \times height \times width\]

  • args – Arguments that might be used in contract().

  • kwargs – Keyword arguments that might be used in contract(), like inline.

PEPS#

PEPS#

class tensorkrowch.models.PEPS(n_rows, n_cols, in_dim, bond_dim, boundary=['obc', 'obc'], n_batches=1)[source]#

Class for Projected Entangled Pair States, where all nodes are input nodes, that is, they are all connected to data nodes that will store the input data tensor(s). When contracting the PEPS with new input data, the result will be a just a number.

A PEPS is formed by the following nodes:

  • left_up_corner, left_down_corner, right_up_corner, right_down_corner: Corner nodes with 3 edges, the one corresponding to the input and 2 connected to the borders.

  • left_border, right_border, up_border, down_border: Border nodes with 4 edges, the one corresponding to the input, 2 connected to the neighbours in the border, and 1 connected to the interior of the grid.

  • grid_env: Grid environment of nodes with 5 edges, (“input”, “left”, “right”, “up”, “down”). Is is a list of lists of nodes.

Parameters
  • n_rows (int) – Number of rows of the 2D grid.

  • n_cols (int) – Number of columns of the 2D grid.

  • in_dim (int) – Input dimension. Equivalent to the physical dimension.

  • bond_dim (list[int] or tuple[int]) – Bond dimensions for horizontal and vertical edges (in that order). Thus it should contain 2 elements.

  • boundary (list[{"obc", "pbc"}]) – List of strings indicating whether periodic or open boundary conditions should be used in the horizontal (up and down) and vertical (left and right) boundaries.

  • n_batches (int) – Number of batch edges of input data nodes. Usually n_batches = 1 (where the batch edge is used for the data batched) but it could also be n_batches = 2 (one edge for data batched, other edge for image patches in convolutional layers).

Examples

>>> peps = tk.models.PEPS(n_rows=2,
...                       n_cols=2,
...                       in_dim=3,
...                       bond_dim=[5, 5])
>>> data = torch.ones(20, 4, 3) # batch_size x n_features x feature_size
>>> result = peps(data)
>>> result.shape
torch.Size([20])
property n_rows#

Returns number of rows of the 2D grid.

property n_cols#

Returns number of columns of the 2D grid.

property boundary#

Returns boundary conditions in the horizontal (up and down) and vertical (left and right) boundaries.

property in_dim#

Returns input/physical dimension.

property bond_dim#

Returns bond dimensions for horizontal and vertical edges.

property n_batches#

Returns number of batch edges of the data nodes.

initialize(std=1e-09)[source]#

Initializes all the nodes.

set_data_nodes()[source]#

Creates data nodes and connects each of them to the physical edge of an input node.

contract(from_side='up', max_bond=32, inline=False)[source]#

Contracts the whole PEPS.

Parameters
  • from_side ({"up", "down", "left", "right"}) – Indicates from which side of the 2D grid the contraction algorithm should start.

  • max_bond (int) – The maximum allowed bond dimension. If, when contracting consecutive lines (rows or columns) of the PEPS this bond dimension is exceeded, the bond dimension is reduced using singular value decomposition (see split()).

  • inline (bool) – Boolean indicating whether consecutive lines should be contracted inline or in parallel (using a single stacked contraction).

Return type

Node

UPEPS#

class tensorkrowch.models.UPEPS(n_rows, n_cols, in_dim, bond_dim, n_batches=1)[source]#

Class for Uniform (translationally invariant) Projected Entangled Pair States, where all nodes are input nodes. It is the uniform version of PEPS, that is, all nodes share the same tensor. Thus boundary conditions are always periodic.

A UPEPS is formed by the following nodes:

  • grid_env: Grid environment of nodes with 5 edges, (“input”, “left”, “right”, “up”, “down”). Is is a list of lists of nodes.

Parameters
  • n_rows (int) – Number of rows of the 2D grid.

  • n_cols (int) – Number of columns of the 2D grid

  • in_dim (int) – Input dimension. Equivalent to the physical dimension.

  • bond_dim (list[int] or tuple[int]) – Bond dimensions for horizontal and vertical edges (in that order). Thus it should also contain 2 elements

  • n_batches (int) – Number of batch edges of input data nodes. Usually n_batches = 1 (where the batch edge is used for the data batched) but it could also be nu_batches = 2 (one edge for data batched, other edge for image patches in convolutional layers).

Examples

>>> peps = tk.models.PEPS(n_rows=2,
...                       n_cols=2,
...                       in_dim=3,
...                       bond_dim=[5, 5])
>>> for node in peps.grid_env:
...     assert node.tensor_address() == 'virtual_uniform'
...
>>> data = torch.ones(20, 4, 3) # batch_size x n_features x feature_size
>>> result = peps(data)
>>> result.shape
torch.Size([20])
property n_rows#

Returns number of rows of the 2D grid.

property n_cols#

Returns number of columns of the 2D grid.

property in_dim#

Returns input/physical dimension.

property bond_dim#

Returns bond dimensions for horizontal and vertical edges.

property n_batches#

Returns number of batch edges of the data nodes.

initialize(std=1e-09)[source]#

Initializes all the nodes.

set_data_nodes()[source]#

Creates data nodes and connects each of them to the physical edge of an input node.

contract(from_side='up', max_bond=32, inline=False)[source]#

Contracts the whole PEPS.

Parameters
  • from_side ({"up", "down", "left", "right"}) – Indicates from which side of the 2D grid the contraction algorithm should start.

  • max_bond (int) – The maximum allowed bond dimension. If, when contracting consecutive lines (rows or columns) of the PEPS this bond dimension is exceeded, the bond dimension is reduced using singular value decomposition (see split()).

  • inline (bool) – Boolean indicating whether consecutive lines should be contracted inline or in parallel (using a single stacked contraction).

Return type

Node

ConvPEPS#

class tensorkrowch.models.ConvPEPS(in_channels, bond_dim, kernel_size, stride=1, padding=0, dilation=1, boundary=['obc', 'obc'])[source]#

Class for Projected Entangled Pair States, where all nodes are input nodes, and where the input data is a batch of images. It is the convolutional version of PEPS.

Input data as well as initialization parameters are described in torch.nn.Conv2d.

Parameters
  • in_channels (int) – Input channels. Same as in_dim in PEPS.

  • bond_dim (list[int] or tuple[int]) – Bond dimensions for horizontal and vertical edges (in that order). Thus it should also contain 2 elements

  • kernel_size (int, list[int] or tuple[int]) –

    Kernel size used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • stride (int) –

    Stride used in torch.nn.Unfold.

  • padding (int) –

    Padding used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • dilation (int) –

    Dilation used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • boundary (list[{"obc", "pbc"}]) – List of strings indicating whether periodic or open boundary conditions should be used in the horizontal (up and down) and vertical (left and right) boundaries.

Examples

>>> conv_peps = tk.models.ConvPEPS(in_channels=2,
...                                bond_dim=[5, 5],
...                                kernel_size=2)
>>> data = torch.ones(20, 2, 2, 2) # batch_size x in_channels x height x width
>>> result = conv_peps(data)
>>> result.shape
torch.Size([20, 1, 1])
property in_channels#

Returns in_channels. Same as in_dim in PEPS.

property kernel_size#

Returns kernel_size. Number of rows and columns in the 2D grid is given by \(kernel\_size_0\) and \(kernel\_size_1\), respectively.

property stride#

Returns stride used in torch.nn.Unfold.

property padding#

Returns padding used in torch.nn.Unfold.

property dilation#

Returns dilation used in torch.nn.Unfold.

forward(image, *args, **kwargs)[source]#

Overrides torch.nn.Module’s forward to compute a convolution on the input image.

Parameters
  • image (torch.Tensor) –

    Input batch of images with shape

    \[batch\_size \times in\_channels \times height \times width\]

  • args – Arguments that might be used in contract().

  • kwargs – Keyword arguments that might be used in contract(), like from_size, max_bond or inline.

ConvUPEPS#

class tensorkrowch.models.ConvUPEPS(in_channels, bond_dim, kernel_size, stride=1, padding=0, dilation=1)[source]#

Class for Uniform Projected Entangled Pair States, where all nodes are input nodes, and where the input data is a batch of images. It is the convolutional version of UPEPS.

Input data as well as initialization parameters are described in torch.nn.Conv2d.

Parameters
  • in_channels (int) – Input channels. Same as in_dim in UPEPS.

  • bond_dim (list[int] or tuple[int]) – Bond dimensions for horizontal and vertical edges (in that order). Thus it should also contain 2 elements

  • kernel_size (int, list[int] or tuple[int]) –

    Kernel size used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • stride (int) –

    Stride used in torch.nn.Unfold.

  • padding (int) –

    Padding used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

  • dilation (int) –

    Dilation used in torch.nn.Unfold. If given as an int, the actual kernel size will be (kernel_size, kernel_size).

Examples

>>> conv_peps = tk.models.ConvPEPS(in_channels=2,
...                                bond_dim=[5, 5],
...                                kernel_size=2)
>>> for node in conv_peps.grid_env:
...     assert node.tensor_address() == 'virtual_uniform'
...
>>> data = torch.ones(20, 2, 2, 2) # batch_size x in_channels x height x width
>>> result = conv_peps(data)
>>> result.shape
torch.Size([20, 1, 1])
property in_channels#

Returns in_channels. Same as in_dim in UPEPS.

property kernel_size#

Returns kernel_size. Number of rows and columns in the 2D grid is given by \(kernel\_size_0\) and \(kernel\_size_1\), respectively.

property stride#

Returns stride used in torch.nn.Unfold.

property padding#

Returns padding used in torch.nn.Unfold.

property dilation#

Returns dilation used in torch.nn.Unfold.

forward(image, *args, **kwargs)[source]#

Overrides torch.nn.Module’s forward to compute a convolution on the input image.

Parameters
  • image (torch.Tensor) –

    Input batch of images with shape

    \[batch\_size \times in\_channels \times height \times width\]

  • args – Arguments that might be used in contract().

  • kwargs – Keyword arguments that might be used in contract(), like from_size, max_bond or inline.