Tensor Network Theory Library  Beta release 1.0 A library of routines for performing TNT-based 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)

## Detailed Description

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.

## Typedef Documentation

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

1. The simplest type is where the node is represented by a static array, which can be loaded from an initialisation file, created by library functions, or is the result of a previous calculation.
2. A more flexible option is the functional node. A functional node contains a number of operators, and information for building the node from a function, and operators and parameters. Currently functional nodes can only be created using initialisation files, and more information is given in the documentation for tntLoadNodes(). Multiple copies of this node can then be made for using at different points in the network. The parameter values for each point in the node are then set using the functions tntNodeSetRealParam() or tntNodeSetCompParam(). Note that once the node has been used in a calculation e.g. tntNodeContractPair(), the functional nature is lost.

## Function Documentation

 void tntNodeAdd ( tntNode tnA, tntNode tnB )

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.

Note
Although the value of tnB is unchanged, if it is of the params type, these parameters will be applied and the node will subsequently be a static node.
Returns
No return value
Parameters
 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.

Returns
No return value
Parameters
 tn The first node to add and that will contain the result of the addition. leglabel The id of the leg to add.
 tntNode tntNodeContract ( tntNode tnA, tntNode tnB, int * legMapAC, int * legMapBC )

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.

Returns
The node that is the result of the contraction.
Parameters
 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.
 tntNode tntNodeCopy ( tntNode tn, int conj )

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.

Returns
The copy of the original node.
Parameters
 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 1e-14, 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 column-major 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().

Returns
The new node.
Parameters
 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.
 tntNode tntNodeCreateEyeOp ( tntNode tn )

Returns the operator which defines the identity node with the same leg properties as the node passed as an argument i.e

• the leg labels, leg dimensions and quantum number information match those of the node passed as an argument,
• the elements of the node are 1 whenever the index of every leg is equal, and zero otherwise.

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.

Returns
The tntNode which represents the identity operator.
Parameters
 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.

Note
This function currently is only available if linking to the NAG library.
Returns
No return value.
Parameters
 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.
 tntNode tntNodeFindConn ( tntNode tn, unsigned legA )

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.

Returns
The node connected to the node tn by the leg stated.
Parameters
 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.

Returns
The first node in the network.
Parameters
 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.

Returns
The last node in the network.
Parameters
 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.

Returns
No return value.
Parameters
 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.

Returns
An complex array containing the diagonal elements of the reshaped tensor that represents the node tn.
Parameters
 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.

Returns
The first element of the tensor that represents the node tn.
Parameters
 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.

Returns
The leg dimension.
Parameters
 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.

Returns
Integer array containing quantum numbers for that leg.
Parameters
 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.

Returns
The trace of the reshaped tensor that represents the node tn.
Parameters
 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.

Returns
No return value.
Parameters
 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.

Returns
No return value.
Parameters
 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

Returns
No return value.
Parameters
 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

Returns
No return value.
Parameters
 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.

Parameters
 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.

Returns
1 if the node is a covariant node, 0 if the node there is no or incomplete symmetry information set for the node.
Parameters
 tn The node to check
 unsigned tntNodeIsFunctional ( tntNode tn )

Checks whether the node is a functional node or a static node.

Returns
The number of parameters if the node is a functional node, 0 if the node is a static node.
Parameters
 tn The node to check
 void tntNodeJoin ( tntNode tnA, int legA, tntNode tnB, int legB )

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.

Returns
No return value.
Parameters
 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 non-zero 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.

Returns
No return value.
Parameters
 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].

Returns
No return value.
Parameters
 tn Node to change leg ids of legmap Map for the new leg numbers, such that legmap[old_id] = new_id
 void tntNodePrepContract ( tntNode tnA, tntNode tnB )

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.

Returns
No return value.
Parameters
 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.

Returns
No return value.
Parameters
 tn The node to print.
 void tntNodePrintInfo ( tntNode tn )

Returns
No return value.
Parameters
 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.

Note
The node is not deleted, so if it is no longer required call tntNodeFree() afterwards.
Parameters
 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
 void tntNodeReplace ( tntNode tnA, tntNode tnB )

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.

Returns
No return value.
Parameters
 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.

Returns
No return value
Parameters
 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.

Returns
No return value
Parameters
 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.

Returns
No return value.
Parameters
 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 block-type form. If this conversion results in values being lost, a warning will be printed.

Use function tntNodeSetQN_nowarn() instead if you do not wish a warning to be printed when information is discarded on conversion.
Parameters
 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.

See documentation for tntNodeSetQN() for full details.
Parameters
 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.

Returns
No return value.
Parameters
 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 tntNodeSplit ( tntNode tnA, tntNode tnB )

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.

Returns
No return value.
Parameters
 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.

Returns
No return value.
Parameters
 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.

• If connDim=-1, the the dimension is set to be the minimum dimension $$D$$ such that no information is discarded.
• If connDim > $$D$$ the value is ignored and instead it is set to $$D$$.
• If connDim < $$D$$ then the singular vectors corresponding to the smallest singular values will be discarded, and the truncation error will be non-zero.

The truncation error is calculated by taking the 2-norm 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.

Note
By default this function optimises the SVD by making small values (below a certain tolerance) equal to zero, then splitting the SVD into blocks. The default tolerance is $$10^{-12}$$, so any values in A smaller than this will be set to zero. This can be changed by using tntSVDTolSet() - see the documentation for this function for more information.
Returns
The node U.
Parameters
 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.