ITensor Support Q&A - Recent questions and answers
http://itensor.org/support/qa
Powered by Question2AnswerHow to realize Hubbard-Holstein model
http://itensor.org/support/1502/how-to-realize-hubbard-holstein-model
<p>I want to realize Hubbard-Holstein model which is mixed bose-fermi model. I watch the question:<a rel="nofollow" href="https://itensor.org/support/782/how-deal-with-bose-fermion-mixture-with-fermion-spinfull-down?show=782#q782">enter link description here</a></p>
<p>the QN file work well. However, Hubbard-holstein hamiltonian like below(Cdagup,Cdagdn,Cup,Cdn is spinfull fermi and Ab,Adagb is bose). I want to initial fermi state and bose state. When I set the initial state , the program error: setting IQtensor element non-zero would violate its symmetry. I think the problem is </p>
<pre><code> ampo += g,"Cdagup",j,"Ab",j+1;
</code></pre>
<p>which are not conserve bose number. I want to know how to correct code,Thank a lot.</p>
<pre><code>int N=80;
auto U=3.6;
auto J=1.0;
auto g=3.0;
auto K=5.0;
auto sites=BF(N);
auto ampo=AutoMPO(sites);
for(int j=1;j<=N-2;j+=2)
{
ampo += -J,"Cdagup",j+2,"Cup",j;
ampo += -J,"Cdagdn",j+2,"Cdn",j;
ampo += -J,"Cdagup",j,"Cup",j+2;
ampo += -J,"Cdagdn",j,"Cdn",j+2;
}
</code></pre>
<p>for(int j=1;j<=N;j=j+2)<br>
{<br>
ampo += U,"Nup",j,"Ndn",j;<br>
<strong>ampo += g,"Cdagup",j,"Ab",j+1;<br>
ampo += g,"Cup",j,"Adagb",j+1;<br>
ampo += g,"Cdagdn",j,"Ab",j+1;<br>
ampo += g,"Cdn",j,"Adagb",j+1;</strong><br>
ampo += K,"Adagb",j+1,"Ab",j+1;<br>
}</p>
<p>}</p>
<pre><code>auto H = IQMPO(ampo);
auto state0 = InitState(sites);
for(int i = 1; i <= N; i=i+1)
{
if (i%4==1)
{
state0.set(i,"Up");
}
else if (i%4==3)
{
state0.set(i,"Dn");
}
else
{
state0.set(i,"b1");
}
}
</code></pre>
<p>auto psi = IQMPS(state0); </p>
<pre><code>auto sweeps=Sweeps(5);
sweeps.maxm() = 20,50,100,200,500;
sweeps.cutoff() = 1E-12;
auto energy = dmrg(psi,H,sweeps,{"Quiet=",true});
</code></pre>
http://itensor.org/support/1502/how-to-realize-hubbard-holstein-modelTue, 21 May 2019 00:20:45 +0000Answered: Extrapolation with truncation error
http://itensor.org/support/1493/extrapolation-with-truncation-error?show=1501#a1501
<p>Hi R.,<br>
To briefly answer your questions:</p>
<p>1 & 2:<br>
The best practice for extrapolating in truncation error is to do <em>two sweeps</em> at a fixed maximum MPS bond dimension "m", then use the energy from the last half-sweep (the last of the four half-sweeps making up the two sweeps) and the corresponding truncation error computed at the central bond of the MPS. This is what is reported by our DMRG code by default, so if you set up your Sweeps object to do two sweeps of each bond dimension, then use the energy and truncation error reported for the second of each sweep, that should be what you need for extrapolation purposes.</p>
<p>If you want to get more detail, just turn off the "Quiet" named argument to DMRG or set it to false. Then you should get a report of the truncation error at every single step.</p>
<p>3: I don't actually know the answer to this - it's a good question. I think it would be a good exercise to convince yourself of why a linear extrapolation is justified by imagining you have a state which is within epsilon of the true ground state using the Euclidean norm / distance. And assume there is a gap to all excited states. Then you can probably recover the argument of the energy error scaling as epsilon to leading order. Then try repeating the argument for excited states (maybe just the first excited state) to see how much of it goes through. </p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1493/extrapolation-with-truncation-error?show=1501#a1501Mon, 20 May 2019 17:44:44 +0000install on linux Ubuntu 18.04
http://itensor.org/support/1497/install-on-linux-ubuntu-18-04
<p>Hi,</p>
<p>I run into problems when installing itensor on Linux(Ubuntu 18.04 ). Here is the error message after running the make file:</p>
<blockquote>
<p>Makefile:2: /home/essa/itensor/this<em>dir.mk: No such file or directory<br>
make: *** No rule to make target '/home/essa/itensor/this</em>dir.mk'. Stop.</p>
</blockquote>
<p>Do you have any idea what went wrong?</p>
<p>Thanks</p>
http://itensor.org/support/1497/install-on-linux-ubuntu-18-04Mon, 20 May 2019 10:53:39 +0000"make" chokes on "itensor_operators.cc" -- windows/cygwin
http://itensor.org/support/1489/make-chokes-on-itensor_operators-cc-windows-cygwin
<p>$ make</p>
<p>Configure: Writing current dir to this_dir.mk</p>
<p>Building ITensor library</p>
<p>make[1]: Entering directory '/cygdrive/c/Users/vadim/itensor/itensor'<br>
Compiling itensor/itensor_operators.cc in debug mode</p>
<p>/usr/lib/gcc/x86<em>64-pc-cygwin/7.4.0/../../../../x86</em>64-pc-cygwin/bin/as: .debug<em>objs/itensor</em>operators.o: section .debug<em>frame$</em>ZN7itensor6detail5FuncTINS0<em>8CallWrapINS0</em>12RegisterTaskINS0<em>7TwoArgsISt10shared</em>ptrINS<em>6ITDataEENS</em>6CPDataEEEONS<em>8ContractINS</em>7IQIndexEEENS<em>8NoneTypeEEESC</em>KNS<em>6ScalarISt7complexIdEEESE</em>S7<em>S8</em>EENS<em>8TypeListIJNS</em>6QDenseISI<em>EENS</em>9QCombinerENS<em>5QDiagIdEENSQ</em>ISI<em>EENS</em>6QMixedIdEENST<em>ISI</em>EENSG<em>IdEESJ</em>EEEE7applyToERKSO_: string table overflow at offset 10000178<br>
/tmp/ccoviA1e.s: Assembler messages:<br>
/tmp/ccoviA1e.s: Fatal error: can't close .debug<em>objs/itensor</em>operators.o: File too big<br>
Failure while executing command: g++ -std=c++11 -Wa,-mbig-obj -O2 -fPIC -c -I/cygdrive/c/Users/vadim/itensor -DDEBUG -g -Wall -pedantic -DPLATFORM_lapack -D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0 -o .debug_objs/itensor_operators.o itensor_operators.cc<br>
make[1]: *** [Makefile:64: .debug_objs/itensor_operators.o] Error 1<br>
make[1]: Leaving directory '/cygdrive/c/Users/vadim/itensor/itensor'<br>
make: *** [Makefile:14: itensor] Error 2</p>
http://itensor.org/support/1489/make-chokes-on-itensor_operators-cc-windows-cygwinTue, 14 May 2019 02:10:35 +0000Answered: LaTeX formulas not rendering properly on the website
http://itensor.org/support/1477/latex-formulas-not-rendering-properly-on-the-website?show=1479#a1479
<p>Hi, thanks for the bug report. Unfortunately I'm not able to reproduce this issue because it is working for me in Chrome, Safari, and iOS. Is it still not working for you? Perhaps it is because you have a firewall or some other internet situation that is blocking the content delivery network (CDN) that is used to render the MathJax (this is cdn.mathjax.org)?</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1477/latex-formulas-not-rendering-properly-on-the-website?show=1479#a1479Sun, 12 May 2019 16:19:52 +0000DMRG doesn't work with certain initial conditions in fermionic systems
http://itensor.org/support/1476/doesnt-work-certain-initial-conditions-fermionic-systems
<p>Hello,</p>
<p>I am running some calculations on a 4-site square chain with a tight-binding Hamiltonian, and have found an issue when applying the DMRG function to my system. Depending on the state I initialize the system, the DMRG can either run normally and return the expected value for the energy, or almost instantly return a (wrong) value of 0 for the ground state energy. Here is a sample code to demonstrate the problem:</p>
<pre><code>#include "itensor/all.h"
using namespace itensor;
int main()
{
int N = 4;
double t = 1.0;
int nsweeps = 5;
int maxm = 200;
double cutoff = 1E-15;
int niter = 2;
double noise = 0;
auto sites = Hubbard(N);
auto ampo = AutoMPO(sites);
ampo += -t,"Cdagup",1,"Cup",2;
ampo += -t,"Cdagup",2,"Cup",1;
ampo += -t,"Cdagdn",1,"Cdn",2;
ampo += -t,"Cdagdn",2,"Cdn",1;
ampo += -t,"Cdagup",1,"Cup",3;
ampo += -t,"Cdagup",3,"Cup",1;
ampo += -t,"Cdagdn",1,"Cdn",3;
ampo += -t,"Cdagdn",3,"Cdn",1;
ampo += -t,"Cdagup",2,"Cup",4;
ampo += -t,"Cdagup",4,"Cup",2;
ampo += -t,"Cdagdn",2,"Cdn",4;
ampo += -t,"Cdagdn",4,"Cdn",2;
ampo += -t,"Cdagup",3,"Cup",4;
ampo += -t,"Cdagup",4,"Cup",3;
ampo += -t,"Cdagdn",3,"Cdn",4;
ampo += -t,"Cdagdn",4,"Cdn",3;
//Use IQMPO or MPO to generate the hamiltonian
auto H = IQMPO(ampo);
Print(ampo);
//Define initial wavefunction MPS for IQMPS
auto state1 = InitState(sites);
state1.set(1,"Up");
state1.set(2,"Up");
state1.set(3,"0");
state1.set(4,"0");
//Create IQMPS
auto psi = IQMPS(state1);
//Overlap test
auto state2 = InitState(sites);
state2.set(1,"0");
state2.set(2,"Up");
state2.set(3,"Up");
state2.set(4,"0");
auto psi2 = IQMPS(state2);
println(overlap(psi2,H,psi));
//Define DMRG sweeps
auto sweeps = Sweeps(nsweeps);
sweeps.maxm() = maxm/20,maxm/10,maxm/2,maxm/2,maxm;
sweeps.cutoff() = cutoff;
sweeps.niter() = niter;
sweeps.noise() = noise;
auto energy = dmrg(psi,H,sweeps,{"Quiet",true});
return 0;
} //End of main
</code></pre>
<p>When I run this code exactly as it is, the DMRG returns a value of 0 for the ground state energy. The same happens if the two electrons are initialized in sites 3 and 4. However, if I change the initial conditions to initialize the electrons on other combinations of sites (for instance sites 1 and 3), I get the correct value for the energy (-2).</p>
<p>I've made some tests and found out this problem does not happen if I change the ordering of the sites to a cyclic chain, that is, with interactions 1-2, 2-3, 3-4, 4-1. However, since my goal is to work with larger chains, I figured I should number the sites the way I am doing in the sample code, as to avoid creating super-long-range interactions when working with more sites. Therefore, I think having a fix for this problem while still using my ordering would be ideal.</p>
<p>I believe the cause of this issue is the way the ITensor library handles the fermionic operators "Cdagup" and "Cup". Depending on the order they are applied when initializing the system and how many anticommutations are made when the Hamiltonian is applied, the final sign of the tight-binding interaction might become positive when it should be negative, thus "fooling" the DMRG algorithm into believing the system is already at the lowest energy level. To exemplify, if one calculates the overlap <0 Up Up 0| H |Up Up 0 0> in the sample code, instead of the expected result of -1 (given the sign of the hopping term), the code returns +1. </p>
<p>This overlap test made me think a simple change of signs on the Hamiltonian could solve everything. However, I discovered that changing the sign of the hopping term on the specific part of the Hamiltonian that annihilates one electron on the first site and creates it on the third site doesn't seem to completely fix the problem; although the overlap described above now returns a value of -1, the DMRG surprisingly still returns a value of 0 for the energy. </p>
<p>So, I wanted to ask if there is anyway I can have consistent (a.k.a. not dependent on the initial conditions) DMRG results for my system while keeping the ordering of the sites intact. I would appreciate any input into this. Thanks!</p>
http://itensor.org/support/1476/doesnt-work-certain-initial-conditions-fermionic-systemsThu, 09 May 2019 18:29:48 +0000Answered: define initial state in iTEBD
http://itensor.org/support/1467/define-initial-state-in-itebd?show=1474#a1474
<p>Hi, so unfortunately we can't provide official user support specifically for codes listed on the "ITensor codes" page. This is because those codes are written by a variety of people outside the ITensor development team, and we do not always understand their inner workings in detail. </p>
<p>But taking a quick look at that code, it appears that QNA and QNB are how you set an initial state. I believe that setting these creates an initial state which is a product state where each site (of the two sites) has a state defined by the quantum numbers QNA, and QNB, where these quantum numbers are defined through the IQIndex sites (but unfortunately the description of this part is vague, I agree, so you'll have to read the code or ask the code's developer).</p>
<p>He does describe the usage somewhat in the readme file here: <a rel="nofollow" href="https://github.com/hoihui/itebd">https://github.com/hoihui/itebd</a></p>
<p>The line "Sys(ampo,2,3)" is defining an object of type "itebd" and calling its constructor function, which takes an AutoMPO object and two integers. The itebd type is defined as "struct itebd ..." in the itebd.h file. </p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1467/define-initial-state-in-itebd?show=1474#a1474Wed, 08 May 2019 13:33:44 +0000Answered: Time Evolution of multi-band Hubbard Model Not Working
http://itensor.org/support/1449/time-evolution-of-multi-band-hubbard-model-not-working?show=1473#a1473
<p>Hi, thanks for the question but basically one would need to look more deeply into each step of the calculation to find out what is going on. But my suspicion is that the MPO approach is not well-suited for the kind of Hamiltonian you are evolving with.</p>
<p>I presume you are using the toExpH function to approximately exponentiate an AutoMPO then using that to do the time evolution? This approach to time evolution has actually been turning out not to work too well compared to other methods, especially for Hamiltonians with further-neighbor interactions (in the sense of the ordering of the sites of an MPS). But we put it into ITensor as an option for people to try, since it can work fine in certain cases and can be useful for benchmarking other, more accurate methods such as using Trotter gates.</p>
<p>Most likely for your case the best approach for time evolution would be to use the TDVP method. We don't have a TDVP code available in ITensor at the moment, but one of our colleagues is working on one so we hope to make that public sometime this summer. Also you could write a TDVP code yourself if you have the time & energy to do so. </p>
<p>Best regards,<br>
Miles</p>
<p>(Also, please see my question in the comment above about the long-rangedness of your Hamiltonian and the possibility of using Trotter gates.)</p>
http://itensor.org/support/1449/time-evolution-of-multi-band-hubbard-model-not-working?show=1473#a1473Wed, 08 May 2019 13:22:36 +0000Answered: initial state in the "toExpH" function
http://itensor.org/support/1470/initial-state-in-the-toexph-function?show=1471#a1471
<p>Hi,<br>
<code>toExpH</code> only converts ampo object to <strong>exp(−tauH)</strong>, you can use <code>exactApplyMPO</code> or <code>fitApplyMPO</code> to compute <strong>exp(−tauH)|psi></strong></p>
<p>e.g. <strong>psi1</strong> is the initial state:<br>
<code>auto expH = toExpH<ITensor>(ampo,tau);</code><br>
<code>psi1 = exactApplyMPO(expH,psi1,args);</code></p>
http://itensor.org/support/1470/initial-state-in-the-toexph-function?show=1471#a1471Wed, 08 May 2019 02:36:36 +0000Answered: Extract effective hamiltonian from LocalMPO
http://itensor.org/support/1450/extract-effective-hamiltonian-from-localmpo?show=1469#a1469
<p>The effective Ham support in modified localmpo.h and localop.h can be found <a rel="nofollow" href="https://github.com/empter/ITensor/commit/c12de4cee5ac21d90943bddd58748d68487b85e1">here</a>.<br>
With LocalMPO object PH</p>
<p><code>PH.position(b,psi);
Tenosr heff;
PH.localh(heff);</code><br>
gives the two-site (b,b+1) effective Hamiltonian held in <code>heff</code></p>
<p>The most challenging problem is how to calculate <strong>e^(-i Heff t)|psi></strong>, a possible way is using the Keylov subspace algorithm. In my practice, it is difficult to implemented this algorithm under itensor, because it needs expnonHermitian, or eigensystem of non-Hermitian matrix.</p>
http://itensor.org/support/1450/extract-effective-hamiltonian-from-localmpo?show=1469#a1469Tue, 07 May 2019 12:51:17 +0000Answered: Single site SVD - QR decomposition
http://itensor.org/support/1459/single-site-svd-qr-decomposition?show=1460#a1460
<p>Hi Jacopo,</p>
<p>That sounds like a good approach for doing what you want to do. In the code above, is <code>phi</code> a copy of <code>psi.A(b)</code>?</p>
<p>I am not sure why it would be seg faulting. The reason would not be that <code>U</code> and <code>psi.A(b)</code> have different ordering of indices, since ITensor doesn't care what the ordering of the indices are. Could you run your code in debug mode and see if it outputs any more specific errors?</p>
<p>In order to help debug it would be helpful to have a minimal working example of the code that is failing.</p>
<p>Here is a minimal example of how this approach would work (this runs correctly for me):</p>
<pre><code>auto N = 10;
auto sites = SpinHalf(N);
auto psi = MPS(sites);
auto b = 4;
// Set the center site gauge with ITensor
psi.position(b);
// Move the center gauge manually
auto lb = linkInd(psi,b);
ITensor U,S,V(lb);
svd(psi.A(b),U,S,V);
psi.setA(b,U);
psi.Aref(b+1) *= S*V;
</code></pre>
<p><code>linkInd(psi,b)</code> is a shorthand for <code>commonIndex(psi.A(b),psi.A(b+1),Link)</code>. Also note that if you put indices only on the <code>V</code> tensor, the <code>svd</code> function will use those to determine how to reshape the input tensor.</p>
<p>Note that a more efficient alternative to using <code>svd</code>, if you don't need extremely high accuracy of your singular values, is to use <code>denmatDecomp</code> ( <a rel="nofollow" href="http://itensor.org/docs.cgi?page=classes/decomp">http://itensor.org/docs.cgi?page=classes/decomp</a> ), which directly computes <code>T = U*B</code> where <code>B = S*V</code>.</p>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1459/single-site-svd-qr-decomposition?show=1460#a1460Tue, 30 Apr 2019 14:47:09 +0000Answered: Simple exact diagonalization missing code formula
http://itensor.org/support/1454/simple-exact-diagonalization-missing-code-formula?show=1456#a1456
<p>Thanks Joel - this was just an issue with the website, which we recently upgraded to let users switch between multiple versions of the documentation. Please check again and the code ought to appear for you now -</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1454/simple-exact-diagonalization-missing-code-formula?show=1456#a1456Mon, 29 Apr 2019 14:00:29 +0000Answered: main function
http://itensor.org/support/1452/main-function?show=1453#a1453
<p>Hi, so if you want to put ITensor code into a function (which is a good idea), you can do this in the same way as putting any other C++ code into a function.</p>
<ol>
<li><p>identify which variables you would like to be changeable or adjustable each time the function is run. (For the example of AutoMPO, let's say this is the Sz*Sz coupling called Jz.) Also you will need to pass variables to the function which are required for it to run, such as your site set needed to create your AutoMPO.</p></li>
<li><p>create a function which takes the needed variables (here it is your site set and Jz).</p></li>
<li><p>put the code into the function and then return the result of that code, in this case the MPO you create from the AutoMPO.</p></li>
</ol>
<p>Here is an example:</p>
<pre><code>MPO
makeH(SiteSet const& sites,
Real Jz)
{
auto N = sites.N();
auto ampo = AutoMPO(sites);
for(int j = 1; j < N; ++j)
{
ampo += 0.5,"S+",j,"S-",j+1;
ampo += 0.5,"S-",j,"S+",j+1;
ampo += Jz,"Sz",j,"Sz",j+1;
}
return MPO(ampo);
}
</code></pre>
<p>(Advanced C++ user note: If you put the function into a header file, don't forget to put the "inline" keyword at the front of the function definition.)</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1452/main-function?show=1453#a1453Sun, 28 Apr 2019 16:12:56 +0000Answered: tMPS and OpenBLAS
http://itensor.org/support/1446/tmps-and-openblas?show=1447#a1447
<p>Hi Jin,<br>
I think the answer to #1 is complicated. I'm not sure what the difference in error would be between the two methods without doing a careful theoretical error analysis. Barring that, I think if you're really very curious about both methods, or suspect one might not be accurate enough for what you need, then you could just code both of them and plot results to see how the errors behave.</p>
<p>Regarding BLAS parallelism, it's kind of complicated also. Sometimes we have seen speedups from letting the BLAS use multiple cores, but other times we've seen what you report, namely that it does a bad job and can even hurt speed. Basically this is a feature of your BLAS which is outside of ITensor and which we do not control. Also its effectiveness is highly dependent on the details of the algorithm you are doing, whether DMRG or another algorithm, and the sizes of the tensors, their block structure, etc. So again I think your best bet is just to adjust the settings as you have done and see what works best for your needs. Also you might get different results with a different BLAS implementation, such as MKL which is a very high quality BLAS code.</p>
<p>Best regards,<br>
Miles</p>
<p>P.S. about the BLAS, you might want to write a simple test code which just multiplies two very large matrices, and run that with different OPENBLAS NUM THREADS settings to see what results you get. If it doesn't work for that, i.e. if it doesn't give a speedup even for rather large matrices, you might conclude that it's just not a very useful feature of your BLAS. On the other hand, if you do see a speedup, you should see what matrix sizes are needed to see it and compare to the typical sizes in your DMRG calculation. Perhaps it could help if you turn it on for a very large DMRG calculation in the last few sweeps.</p>
http://itensor.org/support/1446/tmps-and-openblas?show=1447#a1447Fri, 19 Apr 2019 15:51:41 +0000Answered: Parallelization of Trotter with openMP
http://itensor.org/support/1444/parallelization-of-trotter-with-openmp?show=1445#a1445
<p>Hi, so we have not explored parallelism with OpenMP very much. But please do try it and let us know if you run into any issues. The kind of parallelism you are describing would sit outside of ITensor, which is why we have not documented it (it's not a feature of ITensor, but just a way of using ITensor inside of a larger code). </p>
<p>In the past, I have used ITensor within a multi-threaded code where I created a parallel for loop using the C++ threading library and it worked extremely well. So hopefully you can use an OpenMP parallel for loop in the same way. The reason I say "let us know if you run into any issues" is that there may be some special handling of certain parts of ITensor we need to put in to make things thread safe within OpenMP. We can do this and add a compiler flag to turn it on, but please just try it first.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1444/parallelization-of-trotter-with-openmp?show=1445#a1445Tue, 16 Apr 2019 14:49:13 +0000Quick code review: Possible misunderstanding of MPO/MPS
http://itensor.org/support/1439/quick-code-review-possible-misunderstanding-of-mpo-mps
<p>The below (< 50 lines) of code is the simplest way I could illustrate my possible misunderstanding. To be clear, this is <em>not</em> the actual problem I am trying to solve in my research (the solution is trivial); I'm just trying to find my way around ITensor and MPO/MPS.</p>
<p>Here is my current understanding of what this code <strong>should</strong> do: I construct an MPS of all "occupied" sites and two MPOs. The first is the Hamiltonian, which is supposed to subtract particles from occupied sites to yield empty sites, at a simple rate of 1. At each timestep, I apply the Hamiltonian times a small timestep @@h@@. This is the explicit Euler solution to the equation:</p>
<p>$$<br>
\frac{\mathrm{d} \mathbf{y}}{\mathrm{d} t} = A \mathbf{y}<br>
$$</p>
<p>The observable I want to record is the number of occupied sites, so I use the second MPO, constructed from the number operator, and apply it as @@\langle \psi, B \psi \rangle@@.</p>
<p>Examining the raw output, or even plotting the results, is not encouraging, because the total number of occupied states is increasing, not decreasing. I'm sure I've just misunderstood something along the way, but I can't think of any particcular reason why the method I've described wouldn't yield (something close to) the analytic solution,</p>
<p>$$<br>
y(t) = 3 e^{-t}.<br>
$$</p>
<p>As always, help is greatly appreciated.</p>
<pre><code>#include <itensor/all_basic.h>
#include <itensor/all_mps.h>
#include <iostream>
int main(int argc, char *argv[])
{
int N = 3;
auto sites = itensor::Spinless(N);
auto ampo = itensor::AutoMPO(sites);
auto ampo2 = itensor::AutoMPO(sites);
auto state = itensor::InitState(sites);
for (auto j : itensor::range1(N))
{
ampo += "A", j;
ampo2 += "N", j;
state.set(j, "Occ");
}
auto mpo = itensor::toMPO<itensor::ITensor>(ampo, { "Exact=", true });
auto mpo2 = itensor::toMPO<itensor::ITensor>(ampo2, { "Exact=", true });
auto mps = itensor::MPS(state);
double h = 1.e-6, t = 0;
for (auto i : itensor::range(1000))
{
mps.plusEq(h * itensor::applyMPO(mpo, mps, { "Exact=", true }));
t += h;
auto norm = itensor::overlap(mps, mps);
auto count = itensor::overlap(mps, mpo2, mps);
std::cout << std::scientific << t << " " << norm << " " << count
<< std::defaultfloat << std::endl;
}
return 0;
}
</code></pre>
http://itensor.org/support/1439/quick-code-review-possible-misunderstanding-of-mpo-mpsFri, 12 Apr 2019 17:58:08 +0000Answered: Efficient way to manually increase bond dimension of MPS or IQMPS
http://itensor.org/support/1419/efficient-way-manually-increase-bond-dimension-of-mps-iqmps?show=1438#a1438
<p>Just to give an official answer to summarize the comments above:</p>
<ol>
<li><p>As a technical problem of expanding the subspace of an IQMPS, it is not directly built into ITensor right now, though with some modification of existing code in itensor/mps/mpsalgs.cc it is not hard to do. For example, take a look at: <a rel="nofollow" href="https://gist.github.com/mtfishman/1804a3a473112cb7cb80722eeac47a8b">https://gist.github.com/mtfishman/1804a3a473112cb7cb80722eeac47a8b</a> which shows an implementation of a "partial direct sum" operation of two IQTensors, which should be sufficient for doing a subspace expansion of an IQMPS. This is something that we will try to support officially in ITensor as soon as possible.</p></li>
<li><p>A general question which is application dependent is how to choose the QNs of an expanded IQMPS subspace. The answer is that, when possible, it is best to determine the expanded subspace using the physics of your problem. For a single site DMRG calculation, a popular method seems to be ( <a rel="nofollow" href="https://arxiv.org/pdf/1501.05504.pdf">https://arxiv.org/pdf/1501.05504.pdf</a> ), but various methods have been proposed. Alternatively, a method that would work fairly generically would be to first perform a 2-site version of the MPS algorithm you are interested in (for example, 2-site DMRG or 2-site TDVP), which will automatically expand the subspace. Then, you can switch to a 1-site version once the desired bond dimension is reached.</p></li>
</ol>
http://itensor.org/support/1419/efficient-way-manually-increase-bond-dimension-of-mps-iqmps?show=1438#a1438Wed, 10 Apr 2019 19:22:08 +0000Answered: Trotter gates for ancilla/purification method
http://itensor.org/support/1426/trotter-gates-for-ancilla-purification-method?show=1427#a1427
<p>Hi Jacopo,<br>
Thanks for the question. So the problem here is on us, namely that we had not yet documented the gateTEvol method despite publicizing it. The key thing you are missing is that gateTEvol requires each of the gates passed to it to act only on consecutive (nearest-neighbor) site pairs. </p>
<p>I just started documenting it so people will know this in the future:<br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv2&page=classes/tevol">http://itensor.org/docs.cgi?vers=cppv2&page=classes/tevol</a></p>
<p>In order to do the ancilla technique with Trotter gates (which is a very good way to do it), you will need to insert "swap gates" into your gate list. You can use the "Gate = BondGate" class to make swap gates like this:</p>
<pre><code>auto swapij = Gate(sites,i,j);
</code></pre>
<p>In the upcoming version 3 of ITensor we're going to make a more intuitive interface for making gates. (Probably just separate functions such as <code>swapGate</code>, <code>realGate</code>, <code>imagGate</code> etc.)</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1426/trotter-gates-for-ancilla-purification-method?show=1427#a1427Wed, 10 Apr 2019 14:53:38 +0000Answered: Addition of onsite terms in trotter gates gives wrong overlap with ground state of H
http://itensor.org/support/1413/addition-onsite-trotter-gates-gives-wrong-overlap-ground-state?show=1415#a1415
<p>Hi, thanks for the question. The answer is that why this is happening could be due to many reasons, so it's hard to tell just from the description of the results you are seeing.</p>
<p>The most likely reason, if I had to guess, is that Trotter gates very generally incur a finite-time-step error, as you know. So the evolution is not exact. Therefore even if theoretically the overlap should stay very close to 1, in practice it will not. How close it stays should then depend on how small of a time step you use, how many steps you do, and how accurately you decompose/truncate the MPS after each step.</p>
<p>Another possibility is that there is a slight error or bug in your code.</p>
<p>If you try adjusting the time step and other accuracy parameters, and do other checks you can think of, but then think the results you are seeing cannot be right, please post a follow up comment or new question, perhaps with some code, and we can discuss more.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1413/addition-onsite-trotter-gates-gives-wrong-overlap-ground-state?show=1415#a1415Mon, 08 Apr 2019 14:49:32 +0000Answered: Computing the partial Kronecker product of two ITensors
http://itensor.org/support/1407/computing-the-partial-kronecker-product-of-two-itensors?show=1408#a1408
<p>Hello,</p>
<p>If I understand the operation correctly, I think you could do it this way:</p>
<pre><code>auto I1 = Index("I1",2);
auto I2 = Index("I2",2);
auto R1 = Index("R1",2);
auto R2 = Index("R2",2);
auto S1 = Index("S1",2);
auto S2 = Index("S2",2);
auto A = randomTensor(R1,R2,I1,I2);
auto B = randomTensor(S1,S2,prime(I1),prime(I2));
auto del1 = delta(I1,prime(I1),prime(I1,2));
auto del2 = delta(I2,prime(I2),prime(I2,2));
auto C = (A*del1*del2*B).noprime();
PrintData(C);
</code></pre>
<p>where here M=N=2, just for simplicity. For arbitrary M and N, it shouldn't be too hard to do it in terms of vectors of Indices and <code>delta</code> tensors.</p>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1407/computing-the-partial-kronecker-product-of-two-itensors?show=1408#a1408Fri, 05 Apr 2019 14:35:57 +0000Answered: Non-Uniform Density of Up States in First Neighbor Tight-Binding Model
http://itensor.org/support/1403/uniform-density-states-first-neighbor-tight-binding-model?show=1404#a1404
<p>Hi rmagaldi,<br>
Thanks for the question. So I think I may have figured out what's going wrong. The good news is that it does not appear to be the DMRG optimization itself, but the definition of the Hamiltonian.</p>
<p>What I did to test this is to observe that your system is just a periodic ring, so one can make the Hamiltonian in a simpler way:</p>
<pre><code>for(int j = 1; j <= N-1; j+=1)
{
ampo += -t,"Cdagup",j,"Cup",j+1;
ampo += -t,"Cdagup",j+1,"Cup",j;
ampo += -t,"Cdagdn",j,"Cdn",j+1;
ampo += -t,"Cdagdn",j+1,"Cdn",j;
}
ampo += +t,"Cdagup",1,"Cup",N;
ampo += +t,"Cdagup",N,"Cup",1;
ampo += +t,"Cdagdn",1,"Cdn",N;
ampo += +t,"Cdagdn",N,"Cdn",1;
</code></pre>
<p>This is just a nearest-neighbor hopping with an additional "long bond" connecting site 1 to site N. Note that the coupling has the opposite sign for the long bond. Choosing this sign gives a uniform density, regardless of the initial state. Choosing a -t coupling gives the behavior you reported.</p>
<p>So probably if one works through this carefully, the reason the +t is the correct coupling is because really one should think of the long bond as going from N to 1 with a -t, which is equivalent to going from 1 to N with a +t, due to the fact that C and Cdagger anti commute.</p>
<p>Hope that helps!</p>
<p>Miles</p>
http://itensor.org/support/1403/uniform-density-states-first-neighbor-tight-binding-model?show=1404#a1404Tue, 02 Apr 2019 22:05:19 +0000Using ITensor for computational not-quantum chemistry
http://itensor.org/support/1401/using-itensor-for-computational-not-quantum-chemistry
<p>This is an amazing piece of code and I'm delighted to have found it! I think it might be useful for an application I am working on. The goal is to solve the chemical master equation</p>
<p>$$<br>
\frac{\mathrm{d} P}{\mathrm{d} t} =\mathbf{A} P<br>
$$</p>
<p>where @@\mathbf{A}@@ is a matrix of connections and @@P@@ represents the vector of probabilities of being in each state. (See <a rel="nofollow" href="https://en.wikipedia.org/wiki/Master_equation">this Wikipedia page</a> for more details on master equations.) I got the idea for solving the master equation using the tensor formalism from <a rel="nofollow" href="http://dx.doi.org/10.1016/j.jcp.2017.04.007">this paper</a> and <a rel="nofollow" href="http://dx.doi.org/10.1016/j.jcp.2016.03.025">its companion paper</a>. Our system is similar in form to the CO oxidation model in the papers, but it has different chemical species and more complicated reactions.</p>
<p>To model this, I <em>think</em> I can use ITensor by applying an MPO (which may act on more than two sites!) to an MPS repeatedly and, at each timestep, measure the properties we are interested in (say, total number of atoms/molecules of each type). I haven't seen an example of this being done in ITensor yet, but <a rel="nofollow" href="https://en.wikipedia.org/wiki/Creation_and_annihilation_operators#Creation_and_annihilation_operators_for_reaction-diffusion_equations">this Wikipedia page</a> suggests that a reaction-diffusion system could be modeled as a time-evolving set of non-quantum states.</p>
<p><strong>Has anyone done something like this in ITensor before? Are there any fundamental problems with using the library this way, particularly since this isn't exactly the canonical use case?</strong></p>
<p>I also understand that <code>toExpH</code> doesn't work for MPOs that operate on more than two sites -- which, sadly, mine probably does. <strong>Barring the obvious numerical instabilities, is there any reason why I couldn't do something like an explicit Euler integration instead of using the matrix exponential form to solve the above equation?</strong></p>
http://itensor.org/support/1401/using-itensor-for-computational-not-quantum-chemistryMon, 01 Apr 2019 21:58:13 +0000Answered: Time evolution with IQTensors is slower than ITensors
http://itensor.org/support/1397/time-evolution-with-iqtensors-is-slower-than-itensors?show=1399#a1399
<p>Hi, thanks for raising this issue. So this is actually expected when tensors are sufficiently small. In that case the non-trivial overhead of book keeping the QNs can have a noticeable effect. Could you try making the MPS bond dimension bigger and see if the difference persists?</p>
<p>Thanks,<br>
Miles </p>
http://itensor.org/support/1397/time-evolution-with-iqtensors-is-slower-than-itensors?show=1399#a1399Sun, 31 Mar 2019 13:57:49 +0000Answered: Conserving difference of two bosonic species
http://itensor.org/support/1391/conserving-difference-of-two-bosonic-species?show=1392#a1392
<p>Hi, thanks for the question. So in version 2 (we've made this easier in the soon to be released version 3) the way the QNs work is that they are globally defined throughout your code. They are ordered tuples of pairs of integers.</p>
<p>The design you'll want to then do is define your QNs like this (all of them):</p>
<p>QN({na,1},{nb,1},{sz,1})</p>
<p>where na, nb, and sz are integers that are the number of A bosons; number of B bosons; and Sz quantum number of that site. If a site consists purely of one type of boson (say "A"), that's ok: just set nb=0. Similar for if a site carries no spin, just set sz=0. </p>
<p>If your A and B bosons reside on different sites, I'd recommend making two different site types, which could be named ABosonSite and BBosonSite, say. Then you can write code similar to that for BasicSiteSet (see line 376 of itensor/mps/siteset.h) except have the for loop switch the site type between odd and even sites. </p>
<p>If you want to post your code here I'd be happy to take a look.</p>
<p>An alternative is that you could go ahead and switch to version 3. To do this, just do "git checkout rc3" and then "make clean" and "make" from the top level of the ITensor folder. The rc3 branch means "release candidate 3". Howver, I should caution that one of the last parts of ITensor we're taking a hard look at before we finally release version 3 happens to be site sets! We probably won't change them too much, but there's a chance we might. </p>
<p>The advantage of version 3, though, is the new QN design. In that version, each quantum number within a QN object has a name string that goes with it, so for a case like yours you can just make QN's like QN({"A",na,1}) for A sites and QN({"B",nb,1}) for B sites and they will mix together just fine.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1391/conserving-difference-of-two-bosonic-species?show=1392#a1392Fri, 29 Mar 2019 02:01:05 +0000Answered: Set the element in a sparse matrix
http://itensor.org/support/1384/set-the-element-in-a-sparse-matrix?show=1387#a1387
<p>It looks like right now <code>.set()</code> is not defined for diagonal storage, i.e.:</p>
<pre><code>auto i = Index("i",2);
auto j = Index("j",2);
auto A = delta(i,j);
A.set(i(1),j(1),2.0);
</code></pre>
<p>throws an error:</p>
<pre><code>terminate called after throwing an instance of 'itensor::ITError'
what(): doTask not defined for task SetElt and storage type DiagReal
</code></pre>
<p>From what I can tell, right now the only methods for actually modifying ITensors with Diag storage are <code>.apply()</code> and <code>.fill()</code>, so for example:</p>
<pre><code>A.apply([](Real x){ return 2*x; });
</code></pre>
<p>would double all of the values of the diagonals, and</p>
<pre><code>A.fill(3.);
</code></pre>
<p>would set all of the values to 3.</p>
<p>For more complicated element setting, you may have to store the original diagonal values (for example in a vector), manipulate them, and then use them in a <code>diagTensor</code> constructor to make a new ITensor with the diagonal values you want.</p>
<p>I think it would be good for us to define <code>.set()</code> for Diag/QDiag storage, and have it throw an error if a user tries to set an off-diagonal element. But I think many current cases can be covered by the current functionality, and worse case would be making a new diagTensor.</p>
<p>What is your particular use-case? Note that there is also a new <code>iterInds</code> function (<a rel="nofollow" href="http://www.itensor.org/support/1361/iterating-over-non-zero-elements-of-a-sparse-itensor)">http://www.itensor.org/support/1361/iterating-over-non-zero-elements-of-a-sparse-itensor)</a> that can help you visit all of the elements of an ITensor, in case that helps.</p>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1384/set-the-element-in-a-sparse-matrix?show=1387#a1387Wed, 27 Mar 2019 14:54:06 +0000Answered: How to obtain eigenvalue of two-site reduced density matrix
http://itensor.org/support/1385/how-to-obtain-eigenvalue-of-two-site-reduced-density-matrix?show=1386#a1386
<p>Hi JR, <br>
The diagHermitian function should be what you need. You can read more about it on this page:<br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv2&page=classes/decomp">http://itensor.org/docs.cgi?vers=cppv2&page=classes/decomp</a></p>
http://itensor.org/support/1385/how-to-obtain-eigenvalue-of-two-site-reduced-density-matrix?show=1386#a1386Wed, 27 Mar 2019 14:15:38 +0000Answered: Use vector of doubles in Args
http://itensor.org/support/1380/use-vector-of-doubles-in-args?show=1381#a1381
<p>Hi jsf,<br>
While that's a clever way to store and retrieve values, the Args system is really intended to pass named arguments to functions, not as a database to hold arbitrary types. If we made it possible to do so, it would cause an unacceptably high performance penalty to most of the functions using Args and go beyond the intended purpose of that system.</p>
<p>Instead, you can already read and write most types used in ITensor, including standard library types such as std::vector, to files using the read and write functions provided with ITensor. Here is some example code showing how.</p>
<p>Writing objects to a file "myfile.dat":</p>
<pre><code>auto v = vector<int>(4);
v[0] = 1;
v[1] = 3;
v[2] = 5;
v[3] = 9;
auto i = Index("i",2);
auto T = randomTensor(i);
std::ofstream f("myfile.dat",std::ios::binary);
write(f,v);
write(f,i);
write(f,T);
f.close();
</code></pre>
<p>Reading the data back in from the file:</p>
<pre><code>std::ifstream f("myfile.dat",std::ios::binary);
vector<int> v;
read(f,v);
Index i;
read(f,i);
ITensor T;
read(f,T);
f.close();
Print(v.size());
Print(v[0]);
Print(v[1]);
Print(v[2]);
Print(v[3]);
Print(T);
</code></pre>
http://itensor.org/support/1380/use-vector-of-doubles-in-args?show=1381#a1381Mon, 25 Mar 2019 17:38:52 +0000Answered: Iterating over non-zero elements of a sparse ITensor
http://itensor.org/support/1361/iterating-over-non-zero-elements-of-a-sparse-itensor?show=1369#a1369
<p>Good suggestion, thanks. I think this is a feature we should definitely have, so I just added it! (You'll have to pull the latest version of ITensor to get it.)</p>
<p>What I added is a function called <code>iterInds</code> which you in a range-based for loop, which gives the behavior you asked about. </p>
<p>Here is a sample code using it:</p>
<pre><code>auto i = Index("i",2);
auto j = Index("j",3);
auto k = Index("k",4);
auto is = IndexSet(i,j,k);
auto T = randomTensor(i,j,k);
for(auto it : iterInds(T))
{
Print(it[0]);
Print(it[1]);
Print(it[2]);
Print(T.real(it));
println();
}
PrintData(T);
</code></pre>
http://itensor.org/support/1361/iterating-over-non-zero-elements-of-a-sparse-itensor?show=1369#a1369Tue, 12 Mar 2019 05:25:30 +0000Answered: How to create a particular initial state as a MPS?
http://itensor.org/support/1359/how-to-create-a-particular-initial-state-as-a-mps?show=1368#a1368
<p>Diego's answer is a good one.</p>
<p>Another way to do what you want, setting the tensor elements directly, is to use similar code to what olabaz provides in his question here:<br>
<a rel="nofollow" href="http://itensor.org/support/1357/setting-random-initial-product-state">http://itensor.org/support/1357/setting-random-initial-product-state</a></p>
http://itensor.org/support/1359/how-to-create-a-particular-initial-state-as-a-mps?show=1368#a1368Tue, 12 Mar 2019 04:40:42 +0000Answered: Setting Random Initial Product State
http://itensor.org/support/1357/setting-random-initial-product-state?show=1366#a1366
<p>That looks like a fine way to do it. Note that you could also use an InitState and then apply a random on-site rotation, similar to the answer given here: <a rel="nofollow" href="http://www.itensor.org/support/1359/how-to-create-a-particular-initial-state-as-a-mps">http://www.itensor.org/support/1359/how-to-create-a-particular-initial-state-as-a-mps</a></p>
<p>You don't need to worry about the link indices, the <code>MPS (sites)</code> constructor makes a product state with only site indices. If you use your MPS in an algorithm that increases the bond dimension (such as 2-site DMRG or TEBD), the link indices will get "generated" by the SVD.</p>
http://itensor.org/support/1357/setting-random-initial-product-state?show=1366#a1366Mon, 11 Mar 2019 21:35:27 +0000Answered: Is there a way to get\set slices of a tensor?
http://itensor.org/support/1360/is-there-a-way-to-get-set-slices-of-a-tensor?show=1365#a1365
<p>The most straightforward way I can think to do it right now is the following:</p>
<pre><code>auto i = Index("i", 2);
auto j = Index("j", 2);
auto k = Index("k", 2);
auto A = ITensor(i, j, k);
auto B = ITensor(i, j);
A.fill(0.0);
B.fill(1.0);
for(int ii = 1; ii <= i.m(); ii++)
for(int jj = 1; jj <= j.m(); jj++)
A.set(i(ii),j(jj),k(2), B.real(i(ii),j(jj)));
</code></pre>
<p>We would definitely like to support a nicer interface for this kind of slicing. However, it requires some thinking to figure out the right interface for slicing into a QN conserving/block sparse ITensor. It may be a little while before we get to it, but it is on our todo list!</p>
http://itensor.org/support/1360/is-there-a-way-to-get-set-slices-of-a-tensor?show=1365#a1365Mon, 11 Mar 2019 21:28:03 +0000Answered: Krylov Subspace Method to the Matrix Exponential for TDVP
http://itensor.org/support/1337/krylov-subspace-method-to-the-matrix-exponential-for-tdvp?show=1340#a1340
<p>Hi Titas,<br>
Regarding Krylov, this is a good idea for a low-level algorithm we should supply with ITensor. However, this is in addition to many other things we should or would like to add (tensor slicing, other algorithms, etc) so it may take some time for us to add Krylov.</p>
<p>But in the meantime, it is something that should be quite possible to implement yourself. Good examples of similar algorithms written in ITensor can be found in this file:<br>
<a rel="nofollow" href="https://github.com/ITensor/ITensor/blob/master/itensor/iterativesolvers.h">https://github.com/ITensor/ITensor/blob/master/itensor/iterativesolvers.h</a><br>
In that file there are the Arnoldi, gmres, and Davidson algorithms. </p>
<p>These all follow similar principles, which is that one multiplies a large linear operator onto an initial 'state' or vector, then orthogonalizes the resulting produced vector against all previously produced vectors from earlier in the algorithm to build a Krylov subspace. Then one solves the desired problem, whether an eigenvalue or Ax=b problem etc., within the Krylov space.</p>
<p>The key operations of ITensor taking place in each of these algorithms are just contracting ITensors together (used when multiplying the vectors by the large linear operator and dot-producting the vectors with each other) and addition of ITensors. Most of the code is just dealing with scalars and small matrices to enact the logic of the algorithm, and to check for convergence and things.</p>
<p>Finally, regarding extracting the data of a dense ITensor, you can refer to this code formula page:<br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv2&page=formulas/extractdense">http://itensor.org/docs.cgi?vers=cppv2&page=formulas/extractdense</a><br>
Please ask if you have a question about that page.</p>
<p>Unfortunately, things aren't as simple for extracting storage of block-sparse tensors i.e. IQTensors. I could give you a similar code to the above that would extract the low level storage of an IQTensor, but you'd still need to know how this storage is organized to read out the different blocks properly. Let me know if you definitely decide you need to do that. But it could be easier to just convert the IQTensor to a dense ITensor and then read that out instead.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1337/krylov-subspace-method-to-the-matrix-exponential-for-tdvp?show=1340#a1340Fri, 01 Mar 2019 18:47:47 +0000Answered: evolution with complicated Hamiltonian using Trotter gates
http://itensor.org/support/1330/evolution-with-complicated-hamiltonian-using-trotter-gates?show=1333#a1333
<p>You can just add a if sentence in your for loop.<br>
Something like:<br>
hterm +=sites.op("Sx",b);<br>
if(b == N-1) hterm +=sites.op("Sx",b+1);</p>
http://itensor.org/support/1330/evolution-with-complicated-hamiltonian-using-trotter-gates?show=1333#a1333Fri, 01 Mar 2019 00:28:24 +0000Answered: spinless bosons
http://itensor.org/support/1310/spinless-bosons?show=1329#a1329
<p>Hi AbraDabra,<br>
This is a site set type we should offer. We're working on it! </p>
<p>But in the meantime, yes, you can create your own kind of site set for this case by copying one of the existing ones (such as "Spinless") and creating a new file and a new site set (perhaps boson.h and "class BosonSite" and "class Boson").</p>
<p>Though Mingru is correct that sometimes just having a maximum site occupancy of 1 is enough, in general that's not the case, very much depending on the particular Hamiltonian.</p>
<p>But for many cases, you can truncate the maximum occupancy to, say, 3 or 4 without incurring much error. You should raise and lower this maximum occupancy and check that your results are converged with respect to it.</p>
<p>For the operators you'll need to define, here is an example for maximum occupancy of 3:</p>
<pre><code>ITensor
op(std::string const& opname,
Args const& args) const
{
auto sP = prime(s); //here "s" is the site index stored in this BosonSite object
IQIndexVal Emp(s(1)),
EmpP(sP(1)),
One(s(2)),
OneP(sP(2)),
Two(s(3)),
TwoP(sP(3)),
Three(s(4)),
ThreeP(sP(4));
if(opname == "N" || opname == "n")
{
Op(One,OneP) = 1;
Op(Two,TwoP) = 2;
Op(Three,ThreeP) = 3;
}
else
if(opname == "A")
{
Op(One,EmpP) = 1;
Op(Two,OneP) = std::sqrt(2);
Op(Three,TwoP) = std::sqrt(3);
}
else
if(opname == "Adag")
{
Op(Emp,OneP) = 1;
Op(One,TwoP) = std::sqrt(2);
Op(Two,ThreeP) = std::sqrt(3);
}
</code></pre>
<p>If you'd like to post your code when you're done with a first draft or have some more specific questions please just post a comment or a new question -</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1310/spinless-bosons?show=1329#a1329Thu, 28 Feb 2019 16:21:31 +0000Answered: declaration of the variable
http://itensor.org/support/1311/declaration-of-the-variable?show=1313#a1313
<p>Hello,</p>
<p>In your first code, you just have to initialize <code>hterm</code> before the if statement:</p>
<pre><code>for(int i = L-1; i >= 1; --i)
{
IQTensor hterm;
if (i % 2 == 0)
{
hterm = sites.op("Adag",i)*sites.op("A",i+1);
hterm += sites.op("A",i)*sites.op("Adag",i+1);
}
else
{
hterm = 2.0*sites.op("Adag",i)*sites.op("A",i+1);
hterm += 2.0*sites.op("A",i)*sites.op("Adag",i+1);
}
auto g = Gate(sites,i,i+1,Gate::tReal,tstep/2.,hterm);
gates.push_back(g);
}
</code></pre>
<p>(assuming you are using QNs, otherwise you need to initialize with <code>ITensor hterm</code>).</p>
<p>In your second code, it looks like there is just a small mistake in the code. Instead of:</p>
<pre><code> auto hterm = sites.op("Adag",i)*sites.op("A",i+1);
hterm += sites.op("A",1)*sites.op("Adag",i+1);
</code></pre>
<p>it should be:</p>
<pre><code> auto hterm = sites.op("Adag",i)*sites.op("A",i+1);
hterm += sites.op("A",i)*sites.op("Adag",i+1);
</code></pre>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1311/declaration-of-the-variable?show=1313#a1313Wed, 27 Feb 2019 14:34:52 +0000Answered: Swap gate in a system with alternating QN
http://itensor.org/support/1309/swap-gate-in-a-system-with-alternating-qn?show=1312#a1312
<p>Hi Mingru,</p>
<p>Can you just create a set of swap gates using delta functions? i.e. for sites 5 and 6 with indices <code>s5</code> and <code>s6</code>, make the swap gate:</p>
<pre><code>auto swap56 = delta(s5,prime(s6))*delta(s6,prime(s5));
</code></pre>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1309/swap-gate-in-a-system-with-alternating-qn?show=1312#a1312Wed, 27 Feb 2019 14:28:53 +0000Answered: time-dependent Hamiltonian
http://itensor.org/support/1283/time-dependent-hamiltonian?show=1308#a1308
<p>Thank you very much, Miles. I would like to specify the 2nd point of your answer. I understand what you mean, but I can't imagine how it can be done. Could you please write an example. </p>
<p>For instance, how one can replace 'delt' by the function 'delt(t)'</p>
<pre><code> float delt(float t)
{
return 0.5* sin(t);
}
</code></pre>
<p>snippet for Trotter gates</p>
<pre><code>for(int b = 1; b <= N-1; ++b)
{
auto hterm = delt*sites.op("Sz",b)*sites.op("Sz",b+1);
hterm += delt*sites.op("S+",b)*sites.op("S-",b+1);
hterm += delt* sites.op("S-",b)*sites.op("S+",b+1);
auto g = Gate(sites,b,b+1,Gate::tReal,tstep/2.,hterm);
gates.push_back(g);
}
</code></pre>
<p>(and the same for the reverse oder)<br>
time evolve </p>
<pre><code> gateTEvol(gates,ttotal,tstep,psi,{"Cutoff=",cutoff,"Verbose=",true});
</code></pre>
<p>Is there any detailed documentation of 'gateTEvol' function?</p>
<p>Although, I know one of the solutions, which is to divide the total time by N small steps and perform Trotter evolution N times. But i think it is the worst solution. <br>
Thank you in advance!</p>
http://itensor.org/support/1283/time-dependent-hamiltonian?show=1308#a1308Tue, 26 Feb 2019 20:26:14 +0000Answered: must be converted to an ITensor prior to usage
http://itensor.org/support/1305/must-be-converted-to-an-itensor-prior-to-usage?show=1306#a1306
<p>Yes this is an unfortunate issue with version 2 of ITensor. The soon to be released version 3 will fix this issue. </p>
<p>By convert to ITensor, what is meant is this:</p>
<pre><code>ITensor Sxb = sites.op(“Sx”,b);
</code></pre>
<p>And similar for the other operator. Then you can multiply these ITensors together. </p>
http://itensor.org/support/1305/must-be-converted-to-an-itensor-prior-to-usage?show=1306#a1306Tue, 26 Feb 2019 08:24:57 +0000Answered: Measure multi-site (more than 2) correlation
http://itensor.org/support/1228/measure-multi-site-more-than-2-correlation?show=1303#a1303
<p>Thanks very much for posting a solution, and glad you figured it out! </p>
<p>For those looking for the answer, please see the above comments by the original poster ^</p>
http://itensor.org/support/1228/measure-multi-site-more-than-2-correlation?show=1303#a1303Mon, 25 Feb 2019 08:16:16 +0000Answered: Phase convention of SVD in iTensor
http://itensor.org/support/1287/phase-convention-of-svd-in-itensor?show=1289#a1289
<p>Hi Steve,</p>
<p>As far as I know, there is no particular reason for the phase choice in ITensor, and it is something that could be chosen after the decomposition is performed. Right now, ITensor uses it's own implementation of the SVD (based on recursive eigendecompositions), but we would like to add options for users to choose to use LAPACK versions of the SVD. I believe that Numpy calls LAPACK routines (either *gesvd or *gesdd), so that may be the reason for the difference in the phase.</p>
<p>Note that for degenerate singular values, the gauge degree of freedom is actually an entire unitary rotation of the degenerate subspace, not just a simple phase degree of freedom, so in general there is no fixed convention and you will likely see different results in different numerical libraries.</p>
<p>If you are interested in a decomposition with a fixed phase (for some reason), note that a good option could be the polar decomposition, @@A = QP@@ where @@Q@@ is an isometry and @@P@@ is a positive Hermitian matrix (<a rel="nofollow" href="https://en.wikipedia.org/wiki/Polar_decomposition">https://en.wikipedia.org/wiki/Polar_decomposition</a> ). This can be very simply obtained from an SVD, @@A = U S V^{\dagger} = (U V^{\dagger}) (V S V^{\dagger})@@, so @@Q = U V^{\dagger}@@ and @@P = V S V^{\dagger}@@. Note that @@Q@@ is only an isometry if no truncation in the SVD is performed (and @@m > n@@ for @@m \times n@@ matrix @@A@@).</p>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1287/phase-convention-of-svd-in-itensor?show=1289#a1289Thu, 21 Feb 2019 14:29:10 +0000Product of operators
http://itensor.org/support/1288/product-of-operators
<p>Hello,</p>
<p>I want to construct some operators like these $$\sigma^{\alpha_1}_1 \otimes... \otimes\sigma^{\alpha_N}_N$$ One way would be to use the autoMPO constructor but how can I construct the necessary loop? A much easier way would be to create the tensor product of consecutive sites but I don't seem to find such function, does it exist?</p>
<p>Thank you</p>
http://itensor.org/support/1288/product-of-operatorsThu, 21 Feb 2019 08:33:39 +0000Answered: number_of_particles
http://itensor.org/support/1280/number_of_particles?show=1282#a1282
<p>Good question, since it's kind of a subtle thing in ITensor. For codes using quantum-number conserving tensors, such as when doing DMRG calculations, the quantum numbers present in any wavefunction are not allowed to change. So the number is set by how you make your initial state.</p>
<p>So if you set your initial state to have 3 up and 1 down particles, and use QN conserving tensors, then the number will not change. </p>
<p>Please let me know if you still have a question of course!</p>
<p>Miles</p>
http://itensor.org/support/1280/number_of_particles?show=1282#a1282Mon, 18 Feb 2019 07:18:33 +0000Answered: Segmentation Fault with Combiner
http://itensor.org/support/1271/segmentation-fault-with-combiner?show=1272#a1272
<p>Hi, thanks for the bug report. We'd like to strive to make all of the sample code on the website compile, so this is helpful. But sometimes the codes on the site skip over a few steps, such as setting elements of tensors when initializing them, which can lead to errors.</p>
<p>I just updated the code on that page and it runs now. What I added was a line </p>
<pre><code>randomize(T);
</code></pre>
<p>that sets the elements of the tensor T to be random elements. That allows the rest of the code to run correctly. The reason you were getting that error is that no elements of T had been set, so T had no storage. In the future we'll fix combiners to work even for this case.</p>
<p>One other note is that, if you get an error like a segmentation fault, please try compiling and running your code in "debug mode". <br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?page=formulas/debug_mode">http://itensor.org/docs.cgi?page=formulas/debug_mode</a></p>
<p>Running your code this way will help to give more informative error messages. </p>
<p>Glad you are trying out ITensor!</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1271/segmentation-fault-with-combiner?show=1272#a1272Thu, 14 Feb 2019 20:06:13 +0000Answered: Installation
http://itensor.org/support/1260/installation?show=1269#a1269
<p>For cygwin, I don't know if I recall all of the libraries and correct settings, but I believe the key ones are:</p>
<ol>
<li><p>install the lapack and lapack-devel (or similarly named) libraries with Cygwin</p></li>
<li><p>in your "options.mk" file, comment out ("#") the lines PLATFORM=macos and BLAS<em>LAPACK</em>LIBFLAGS=-framework Accelerate, because as you can see from the comments above those lines, those are the settings for Mac / Apple systems</p></li>
<li><p>uncomment the PLATFORM and BLAS<em>LAPACK</em>LIBFLAGS just below, suitable for general GNU/LINUX systems</p></li>
</ol>
<p>I think with those changes it should compile and work. But if you get other error messages please let me know.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1260/installation?show=1269#a1269Thu, 14 Feb 2019 06:10:18 +0000Answered: Applying Trotter gate to MPS or MPO
http://itensor.org/support/1252/applying-trotter-gate-to-mps-or-mpo?show=1266#a1266
<p>Hi Steve,</p>
<p>1) That is correct, putting the gauge position where the gate is being applied is meant to help minimize the truncation error. Basically, using that gauge center allows one to treat the local tensors (the contraction of the MPS tensors with the gate you are applying) as the square root of the density matrix on those sites, and therefore the best low-rank approximation is truncating according to the singular values. An early reference on this is: </p>
<p><a rel="nofollow" href="https://arxiv.org/abs/cond-mat/0605597">https://arxiv.org/abs/cond-mat/0605597</a></p>
<p>Note that this is essentially the same issue that comes up in 2-site DMRG, that it is best to perform DMRG when the gauge center of the wavefunction is located on the sites you are optimizing, which makes the eigenvector equation simpler and the truncation of the bond dimension using the singular value decomposition optimal.</p>
<p>2) Time evolution of 2D systems is definitely a a tricky subject. There are a few methods available for doing it. As you mention, one approach is to make use of swap gates to move the trotter gates so they become local for the MPS. Another approach is to turn the non-local gates into an MPO. There are also other approaches available for performing time evolution with non-local Hamiltonians, like the time dependent variation principle (TDVP). Here are some references with discussions about these approaches (these are just some that come to mind, but it is a large literature at this point):</p>
<p><a rel="nofollow" href="https://arxiv.org/abs/1002.1305">https://arxiv.org/abs/1002.1305</a><br>
<a rel="nofollow" href="https://arxiv.org/abs/1407.1832v1">https://arxiv.org/abs/1407.1832v1</a><br>
<a rel="nofollow" href="https://arxiv.org/abs/1705.05578">https://arxiv.org/abs/1705.05578</a><br>
<a rel="nofollow" href="https://arxiv.org/abs/1901.05824">https://arxiv.org/abs/1901.05824</a></p>
<p>Note that time evolving MPOs can be even more subtle. There is a problem that naively truncating the MPO with an SVD, as one would do with an MPS, can cause the MPO to possibly become non-positive. Positivity is a property one wants to preserve if the MPO represents a density matrix, and introducing negative eigenvalues can lead to numerical instability in the evolution. Here is a paper discussing that issue, which is addressed with a new technique called density matrix truncation (DMT):</p>
<p><a rel="nofollow" href="https://arxiv.org/abs/1707.01506">https://arxiv.org/abs/1707.01506</a></p>
<p>If you have questions about implementing these methods in ITensor, please don't hesitate to ask. It is difficult to give more guidance without more specifics about the calculations you want to perform.</p>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1252/applying-trotter-gate-to-mps-or-mpo?show=1266#a1266Wed, 13 Feb 2019 17:22:43 +0000Answered: Entanglement entropy of multiple partitions
http://itensor.org/support/1263/entanglement-entropy-of-multiple-partitions?show=1264#a1264
<p>Hello,</p>
<p>Someone please correct me if I am wrong, but I believe the only way is to calculate the reduced density matrix for subsystem A and then calculate the entanglement entropy from the reduced density matrix (for example by diagonalizing the reduced density matrix and using the eigenvalues in whichever entanglement entropy you are interested in). This page has a code formula for calculating the reduced density matrix of disjoint subsystems:</p>
<p><a rel="nofollow" href="http://www.itensor.org/docs.cgi?vers=cppv3&page=formulas/mps_two_rdm">http://www.itensor.org/docs.cgi?vers=cppv3&page=formulas/mps_two_rdm</a></p>
<p>The entanglement entropy can then be calculated from the eiganvalues of the reduced density matrix in the same way as at the bottom of this formula:</p>
<p><a rel="nofollow" href="http://www.itensor.org/docs.cgi?vers=cppv3&page=formulas/entanglement_mps">http://www.itensor.org/docs.cgi?vers=cppv3&page=formulas/entanglement_mps</a></p>
<p>This would become inefficient when dealing with larger subsystems (since the density matrix grows exponentially with the number of sites in A), so perhaps there is a more clever way that I am not aware of.</p>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1263/entanglement-entropy-of-multiple-partitions?show=1264#a1264Wed, 13 Feb 2019 14:09:51 +0000Creating SU(2)xSU(2) site set.
http://itensor.org/support/1262/creating-su-2-xsu-2-site-set
<p>Hello world, </p>
<p>I'm interested in constructing a custom site set for SU(2)xSU(2) fermions, i.e. fermions with spin-1/2 and pseudospin-1/2. I keep reading in the docs that the SiteSets can be mixed with other SiteSets, so I assume I could mix two instances of Hubbard SiteSet to produce what I'm looking for; however, I can't seem to find any good information or tutorials on how to create custom SiteSets.</p>
<p>Where could one find such information?<br>
Any direction, resources, or suggestions would be great!</p>
http://itensor.org/support/1262/creating-su-2-xsu-2-site-setTue, 12 Feb 2019 21:35:00 +0000Answered: std::bad_alloc in spin-polarized system
http://itensor.org/support/1254/std-bad_alloc-in-spin-polarized-system?show=1258#a1258
<p>Hello, I solved this problem.<br>
This problem is due to my little knowledge of the efficient MPS contraction.</p>
<p>The Tensor</p>
<pre><code> psi.A(2) * prime(dag(psi.A(2))
</code></pre>
<p>has a very big index dimension, but what I'd like to do is calculate a correlation function.<br>
So I should do:</p>
<pre><code>lcorr *= psi.A(2);
lcorr *= prime(dag(psi.A(2)), Link);
</code></pre>
<p>where "lcorr" follows basic notation in the ITensor code formula.</p>
<p>Thank you every one.</p>
http://itensor.org/support/1254/std-bad_alloc-in-spin-polarized-system?show=1258#a1258Sat, 09 Feb 2019 00:55:02 +0000Answered: MPS & MPOs as a function of a for loop variable
http://itensor.org/support/1255/mps-%26-mpos-as-a-function-of-a-for-loop-variable?show=1256#a1256
<p>Hi Ipsita,<br>
The direct answer to your question is that, whichever procedure you are using to make your MPO necessarily includes "h" as a parameter. (Say using AutoMPO, where "h" appears as a coefficient.) So then to change h, you just re-create the MPO again from the beginning, using a different value for h.</p>
<p>However, the other answer I would give to your question is to say, I don't recommend doing a lot of different calculations (I assume DMRG?) in a loop. Instead, I think it's a much better practice to do each calculation separately, and carefully study each one. How well did it go? Were all indications that it converged? Is the system approaching a phase boundary where perhaps the initial state and number of sweeps needed for convergence might need to be changed?</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1255/mps-%26-mpos-as-a-function-of-a-for-loop-variable?show=1256#a1256Fri, 08 Feb 2019 21:52:25 +0000Answered: Getting RDM of a RDM Eigenvector
http://itensor.org/support/1233/getting-rdm-of-a-rdm-eigenvector?show=1247#a1247
<p>Good question. Yes, the sample code you wrote is very much on track with what you should do. The main issue you might run into with that code, though, is that rdmEvec will not be an MPS, but just a single tensor, so you can't call .position on it (though I know what you were meaning by writing that in your code). </p>
<p>Instead, what you should do is prepare a new MPS object of size La, and set the tensors of it to be those of your original MPS together with the modified tensor at the edge where you "cut" and project onto the RDM eigenvector. </p>
<p>Then you can call .position on this new, shorter, MPS and do the rest of the calculation the way you wrote it.</p>
<p>I'd definitely suggest testing on a system where you already know the correct answer to ensure everything is working! Or to test in some other way before just assuming the code is correct, even if it runs ok.</p>
http://itensor.org/support/1233/getting-rdm-of-a-rdm-eigenvector?show=1247#a1247Wed, 30 Jan 2019 06:56:06 +0000