+1 vote
asked by (230 points)

I'm running tDMRG for a small Heisenberg spin-1/2 chain, using exactApplyMPO and normalizing the wave-function after each time step. When I run for 10 or 15 steps it works perfectly, but when I try to run more steps, I get a weird error:

element = (3.12191E-05,-7.29522E-19)
terminate called after throwing an instance of 'itensor::ITError'
what(): tensor is complex valued, use .cplx(...) method

1 Answer

0 votes
answered by (70.1k points)

Hi, so the reason for this error is that somehow an element of a tensor turned out to be complex even though a subroutine expected a real result. This isn't too surprising since you were doing real-time evolution, so complex numbers were involved. Then some subroutine multiplied (essentially) a complex number by its conjugate giving a real number ideally, but due to some floating point roundoff error gave a tiny imaginary part.

The code that triggered this error checks if the imaginary part is more than 1E-14 times smaller than the real part. Because the real part here was so small that check failed. So I'll put in a separate check that only runs this one if the imaginary part is larger than some reasonable value.

It's hard to get these things to be perfect in every case - thanks for reporting this.

commented by (70.1k points)
I just pushed a patch to ITensor that ought to prevent this particular error from happening the same way.
commented by (350 points)
edited by
I just received the exact same error, and this morning pulled and built the latest version of the code so I know I'm up to date.

element = (6.97019E-05,1.82453E-13)
terminate called after throwing an instance of 'itensor::ITError'
  what():  tensor is complex valued, use .cplx(...) method
Aborted (core dumped)

How should I deal with this problem?

Edit: I found the problem - I was using .real() somewhere, and I guess that imaginary component was too big to be considered negligible.
commented by (70.1k points)
Hi dkweiss,
Yes, that's correct. Based on your experience, though, and on that of the above post, Matt and I have decided that it's too confusing that the .real() method is allowed to work for tensors with complex storage. So we plan to deprecate that feature, and in the upcoming version 3 of ITensor, make it a requirement that you have to call .cplx() (or in version 3 it's called eltC) on tensors with complex storage, even if the element you're retrieving happens to have zero imaginary part.

For now, the best practice I'd recommend is to call .cplx().real() if you definitely just want the real part, and know it's ok to ignore the imaginary part.
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.