0 votes
asked by (150 points)

Dear community,

The problem I have in hand is: I have three MPS, |\psi1>, |\psi2>, |\psi3>, with length 2*N, N, N, respectively. I want to contract the first N index of |\psi1> with |\psi2>, and the second N index with |\psi3>.

I had a solution for the small system, which requires me to change the data type from MPS to ITensor, since I cannot multiply MPS using innerC with different size. Here is my code:

// Change the data type, so that we can perform contraction
 ITensor mpsToTensor(MPS & psi0){

    ITensor psi = psi0.A(1);
    int N = length(psi0);

    for (int j=2; j <=N; ++j){
        psi *= psi0.A(j);

    return psi;


This works for small system. But when I tried N=20, it throws error terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc.
Do you have a smarter way to perform this task that won't cause this error? I am thinking about making a big MPS by combining |\psi2> and |\psi3>, but haven't found a way to do this.

Many thanks,

1 Answer

0 votes
answered by (14.1k points)
selected by
Best answer

Converting an MPS to an ITensor will require an exponential amount of memory in the number of sites, so it is best to avoid that.

I would recommend combining the two MPS @@\psi2@@ and @@\psi3@@ into a single MPS (say @@\phi@@) and then taking the inner product of @@\phi@@ with @@\psi1@@.

commented by (150 points)
Thanks Matt! Could you also explain a little bit how to combine two MPS into a single MPS?
commented by (14.1k points)
You should be able to initialize a new MPS @@\phi@@ of length @@2N@@ and fill the elements in a loop with the tensors of the MPSs @@\psi2@@ and @@\psi3@@. For example something like this:

    auto phi = MPS(2N);
    for(int j=1; j <=2N; ++j)
        if(j <= N) phi.set(j, psi2(j));
        else phi.set(j, psi3(j - N));
commented by (150 points)
Thank you very much! It is really helpful. I am also a bit curious why this conversion takes exponential amount of memory in sites. From my naive understanding, in the case where I have bond dimension being 64 and spin 1/2 on the site, each MPS stores 64*64*2 complex numbers. In the case where it causes error, the sites N = 20.  I guess 64*64*2*20 shouldn't be a large number for a machine? I assume the required memory scales linearly with N and don't quite understand the exponential scaling.
commented by (14.1k points)
When you contract the MPS tensors with each other, you sum over the internal dimensions (the bond dimensions) and the site dimension remain. So for N = 20 and spin-1/2 particles, the full many-body wavefunction has a dimension 2^20.
Welcome to ITensor Support Q&A, where you can ask questions and receive answers from other members of the community.

Formatting Tips:
  • To format code, indent by four spaces
  • To format inline LaTeX, surround it by @@ on both sides
  • To format LaTeX on its own line, surround it by $$ above and below
  • For LaTeX, it may be necessary to backslash-escape underscore characters to obtain proper formatting. So for example writing \sum\_i to represent a sum over i.
If you cannot register due to firewall issues (e.g. you cannot see the capcha box) please email Miles Stoudenmire to ask for an account.

To report ITensor bugs, please use the issue tracker.