# How do I compute the SVD of a tensor?

+1 vote

I have a tensor T with indices i1, i2, i3, i4 and I want to compute its SVD U,S,V with indices i1 and i3 on U and i2 and i4 on V. How do I do this?

selected by

Here's some sample code to do this:

ITensor U(i1,i3), S, V;
svd(T,U,S,V);


That's all you need to do. Initializing U with indices i1 and i3 tells the svd routine that those indices (along with a new one connecting U to S) should appear on U after the svd. The remaining indices of T will go onto V.

If you want to do the SVD approximately, do this:

ITensor U(i1,i3), S, V;
svd(T,U,S,V,{"Cutoff=",1E-8,"Maxm=",200});

commented by (110 points)
Hi Miles,

Could you also explain what is the best way to go if the object  T is not an ITensor/IQTensor but a LocalMPO, which is a vector of ITensors. Simply calling svd doesn't work. Thanks in advance.
commented by (52.6k points)
Hi, so for an object like a LocalMPO we don't have a routine that will compute its SVD. The reason is that if a tensor is represented as a LocalMPO, or some similar object, then by definition it is a tensor which is too big to store and/or manipulate directly. Instead it is intended that the main operation you do with it is multiply other tensors by it through the .product method.

That means the most natural way to SVD such a tensor would be to find an iterative algorithm which will do it, then use the .product method as the key step in this iterative algorithm. For instance, if the LocalMPO was actually a square, symmetric "matrix" then you could use an iterative algorithm like davidson to obtain its largest few eigenvalues and then its singular values would be the square roots of these.

If you need help implementing such an iterative algorithm, or if there are some missing lapack operations you need I'd be happy to discuss details.