Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Electron occupation number not concerved in imaginary time-evolution #168

Open
atxy-blip opened this issue May 9, 2024 · 9 comments
Open

Comments

@atxy-blip
Copy link
Contributor

Very recently we have found out that the electron occupation number changes drastically after several times of imaginary time-evolution.
The very finding has been reproduced on several GPU platforms with a test file (holstein-test.zip) provided by @zhoulq2333. With any version of renormalizer not earlier than 254b981, the value of e_occupation, which in principle should remain unchanged, deviates significantly from the initial value of 0.1 after a mere evolution of about 20 steps. Please feel free to carry out the test on your own.

In brief, the commit of 254b981 does two things

  1. add an environment variable RENO_NUM_THREADS to unify multi-thread libraries
  2. modify the tolerence used in MPS canonicalization

Bugs introduced by the latter should have been addressed by #167, while as I mentioned in #167 (comment), setting RENO_NUM_THREADS to 1 does not take effect in the latest version cloned from the master branch, though helps in the version of v0.0.4.

Therefore, I am seeking help here on how to address the problem, either to validate its existence or to investigate its origin.

@jiangtong1000
Copy link
Collaborator

I wouldn't say this deviates drastically
image

@liwt31
Copy link
Collaborator

liwt31 commented May 10, 2024

I confirm that on the latest commit of the ttn branch 37145a7, the absolute deviation is around 1e-3 at 20 steps. Pretty large IMO. I'm running on pure CPU.

Update: reproduced the results with CPU+GPU

@liwt31
Copy link
Collaborator

liwt31 commented May 10, 2024

I haven't found out the exact reason for this - it's probably related to how the initial state is prepared through MPS expansion.
But I have an ad-hoc solution that you can try:

Add

tp.latest_mps.canonicalise()

before

tp.evolve(nsteps=self.imsteps, evolve_time=self.beta / 2j)

in holstein2.py

Note the solution only works after(including) commit 940161a . Before the commit, ITE works normally without modification.

@jiangtong1000
Copy link
Collaborator

I haven't found out the exact reason for this - it's probably related to how the initial state is prepared through MPS expansion.

yea the expand_bond_dimension function maybe buggy somewhere, since the eocc from the smaller bonddim (eg.16) calculation is more stable than larger one (eg.32),

also, for this ad hoc solution,

Add

tp.latest_mps.canonicalise()

if we perform tp.latest_mps.canonicalise().canonicalise(), things will become bad too. implying that canonicalise need to be checked too

image

@jiangtong1000
Copy link
Collaborator

also, why we need .canonicalise().canonicalise() here?

return (self + expander.scale(coef*self.norm, inplace=True)).canonicalise().canonicalise().normalize("mps_norm_to_coeff")

@liwt31
Copy link
Collaborator

liwt31 commented May 11, 2024

@jiangtong1000 Good to know you have confirmed that canonicalization helps to reduce the error. The fact that when M=16 the error is smaller is very interesting. Yes I also found performing canonicalization twice will lead to large errors. Additionally, if it's performed 3 times, the error is small.

The number of canonicalizations affects the direction of sweep in TDVP-PS. In particular, odd number of canonicalization ensures that the sweep starts from left to right then right to left. I've tried the following configurations

  • In the first sweep, starts from left. And starts from right in all following time steps. The error is small (1e-5 at 150 steps)
  • Reverse the basis in the model. Then no matter the direction of sweep, the error is intermediate (1e-3 to 1e-4 at 70 steps)

also, why we need .canonicalise().canonicalise() here?

This ensures that there is no "redundant" bond dimension on both sides of MPS chain. For example for a spin chain if the initial bond dimension is 16, 16, 16 after the canonicalization the bond dimension becomes 2, 4, 2

@jiangtong1000
Copy link
Collaborator

Interesting. In the past I always thought that by conserving particle number SVD or QR, (the update_mps function), the particle number are always strictly conserved.

@jiangtong1000
Copy link
Collaborator

oh that is true, the particle number are strictly preserved. It is just the translational invariance was broken.

@liwt31
Copy link
Collaborator

liwt31 commented May 30, 2024

@atxy-blip Does altering the initial MPDM solve the issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants