Tensor Network Theory Library
Beta release 1.0
A library of routines for performing TNTbased operations

Typedefs  
typedef struct tnode *  tntNode 
Functions  
tntNode  tntNodeContract (tntNode tnA, tntNode tnB, int *legMapAC, int *legMapBC) 
void  tntNodePrintInfo (tntNode tn) 
void  tntNodePrintAll (tntNode tn) 
tntNode  tntNodeSVD (tntNode tn, int *startLegs, unsigned startNum, int legUS, int legSU, int *legMap, int connDim, double *err) 
tntNode  tntNodeCreateEyeOp (tntNode tn) 
void  tntNodePrepContract (tntNode tnA, tntNode tnB) 
void  tntNodeAdd (tntNode tnA, tntNode tnB) 
void  tntNodeAddLeg (tntNode tn, unsigned leglabel) 
void  tntNodeFree (tntNode *tn) 
tntNode  tntNodeFindConn (tntNode tn, unsigned legA) 
void  tntNodeJoin (tntNode tnA, int legA, tntNode tnB, int legB) 
tntNode  tntNodeCopy (tntNode tn, int conj) 
tntNode  tntNodeCreate (tntComplexArray *nodeVals, unsigned numLegs, unsigned legId[], unsigned legDim[]) 
void  tntNodeScaleReal (tntNode tn, double val) 
void  tntNodeScaleComplex (tntNode tn, tntComplex val) 
tntNode  tntNodeFindFirst (tntNetwork tnw) 
tntNode  tntNodeFindLast (tntNetwork tnw) 
void  tntNodeMapLegs (tntNode tn, unsigned legmap[]) 
void  tntNodeReplace (tntNode tnA, tntNode tnB) 
void  tntNodeSplit (tntNode tnA, tntNode tnB) 
tntComplex  tntNodeGetFirstEl (tntNode tn) 
tntComplex  tntNodeGetTrace (tntNode tn, unsigned dimNum, int *legs, unsigned dimNumB, int *legsB) 
tntComplexArray  tntNodeGetDiag (tntNode tn, unsigned dimNum, int *legs, unsigned dimNumB, int *legsB) 
void  tntNodeExp (tntNode tn, tntComplex sc_val, unsigned dimNum, int *legs, unsigned dimNumB, int *legsB) 
void  tntNodeInsert (tntNode tnI, int legIA, int legIB, tntNode tnA, int legA, tntNode tnB, int legB) 
void  tntNodeInsertAtStart (tntNode tnI, int legInwstart, int legIfirst, tntNetwork tnw) 
void  tntNodeInsertAtEnd (tntNode tnI, int legIlast, int legInwend, tntNetwork tnw) 
void  tntNodeSetRealParam (tntNode tn, double pval, unsigned pnum) 
void  tntNodeSetCompParam (tntNode tn, tntComplex pval, unsigned pnum) 
void  tntNodeSqueeze (tntNode tn, unsigned squeezeNum, unsigned *squeezeLegs) 
void  tntNodeGroupFree (tntNode *tn) 
unsigned  tntNodeGetLegDim (tntNode tn, unsigned legid) 
unsigned  tntNodeIsFunctional (tntNode tn) 
unsigned  tntNodeIsCovariant (tntNode tn) 
void  tntNodeInverseFact (tntNode tn, unsigned legid) 
void  tntNodeRemove (tntNode tn, int *leg_conn) 
void  tntNodeSetQN (tntNode tn, unsigned legid, tntIntArray *qvals, int legdir) 
void  tntNodeSetQN_nowarn (tntNode tn, unsigned legid, tntIntArray *qvals, int legdir) 
tntIntArray  tntNodeGetQN (tntNode tn, unsigned legid) 
void  tntNodeMakeCovariantQN (tntNode tn) 
This section contains functions and properties that are concerned with nodes, where the nodes can either be part of a network, or can be isolated from any network.
Use this type for defining a node in the network.
The nodes are connected to one another by their legs, where the connections between nodes in the network can be defined by the initialisation file, or by manipulating them using the provided node functions. Each leg has an associated label or or leg id, which is a positive integer. It is defined when the node is created and used to identify that leg. Since the label is used to identify a given leg, obviously it is not possible to use the same leg label for multiple legs on a given node.
Each node will have associated with it a tensor with the number of indices equal to the number of legs. These will be automatically kept track of during manipulation of the nodes  users only need to keep track of leg labels. The library supports two type of nodes
Adds the elements of the node tnB
to tnA
. The result is returned in tnA
(so a copy of tnA
should be made beforehand if it is required for further operations) and tnB
is unchanged. The connections of tnA
and tnB
are unchanged. This function will return an error if tnA
and tnB
do not have the same structure i.e. if the number of legs, dimensions of the legs, and the types of legs are not the same for the two tnodes.
tnA  The first node to add and that will contain the result of the addition 
tnB  the tnode to be added to the node tnA . This is not changed function, unless it is of the functional type in which case function is evaluated) 
void tntNodeAddLeg  (  tntNode  tn, 
unsigned  leglabel  
) 
Adds a leg with singleton dimension, and the leg label given in the arguments, to a node. The leg label most not be the same as any of the labels for the existing legs.
tn  The first node to add and that will contain the result of the addition. 
leglabel  The id of the leg to add. 
Contracts node tnA
with node tnB
on all connecting legs and returns the result in a new node tnC
. Leg maps are required to specify how the leg labels of the starting nodes relate to the leg labels of the final node  the final node should have no repeated leg numbers. If none of the leg labels change then NULL can be used instead of passing a leg map. This function destroys the incoming nodes, so if they are required for later operations a copy should first be made using tntNodeCopy().
If the nodes are not connected to one another, then it is assumed that there is a singleton leg connecting the two nodes which are contracted with each other. This means that the resulting node tnC will have all the legs of tnA and all the legs of tnB.
tnA  The first node to be contracted 
tnB  The second node to be contracted 
legMapAC  How the legs in node A map to the legs in node C. If NULL, it is assumed all legs map onto the same leg number. 
legMapBC  How the legs in node B map to the legs in node C. If NULL, it is assumed all legs map onto the same leg number. 
Makes a copy of the original node. Any parameters that belong to the original node will also be copied to the new node. Sets the tensors that correspond to the node to be the complex conjugate of the orignial node if the flag is given. The legs of the new node will not be connected to anything.
Note that if quantum number information is being used to preserve symmetries, then setting conj = 1
will also act to flip the directions of all the quantum number information for each leg.
tn  The node to take a copy of. 
conj  Conjugate flag: set this to zero if the copy of the node should have the same form as the original node, and set this to 1 if the tensor values associated with the copy of the node should be the complex conjugate of those for the original node. 
tntNode tntNodeCreate  (  tntComplexArray *  nodeVals, 
unsigned  numLegs,  
unsigned  legId[],  
unsigned  legDim[]  
) 
Creates a new static tnode, using the values given in the 1D complex array nodevals. (Note: although the input array is complex, if all the imaginary values have magnitude less that 1e14, then the node will be defined as real).
The number of legs should be given, as well of the dimension of each leg, and the label that should be assigned to each leg. The legs should be order such that the one with the fastest running index in the supplied array comes first. e.g. if there are three legs have respective indices \(i,j,k\) with dimensions \(d_i,d_j,d_k\), the then index in the suplied 1D array should be \( i + d_i j + d_i d_j k \). (Note: If there are two dimensions, rows then columns, this is equivalent to columnmajor order which is the default in MATLAB and Fortran).
The size of the array must be \(d_i d_j d_k\).
The values are copied from nodevals
, so if the array is no longer required it should be freed afterwards using tntComplexArrayFree().
nodeVals  The values for the node. If NULL, node will be filled with random values. Unchanged by the function. 
numLegs  The number of legs to assign to the node. Unchanged by the function. 
legId  The id or numbering for each leg. Unchanged by the function. 
legDim  The dimension of each leg. Unchanged by the function. 
Returns the operator which defines the identity node with the same leg properties as the node passed as an argument i.e
If NULL is passed as an argument, then the basis operator is used to define the leg properties instead. The basis operator can be set using tntSysBasisOpSet() and inspected using tntSysBasisOpGet(). If it has not been set yet calling this function with NULL as an argument will result in an error.
tn  Node to define leg properties of identity node. Pass NULL to use the system basis operator 
void tntNodeExp  (  tntNode  tn, 
tntComplex  sc_val,  
unsigned  dimNum,  
int *  legs,  
unsigned  dimNumB,  
int *  legsB  
) 
Takes the matrix exponential of the node given, where the node can first be scaled by the complex number sc_val
. The legs assigned to each dimension of the matrix are given as arguments, where the ordering of the legs is important.
The resulting matrix must be square, and if not the function exits with an error.
The input node is changed by the function (i.e. the result is placed in the original node), so a copy should be made first if it will be required later.
tn  Node to take the exponential of. 
sc_val  Number to scale node by before taking exponential. 
dimNum  The number of legs that make up one of the dimensions of the matrix. 
legs  An array listing legs that make up that dimension of the matrix. 
dimNumB  The number of legs that make up the other dimension of the matrix. 
legsB  An array listing legs that make up the other dimension of the matrix. 
Finds the node that is connected to legA
of the node tn
that is passed as an argument. It will return NULL if there is nothing connected to this leg.
tn
by the leg stated. tn  The node to find the connection of 
legA  The leg of the node tn to find the connection of 
tntNode tntNodeFindFirst  (  tntNetwork  tnw  ) 
Identifies the first node in the network. Note that the first node in the network is defined when the network is first loaded.
tnw  The current network. 
tntNode tntNodeFindLast  (  tntNetwork  tnw  ) 
Identifies the last node in the network. Note that the last node in the network is defined when the network is first loaded.
tnw  The current network. 
void tntNodeFree  (  tntNode *  tn  ) 
Frees all memory associated with the node. After calling the function the node tn
will be NULL  it will no longer be valid and should not be used again.
tn  Pointer to the node to free 
tntComplexArray tntNodeGetDiag  (  tntNode  tn, 
unsigned  dimNum,  
int *  legs,  
unsigned  dimNumB,  
int *  legsB  
) 
Gets the diagonal elements of a matrix formed by reshaping the tensor corresponding to the node tn
. The legs that are assigned to each of the dimensions of the matrix are given as arguments, where the ordering of the legs is important. The resulting matrix must be square, and if it is not the function exits with an error. The values returned are in complex format even if the tensor values are purely real. The diagonal values are returned in an array of type tntComplexArray. The element vals
of this structure is allocated dynamically, so it should be freed after use.
tn
. tn  Node to get the trace of 
dimNum  The number of legs that make up one of the dimensions of the matrix 
legs  An array listing legs that make up that dimension of the matrix 
dimNumB  The number of legs that make up the other dimension of the matrix 
legsB  An array listing legs that make up the other dimension of the matrix 
tntComplex tntNodeGetFirstEl  (  tntNode  tn  ) 
Gets the first element in the tensor corresponding to the node tn
. The value returned is in complex format even if the tensor values are purely real.
tn
. tn  The node to get the first element of. 
unsigned tntNodeGetLegDim  (  tntNode  tn, 
unsigned  legid  
) 
Returns the dimension of the specified leg of a node. If the leg does not exist an error will result.
tn  The relevant node 
legid  The id of the leg to get the dimension of 
tntIntArray tntNodeGetQN  (  tntNode  tn, 
unsigned  legid  
) 
Gets quantum number information of the given leg of a node, returning the information in an integer array. If there are no quantum numbers set simply returns an empty array of length zero.
tn  Node to get quantum number information from 
legid  Leg to get quantum number information from 
tntComplex tntNodeGetTrace  (  tntNode  tn, 
unsigned  dimNum,  
int *  legs,  
unsigned  dimNumB,  
int *  legsB  
) 
Gets the trace of a matrix formed by reshaping the tensor corresponding to the node tn
. The legs that are assigned to each of the dimensions of the matrix are given as arguments, where the ordering of the legs is important. The resulting matrix must be square, and if it is not the function exits with an error. The value returned is in complex format even if the tensor values are purely real.
tn
. tn  Node to get the trace of 
dimNum  The number of legs that make up one of the dimensions of the matrix 
legs  An array listing legs that make up that dimension of the matrix 
dimNumB  The number of legs that make up the other dimension of the matrix 
legsB  An array listing legs that make up the other dimension of the matrix 
void tntNodeGroupFree  (  tntNode *  tn  ) 
Deletes a group of nodes i.e. frees the tnode passed as an argument, and all the nodes connected to it. After calling the function the node pointer wil be NULL.
tn  Pointer to one of the nodes in the group of nodes to free. 
void tntNodeInsert  (  tntNode  tnI, 
int  legIA,  
int  legIB,  
tntNode  tnA,  
int  legA,  
tntNode  tnB,  
int  legB  
) 
Inserts a node tnI
between node tnA
and node tnB
, where node tnA
and node tnB
are already connected to each other.
tnI  The node to insert 
legIA  The leg of tnI that will connect to tnA 
legIB  the leg of tnI that will connect to tnB 
tnA  The node tnA 
legA  the leg of tnA that will connect to tnI 
tnB  The node tnB 
legB  the leg of tnB that will connect to tnI 
void tntNodeInsertAtEnd  (  tntNode  tnI, 
int  legIlast,  
int  legInwend,  
tntNetwork  tnw  
) 
Inserts a node tnI
at the end of the network tnw
tnI  The node to insert 
legIlast  the leg of tnI that will connect to what was previously connected to the end of the network 
legInwend  The leg of tnI that will connect to the end of the network 
tnw  The network that the node will be inserted in 
void tntNodeInsertAtStart  (  tntNode  tnI, 
int  legInwstart,  
int  legIfirst,  
tntNetwork  tnw  
) 
Inserts a node tnI
at the beginning of the network tnw
tnI  The node to insert 
legInwstart  The leg of tnI that will connect to the start of the network 
legIfirst  the leg of tnI that will connect to what was previously connected to the start of the network 
tnw  The network that the node will be inserted in 
void tntNodeInverseFact  (  tntNode  tn, 
unsigned  legid  
) 
This `factorises' a tensor into the tensor, connected to it's inverse, connected to the original tensor. The original tensors is replaced by these three tensors, putting them in the network if `tn' already has conections. This only makes sense for tensors with two legs  any other leg numbers will result in an error. If the original tensor is a functional tensor, the inverse will be a static tensor but the original tensor will still be functional tensors with parameters that can be changed.
tn  The node to find the inverse of 
legid  The leg of that node to connect the inverse and original nodes to. 
unsigned tntNodeIsCovariant  (  tntNode  tn  ) 
Checks whether the node is covariant under the system type set i.e. whether quantum numbers have been assigned to all the indices, and whether the elements are being stored in blocked form.
tn  The node to check 
unsigned tntNodeIsFunctional  (  tntNode  tn  ) 
Checks whether the node is a functional node or a static node.
tn  The node to check 
Joins legA
of node tnA
to legB
of node tnB
. This function should only be used if legA
and legB
are currently not connected to anything. If they are already connected to something the program will exit with an error.
tnA  The first node to join 
legA  The leg of the first node to join to the second node 
tnB  The second node to join 
legB  The leg of the second node to joing to the first node 
void tntNodeMakeCovariantQN  (  tntNode  tn  ) 
Requires as an input a node with quantum numbers set on all indices apart from a singleton leg. The function then sets the quantum number label for the singleton leg such that at least one nonzero block sized block is formed. If the tensor is covariant there is one quantum number label for which no tensor elements are discarded. Note that if the tensor is not convariant, there is no choice of quantum number label for the singleton leg that will result in all tensor elements being kept, so some information will be discarded. If the node is not in the correct form calling this function will stop execution and print an error.
tn  Node to get resultant quantum number from 
void tntNodeMapLegs  (  tntNode  tn, 
unsigned  legmap[]  
) 
Changes the labels of the legs of node tn
using the leg map. The function will cause leg with id i
to have id legmap[i]
.
tn  Node to change leg ids of 
legmap  Map for the new leg numbers, such that legmap[old_id] = new_id 
This is a `mock' contract of node tnA
and tnB
. It performs all the operations on tnA
and tnB
that are performed before a normal contraction but does not contract the resulting nodes together, does not create a new node tnC
, and does not free tnA
and tnB
. tnA
and tnB
can then be used again for the same contraction without these preparatory steps being required. This can significantly reduce the run time if the same contraction is repeated many times with one of the nodes tnA
or tnB
.
tnA  The first node to be contracted 
tnB  The second node to be contracted 
void tntNodePrintAll  (  tntNode  tn  ) 
Prints information about a node as well as all the values in the blocks if it is a symmetric node.
tn  The node to print. 
void tntNodePrintInfo  (  tntNode  tn  ) 
Prints information about a node.
tn  The node to print information for. 
void tntNodeRemove  (  tntNode  tn, 
int *  leg_conn  
) 
Removes a node from the network, setting all the connections on that node to NULL.
The second argument leg_conn, indicates what to do with the connections of surrounding nodes in the network. If all the entries are 1, then these connections will also be set to NULL. Otherwise, they indicate which of the surrounding nodes to connect to one another by means of the leg_ids they were connected to on tn
i.e. if leg_conn = {0,2,1,1)
this means that the tnode that was connected to leg 2 should be connected to the tnode that was connected to leg 1, and the node that was connected to leg 3 should have that leg disconnected. If leg_conn[i] == j
but leg_conn[j] != i
, then the connection information is inconsistent, and an error will result.
tn  The node to remove. 
leg_conn  Determines how nodes which were connected to tn (identified by the leg of tn they are connected to) will connect to one another after it has been removed 
Takes all nodes connected to tnA
and connects them to tnB
instead, i.e. replaces tnA
in a network with tnB
. This function requires that tnA
and tnB
have the same number of legs, and the same leg labels. It also requires that tnB
is not currently connected to anything. When replacing connections, the node that was previously connected to the leg with a given number label on tnA
then connects to the leg with the same label on tnB
.
tnA  Original node in network to be replaced 
tnB  Node to replace the original node with 
void tntNodeScaleComplex  (  tntNode  tn, 
tntComplex  val  
) 
Scales a node by the complex value given. If the node was previously a functional node, it will now be a static node. The connections on the node are unchanged by the operation.
tn  The node to scale 
val  The value to scale it by 
void tntNodeScaleReal  (  tntNode  tn, 
double  val  
) 
Sacles a node by the real value given. If the node was previously a functional node, it will now be a static node. The connections on the node are unchanged by the operation.
tn  The node to scale 
val  The value to scale it by 
void tntNodeSetCompParam  (  tntNode  tn, 
tntComplex  pval,  
unsigned  pnum  
) 
Sets real parameters for functional nodes. If there are multiple parameters, this function should be called once for each parameter. These parameters will then be used to generate the tensor using the operators and linked function set when the node was first created. Trying to set a parameter for a node that is not a functional node will cause an error.
tn  The node to set the parameter for 
pval  The value to set for the parameter 
pnum  Index specifying which parameter should be set, where the index counts from zero. 
void tntNodeSetQN  (  tntNode  tn, 
unsigned  legid,  
tntIntArray *  qvals,  
int  legdir  
) 
Sets quantum number information to the given leg of a node. The number of quantum number labels required is symm_num_qn
multiplied by the dimension of the specified leg, where symm_num_qn
is the number of quantum numbers required for each quantum number label. The values should be provided in an integer array of at least this length, where only the first symm_num_qn*legdim
values are used. Note if all quantum numbers are required to be zero, then NULL can be used instead of sending an array containing zeros.
Once quantum number information has been set to all the legs, the node will automatically be converted to symmetric blocktype form. If this conversion results in values being lost, a warning will be printed.
tn  Node to set quantum number information to 
legid  Leg to set quantum number information to 
qvals  An array containing the quantum number labels. Send NULL to set all QN to zero. 
legdir  The direction of the leg: incoming legs should be 1, outgoing legs +1. The direction indicates whether the qn's on the index add or subtract to the total number of the state 
void tntNodeSetQN_nowarn  (  tntNode  tn, 
unsigned  legid,  
tntIntArray *  qvals,  
int  legdir  
) 
This function is identical to tntNodeSetQN() however will not print a warning if information is discarded on changing to a covariant node. Use this is if you know information will be discarded e.g. when putting random blocks in covariant form.
tn  Node to set quantum number information to 
legid  Leg to set quantum number information to 
qvals  An array containing the quantum number labels. Send NULL to set all QN to zero. 
legdir  The direction of the leg: incoming legs should be 1, outgoing legs +1. The direction indicates whether the qn's on the index add or subtract to the total number of the state 
void tntNodeSetRealParam  (  tntNode  tn, 
double  pval,  
unsigned  pnum  
) 
Sets a real parameter for functional nodes. If there are multiple parameters, this function should be called once for each parameter. These parameters will then be used to generate the tensor using the operators and linked function set when the node was first created. Trying to set a parameter for a node that is not a functional node will cause an error.
tn  The node to set the parameter for 
pval  The value to set for the parameter 
pnum  Index specifying which parameter should be set, where the index counts from zero. 
Removes all connections between node tnA
and node tnB
. If there are no connections between node tnA
and node tnB
no action is taken, and no error is returned.
tnA  Node A to split from node B 
tnB  Node B to split from node A 
void tntNodeSqueeze  (  tntNode  tn, 
unsigned  squeezeNum,  
unsigned *  squeezeLegs  
) 
Removes the specified legs from the tnode, but only if the legs are not connected to anything and have dimension 1. In any other case the function will cause an error.
If removing the legs will change the symmetry properties of the node (i.e. if they are not assigned a quantum number of zero) then the symmetry information will be removed from the node and it will be turned back into the full format.
tn  The node to remove legs from 
squeezeNum  The number of legs to remove 
squeezeLegs  An array listing the legs to remove 
tntNode tntNodeSVD  (  tntNode  tn, 
int *  startLegs,  
unsigned  startNum,  
int  legUS,  
int  legSU,  
int *  legMap,  
int  connDim,  
double *  err  
) 
Splits the node tn
into three new nodes U
, S
, and VT
using a singular value decomposition. The startLegs
are assigned to U
, and all remaining legs are assigned to VT
. i.e.
The leg ids to use for the connecting legs in the SVD are given by the arguments legUS
and legSU
, while the dimension of these legs is given by the argument connDim
.
The truncation error is calculated by taking the 2norm of the discarded values by default, but to use a different function call the function tntTruncType() before calling this function. This changes the way the truncation error is calculated for all subsequent SVDs. The function returns the node U
, and the remaining nodes S
and VT are inserted in the network and can be identified by traversing the network. The incoming node is deleted, so if it is required for further operations a copy should be made by the calling function.
tn  The node that will be factorised. 
startLegs  The leg id's that will be assigned to U. The remaining legs will be assigned to VT. 
startNum  The number of legs that will be assigned to U. 
legUS  The leg that will connect U to S, and also S to VT. 
legSU  The leg that will connect S to U, and also VT to S. 
legMap  Maps how the legs in A go to legs in U and VT. If all leg numbers stay the same, NULL can be passed instead. 
connDim  The dimension of the leg connecting U to S and S to VT i.e. the number of singular vectors kept. 
err  The truncation error of the SVD (pointer to single value). If the truncation error is not required, pass NULL. 