ITensor Support Q&A - Recent questions
http://itensor.org/support/questions
Powered by Question2AnswerEntanglement entropy (Julia)
http://itensor.org/support/2423/entanglement-entropy-julia
<p>Hello, <br>
how we can calculate the entanglement entropy of an half chain with Julia?<br>
I am trying to adapt the following lines of code which are given for C++</p>
<p>Thanks a lot! <br>
Jacopo</p>
<p>auto b = 10;</p>
<p>//"Gauge" the MPS to site b<br>
psi.position(b); </p>
<p>//SVD this wavefunction to get the spectrum<br>
//of density-matrix eigenvalues<br>
auto l = leftLinkIndex(psi,b);<br>
auto s = siteIndex(psi,b);<br>
auto [U,S,V] = svd(psi(b),{l,s});<br>
auto u = commonIndex(U,S);</p>
<p>//Apply von Neumann formula<br>
//to the squares of the singular values<br>
Real SvN = 0.;<br>
for(auto n : range1(dim(u)))<br>
{<br>
auto Sn = elt(S,n,n);<br>
auto p = sqr(Sn);<br>
if(p > 1E-12) SvN += -p*log(p);<br>
}</p>
http://itensor.org/support/2423/entanglement-entropy-juliaWed, 05 Aug 2020 15:32:47 +0000Jordan wigner fermi string in self-writing AutoMPO
http://itensor.org/support/2422/jordan-wigner-fermi-string-in-self-writing-autompo
<p>I'm working on a 3-flavor fermion model on DMRG and coming up with the correlation of fermion operator.<br>
I don't know the rule of Jordan Wigner string "F" in this situation. Please give me some info about how AutoMPO deal with self-writing Fermions</p>
http://itensor.org/support/2422/jordan-wigner-fermi-string-in-self-writing-autompoWed, 05 Aug 2020 10:06:32 +0000SVD swapping index arrow in TEBD algorithm with conserved quantum numbers
http://itensor.org/support/2421/swapping-index-arrow-algorithm-conserved-quantum-numbers
<p>Hello,<br>
I am implementing the TEBD algorithm in Vidal's gauge (G. Vidal, PRL 98 2007) in presence of conserved quantum numbers and I get some error regarding the indices’ arrows. <br>
I report here a minimal example code that reproduces the issue:</p>
<pre><code>auto sites = SpinHalf(N,{"ConserveQNs=",true});
auto init = InitState(sites);
for(auto n : range1(N))
{
init.set(n, n%2 == 1 ? "Up" : "Dn");
}
auto psi = MPS(init);
std::vector<ITensor> lambda(N-1);
for(int i=1; i<= N-1; i++)
{
auto u= commonIndex(psi(i),psi(i+1));
lambda.at(i-1) = ITensor(dag(u), prime(u));
lambda.at(i-1).set(dag(u)(1), prime(u)(1), 1.);
}
for(int b= 1; b<N; b++){
ITensor A = psi(b);
ITensor B = psi(b+1);
Print(lambda.at(b-1));
A = noPrime(lambda.at(b-1)*A);
auto AA = A*B;
auto u= commonInds(A,AA);
auto [U,S,V] = svd(AA,u,{"Truncation=", false});
lambda.at(b-1) = S;
psi.ref(b) = U;
psi.ref(b+1) = V;
}
</code></pre>
<p>Here, I initialize the system in a product state and define the lambda matrices in the second loop. After this procedure, the indices' arrows of the lambdas have the correct direction in and out. <br>
Then, to avoid priming/unpriming indices in the lambdas, I perform the svd in the third loop, that should just change the indices from (i,i') to (i,j). Nevertheless, I observe that after contraction with the state at a local site psi(i) and SVD the direction of one of the arrows changes from in to out, thus making the contraction with the following site impossible. Furthermore, here the lambda acquires a fictitious bond dimension d=2 and its norm becomes larger by a factor sqrt(2). Please notice that the code does not show the actual TEBD, but just the minimal working patch that reproduces the issue.<br>
Even though it might be possible to fix this issue, at least for what concerns the wrong arrows, by manually change the direction of the troublesome index, I feel like there must be something I am missing and an easier solution.<br>
As this seems to involve the svd routine, I hope you could give some insightful answer to this issue.</p>
<p>Pietro</p>
http://itensor.org/support/2421/swapping-index-arrow-algorithm-conserved-quantum-numbersTue, 04 Aug 2020 10:27:27 +0000Purpose of various actions and parameters in replacebond! function?
http://itensor.org/support/2418/purpose-various-actions-parameters-replacebond-function
<p>I am curious about the purpose of various actions and parameters within the replacebond! function in src/mps/mps.jl. Some of these things don't have obvious use in the code, or I tried to look into the ITensors.jl code for them but didn't get much clarity. Since I am trying to make modified versions of this function for various purposes, I thought I should make sure I understand all of the parts.</p>
<p>(1) What is the purpose of spec, and of the Spectrum object type more generally? I see that spec comes from the factorization "L,R,spec = factorize(...)", and I see that it is returned at the end of the replacebond! function, but what is it supposed to accomplish? In particular, when the dmrg function calls replacebond!, it doesn't use spec for anything, as far as I can tell.</p>
<p>(2) I see that the normalize parameter is set to false by default. Under what circumstances would one likely wish to set it to true, and in such situations, what is it meant to accomplish? I see the lines of the form "normalize && (M[b] ./= norm(M[b]))" near the end of the method, but it's not clear to me when we should be using this and why by default we choose not to.</p>
<p>(3) What is the purpose of setleftlim! and setrightlim!, and more broadly, what is the purpose of leftlim and rightlim at all? I see lines of the form "leftlim(M) == b-1 && setleftlim!(M, leftlim(M)+1)" near the end of the method, but again, it's not clear to me why we are doing this. I notice that we increase leftlim(M) and rightlim(M) by 1 when ortho == "left" and decrease both by 1 when ortho == "right", so that part makes sense (i.e. sweeping to the left versus sweeping to the right). But what is this trying to achieve? And in general, what values are leftlim(M) and rightlim(M) supposed to be in a given situation?</p>
http://itensor.org/support/2418/purpose-various-actions-parameters-replacebond-functionTue, 28 Jul 2020 17:45:13 +0000Julia script for calculating energy gaps
http://itensor.org/support/2411/julia-script-for-calculating-energy-gaps
<p>Hi there,</p>
<p>Is there any existing Julia script for calculating exited MPS states using DMRG? I could only find the C++ version <a rel="nofollow" href="https://www.itensor.org/docs.cgi?page=formulas/excited_dmrg&vers=cppv3">here</a>.</p>
http://itensor.org/support/2411/julia-script-for-calculating-energy-gapsTue, 28 Jul 2020 10:29:23 +0000A Question for the Input Tensor
http://itensor.org/support/2410/a-question-for-the-input-tensor
<p>Hi</p>
<p>Do you happen to have a script/code to generate the input tensors for different scenarios? </p>
<p>We’re thinking of saving the tensors from ITensor to a file (in the format widely adopted in HPC sparse tensor community), which can be used to test other packages for your applications as well. </p>
<p>Thanks!<br>
Jiawen</p>
http://itensor.org/support/2410/a-question-for-the-input-tensorTue, 28 Jul 2020 03:25:05 +0000How do you separate product of two ITensor objects if the two tensors do not have any common indices? (Julia)
http://itensor.org/support/2403/separate-product-itensor-objects-tensors-common-indices-julia
<p>As an example, suppose the first and last sites of an MPS M are combined into an ITensor as phi = M[1] * M[N]. Then you perform some optimization that changes phi, for instance eigsolve using some other tensor as the "matrix" and phi as the "vector." Now I want to put the updated value of phi back into M[1] and M[N], but this requires me to somehow split the ITensor so that the two resulting ITensor objects have the same index structure as M[1] and M[N], respectively. How do I do this?</p>
<p>In regular DMRG, this is done using the factorize method, but I'm pretty sure this only works when the two things you want to separate have an index in common. For instance, if you do phi = M[1] * M[2], then since M[1] and M[2] share a common index, then the appropriate factorization will "sever" the appropriate bond between the two tensors, thus giving you one tensor with the same index structure as M[1] and one tensor with the same index structure as M[2].</p>
<p>However, when I tried this, it doesn't work. In particular, the code seems to introduce a new index to bind the two tensors together. To show an example using code, I did phi = M[1] * M[2] * M[3] * M[6] * M[7] * M[8] on an 8-site MPS M. Then, after doing some changes to phi using eigsolve, I wanted to separate it into M[1] * M[2] * M[3] and M[6] * M[7] * M[8] (each of which can then be separated using further factorize commands). I tried to do so using the following command:</p>
<pre><code>index_list = Index[]
for j=1:3
append!(index_list, inds(M[j]))
end
index_set = IndexSet(index_list)
L,R,spec = factorize(phi, index_set; which_decomp = which_decomp,
tags = tags(linkind(M,3)),
kwargs...)
</code></pre>
<p>But the result I got was the following:</p>
<pre><code>left side of phi:
IndexSet{5} (dim=2|id=16|"S=1/2,Site,n=1") (dim=2|id=978|"S=1/2,Site,n=2")
(dim=2|id=311|"S=1/2,Site,n=3") (dim=1|id=305|"Link,l=3") (dim=8|id=372|"Link,l=3")
right side of phi:
IndexSet{5} (dim=8|id=372|"Link,l=3") (dim=1|id=608|"Link,l=5")
(dim=2|id=514|"S=1/2,Site,n=6") (dim=2|id=558|"S=1/2,Site,n=7")
(dim=2|id=515|"S=1/2,Site,n=8")
</code></pre>
<p>Notice the new index (dim=8|id=372|"Link,l=3") used to connect the two tensors. I don't want to do this--I just want to separate the two tensors so that they have the same index structure as before. How do I do this? It's possible that factorization isn't the right term to describe this.</p>
http://itensor.org/support/2403/separate-product-itensor-objects-tensors-common-indices-juliaSat, 25 Jul 2020 06:57:12 +0000Using IQTensor for general states
http://itensor.org/support/2395/using-iqtensor-for-general-states
<p>Hi,</p>
<p>I have a question about IQTensor following that of <a rel="nofollow" href="http://itensor.org/support/1126/superposed-states-with-iqtensor.">http://itensor.org/support/1126/superposed-states-with-iqtensor.</a> Say I need to calculate O|psi> where O preserves some symmetry G but |psi> does not. That being said, |psi> can (as always) be decomposed into G eigenvectors such that each has a block structure.</p>
<p>My understanding is that the quantum number is taken care by the "boundary tensor". (correct me if I'm wrong.) That's to say, all tensors apart from the boundray one has divergence 0, while the divergence of the boundary one agrees with the quantum number. So a block-structured of |psi> is possible by a proper definition of the boundary one (i.e. a sum of tensors w/ different divergences) and it would still be efficient if I make use of the symmetry throughout. Is that correct?</p>
<p>Best,<br>
Chengshu</p>
http://itensor.org/support/2395/using-iqtensor-for-general-statesFri, 24 Jul 2020 18:42:19 +0000Swapping indices of an MPS for Hubbard
http://itensor.org/support/2379/swapping-indices-of-an-mps-for-hubbard
<p>Hello,</p>
<p>I have written a code that creates MPS's as a product of valence bonds for Hubbard. The code works fine for the cases where the valence bonds have adjacent sites., ie. for 6 sites: 1-2 3-4 5-6, 1-2 5-6 3-4, etc. My guess is that I am doing something wrong when I swap the indices and there must be a difference for Hubbard and Heisenberg, because for Heisenberg the same swapping part of the code works. Below is the code I have written:</p>
<pre><code> ITensor wf, S,V,U;
for (int i=swaps_.size()-1; i>=0; i--){
// swaps_ has all the swaps that are necessary so that I get the pattern that I want.
// swaps_ is calculated somewhere else, but I do not think it matters for the code below.
// Below is some code that gets the indices, again, not super important I think.
ar1 = swaps_[i].first;
ar2 = swaps_[i].second;
s1.clear(); s1.push_back(siteIndex(psi,ar1));
s2.clear(); s2.push_back(siteIndex(psi,ar2));
auto is1 = IndexSet(s1);
auto is2 = IndexSet(s2);
// And below comes the swapping part that works for Heisenberg.
psi.position(ar1);
wf = psi.A(ar1)*psi.A(ar2);
wf.swapInds(is1,is2);
wf.noPrime();
U = psi.A(ar1);
svd(wf,U,S,V,{"Cutoff=",1E-8});
psi.setA(ar1,U);
psi.setA(ar2,S*V);
}
</code></pre>
<p>Does anyone have any input maybe? Am I missing a sign for the fermionic wavefunction somehow that disturbs the final result? Could the error be somewhere else? The Hubbard that I am using preserves all quantum numbers.</p>
<p>Thank you,<br>
Thanos</p>
http://itensor.org/support/2379/swapping-indices-of-an-mps-for-hubbardWed, 22 Jul 2020 16:49:16 +0000Why is a ProjMPO callable but an ITensor not? (Julia)
http://itensor.org/support/2376/why-is-a-projmpo-callable-but-an-itensor-not-julia
<p>I am working on certain modifications to ITensors.jl for my own applications, and one thing I want to play with is how to do an optimization step with sites from both ends of the chain (e.g. optimizing sites N and 1 while everything else stays fixed).</p>
<p>To this end, the ProjMPO structure seemed too rigid, so I contracted the other tensors into an ITensor object in the most standard way, as follows:</p>
<pre><code>M = copy(H[1])
for j=2:N-1
M *= H[j] * psi[j] * dag(prime(psi[j]))
end
M *= H[N]
</code></pre>
<p>So far, so good. However, when I then tried to call eigsolve afterward, I got the following error: "ERROR: LoadError: MethodError: objects of type ITensor{8} are not callable".</p>
<p>I looked into the source code to better understand what was going on, but I didn't really get anywhere. To this end, I want to ask the following: what in the code makes a ProjMPS "callable" but an ITensor not, and why was this choice made?</p>
http://itensor.org/support/2376/why-is-a-projmpo-callable-but-an-itensor-not-juliaWed, 22 Jul 2020 09:28:20 +0000When ITensors in dev mode, modifications to existing functions are recognized but new functions are not
http://itensor.org/support/2375/itensors-modifications-existing-functions-recognized-functions
<p>I have a question regarding ITensors.jl in development mode. I have ITensors in the .julia/dev folder, since I am trying to made modifications to the ITensors.jl code itself for my applications.</p>
<p>I have noticed that, if I modify an existing method in a file in ITensors (for instance, adding a print statement to one of the dmrg functions in src/mps/dmrg.jl), I can see that change reflected immediately in any code I run that calls that function. However, if I create a new method in one of the existing files, then this change fails. Just as an example, I did this with a very simple addition to src/mps/dmrg.jl:</p>
<pre><code>function test_function()
println("You made it!")
return 0
end
</code></pre>
<p>I then made another file with just two lines of code:</p>
<pre><code>using ITensors
my_var = test_function()
</code></pre>
<p>And here is the output I got when running this file:</p>
<pre><code>ERROR: LoadError: UndefVarError: test_function not defined
Stacktrace:
[1] top-level scope at d:\Sujay Google Drive\Julia
Files\J1_J2_model_custom_periodic_dmrg.jl:32
[2] include(::String) at .\client.jl:439
[3] startdebug(::Base.PipeEndpoint, ::VSCodeDebugger.var"#3#4"{Tuple{String,String}})
at c:\Users\user\.vscode\extensions\julialang.language-julia-
0.17.7\scripts\packages\DebugAdapter\src\packagedef.jl:89
[4] startdebugger() at c:\Users\user\.vscode\extensions\julialang.language-julia-
0.17.7\scripts\packages\VSCodeDebugger\src\VSCodeDebugger.jl:38
[5] top-level scope at c:\Users\user\.vscode\extensions\julialang.language-julia-
0.17.7\scripts\debugger\run_debugger.jl:7
[6] include(::Module, ::String) at .\Base.jl:377
[7] exec_options(::Base.JLOptions) at .\client.jl:288
[8] _start() at .\client.jl:484
in expression starting at d:\Sujay Google Drive\Julia
Files\J1_J2_model_custom_periodic_dmrg.jl:32
</code></pre>
<p>Why is this? Is there something different about creating a new function, as opposed to modifying an existing one, that leads to the former change not being incorporated into some other piece of code that uses that function? I can post </p>
http://itensor.org/support/2375/itensors-modifications-existing-functions-recognized-functionsWed, 22 Jul 2020 08:58:23 +0000Cluster Hamiltonian ground state MPS bond dimension
http://itensor.org/support/2369/cluster-hamiltonian-ground-state-mps-bond-dimension
<p>Hi again,</p>
<p>I am trying to make sense of the ground state of the famous cluster Hamiltonian. It is a well known fact that the cluster state has a bond dimension of 2. However, when I run the following script in Julia, it outputs an MPS of bond dimension 4 which is double of what I expect. </p>
<blockquote>
<p>Blockquote</p>
</blockquote>
<p>using ITensors</p>
<p>N = 10<br>
bond_dim=8<br>
sites = siteinds("S=1/2",N)</p>
<p>ampo = AutoMPO()</p>
<p>for j=2:N-1<br>
ampo += 8,"Sz",j-1,"Sx",j,"Sz",j+1;<br>
end<br>
ampo+= 8,"Sz",N-1,"Sx",N,"Sz",1;<br>
ampo+= 8,"Sz",N,"Sx",1,"Sz",2;</p>
<p>H = MPO(ampo,sites)</p>
<p>sweeps = Sweeps(5) # number of sweeps is 5<br>
maxdim!(sweeps,10,20,100,100,200) # gradually increase states kept<br>
cutoff!(sweeps,1E-10) # desired truncation error</p>
<p>psi0 = randomMPS(sites,bond_dim)#create a random initial MPS</p>
<p>energy,psi = dmrg(H,psi0,sweeps)</p>
<blockquote>
<p>Blockquote</p>
</blockquote>
<p>I understand that the ground state energies are correct but the program seems to unnecessarily double the dimension. Is there an explanation for this phenomenon and also is there a way to circumvent the issue?</p>
<p>Finally, while running a dmrg script one needs to specify a initial state with some bond dimension. Is there any significance to this initial bond dimension? (After playing around with the code it is my understanding that the final bond dimension can become both more or less than the initial BD.)</p>
http://itensor.org/support/2369/cluster-hamiltonian-ground-state-mps-bond-dimensionMon, 20 Jul 2020 12:29:40 +0000non-Hermitian DMRG in Julia
http://itensor.org/support/2367/non-hermitian-dmrg-in-julia
<p>Hi, </p>
<p>I am trying to do an example by obtaining the ground state of a non-Hermitian Hamiltonian. Is it possible to do it now in Julia (or in the future version when there is Arnoldi eigensolver). I already know there's one in the C++ version. Thank you!</p>
http://itensor.org/support/2367/non-hermitian-dmrg-in-juliaMon, 20 Jul 2020 04:54:33 +0000How to calculate spectrum function by using ITensor?
http://itensor.org/support/2366/how-to-calculate-spectrum-function-by-using-itensor
<p>Dear ITensor team,<br>
Thanks for your wonderful tool about Tensor Network. I have some silly questions about spectrum function. I want to repeat PHYSICAL REVIEW B 77, 134437 2008 Fig.4(t=10 (vertical green dot line ) results S^{zz}(0,10) about 0.02, spin 1 Heisenberg chain)<br>
According to definition: C^{z}(x,t)=<g.s|exp{iHt}S^{z}(x)exp(-iHt)S^{z}(0)|g.s> right?<br>
my naive strategy as follow:<br>
1) S^{z}(0) act on ground state |g.s>(single site operator act on MPS get new MPS psi1)<br>
2) exp(-iHt) act new state psi1(Trotter evolution) get new MPS state psi2<br>
3) S^{z}(x) act new psi2 to get new MPS psi3(same as step 1 )<br>
4) exp(iHt) act psi3 get new MPS psi4(Note that in the code I want to construct exp(I<em>tstep</em>hterm) gate. Naively, I replaced tstep to -tstep because if BondGate argument is tstep we get exp(-I<em>tstep</em>hterm), is that correct? (please see my naive code))<br>
5) Finally, C^{z}(x,t)=innerC(psi,psi4) right?<br>
According to this strategy, I write a naive code, but my answer is not consistent with that paper. So I don't know is there any wrong with my naive code? Thank you very much !</p>
<p>int main()<br>
{<br>
ofstream outfile;<br>
outfile.open("cor_t.dat",ios::app);</p>
<p>int N = 50; //number of sites<br>
Real tt = 10.0;<br>
Real tstep = 0.05; //time step (smaller is generally more accurate)<br>
Real ttotal = tt; //total time to evolve<br>
Real cutoff = 1E-8; //truncation error cutoff when restoring MPS form</p>
<p>auto sites = SpinOne(N);</p>
<p>auto state = InitState(sites);<br>
auto ampo = AutoMPO(sites);<br>
for(auto j : range1(N))<br>
{<br>
state.set(j,j%2==1?"Up":"Dn");<br>
}<br>
auto psi = MPS(state);</p>
<p>for(int b = 1; b < N; ++b)<br>
{<br>
ampo += 0.5,"S+",b,"S-",b+1;<br>
ampo += 0.5,"S-",b,"S+",b+1;<br>
ampo += "Sz",b,"Sz",b+1;<br>
}</p>
<p>auto H = MPO(ampo);</p>
<p>auto sweeps = Sweeps(30);<br>
sweeps.maxm() = 100,200,800,800,1000;<br>
sweeps.cutoff() = 1E-10;<br>
sweeps.niter() = 2;<br>
sweeps.noise() = 1E-7,1E-8,1E-9;<br>
println(sweeps);</p>
<p>auto energy = dmrg(psi,H,sweeps,"Quiet");<br>
println(energy);</p>
<p>auto psi0 = psi;</p>
<p>// S^{z}<em>{1} act on RHS<br>
auto Sz</em>1 = op(sites,"Sz",1);<br>
println(Sz<em>1);<br>
auto newpsi = Sz</em>1*psi(1);<br>
newpsi.noPrime();<br>
psi.set(1,newpsi);</p>
<p>//Create a std::vector (dynamically sizeable array)<br>
//to hold the Trotter gates<br>
auto gates = vector();</p>
<p>//Create the gates exp(-i<em>tstep/2</em>hterm)<br>
//and add them to gates<br>
for(int b = 1; b <= N-1; ++b)<br>
{<br>
auto hterm = op(sites,"Sz",b)<em>op(sites,"Sz",b+1);<br>
hterm += 0.5</em>op(sites,"S+",b)<em>op(sites,"S-",b+1);<br>
hterm += 0.5</em>op(sites,"S-",b)*op(sites,"S+",b+1);</p>
<pre><code>auto g = BondGate(sites,b,b+1,BondGate::tReal,tstep/2.,hterm);
gates.push_back(g);
}
</code></pre>
<p>//Create the gates exp(-i<em>tstep/2</em>hterm) in reverse<br>
//order (to get a second order Trotter breakup which<br>
//does a time step of "tstep") and add them to gates<br>
for(int b = N-1; b >= 1; --b)<br>
{<br>
auto hterm = op(sites,"Sz",b)<em>op(sites,"Sz",b+1);<br>
hterm += 0.5</em>op(sites,"S+",b)<em>op(sites,"S-",b+1);<br>
hterm += 0.5</em>op(sites,"S-",b)*op(sites,"S+",b+1);</p>
<pre><code>auto g = BondGate(sites,b,b+1,BondGate::tReal,tstep/2.,hterm);
gates.push_back(g);
}
</code></pre>
<p>//Time evolve, overwriting psi when done<br>
gateTEvol(gates,ttotal,tstep,psi,{"Cutoff=",cutoff,"Verbose=",true}); </p>
<p>// S^{z}<em>{1} act RHS<br>
auto newpsi1 = Sz</em>1*psi(1);<br>
newpsi1.noPrime();<br>
psi.set(1,newpsi1);</p>
<p>// exp(i<em>tstep</em>H) act RHS<br>
//Create the gates exp(i<em>tstep/2</em>hterm)<br>
//and add them to gates<br>
for(int b = 1; b <= N-1; ++b)<br>
{<br>
auto hterm = op(sites,"Sz",b)<em>op(sites,"Sz",b+1);<br>
hterm += 0.5</em>op(sites,"S+",b)<em>op(sites,"S-",b+1);<br>
hterm += 0.5</em>op(sites,"S-",b)*op(sites,"S+",b+1);</p>
<pre><code>auto g = BondGate(sites,b,b+1,BondGate::tReal,-tstep/2.,hterm);
gates.push_back(g);
}
</code></pre>
<p>//Create the gates exp(i<em>t</em>step/2*hterm) in reverse<br>
//order (to get a second order Trotter breakup which<br>
//does a time step of "tstep") and add them to gates</p>
<p>for(int b = N-1; b >= 1; --b)<br>
{<br>
auto hterm = op(sites,"Sz",b)<em>op(sites,"Sz",b+1);<br>
hterm += 0.5</em>op(sites,"S+",b)<em>op(sites,"S-",b+1);<br>
hterm += 0.5</em>op(sites,"S-",b)*op(sites,"S+",b+1);</p>
<pre><code>auto g = BondGate(sites,b,b+1,BondGate::tReal,-tstep/2.,hterm);
gates.push_back(g);
}
</code></pre>
<p>//Time evolve, overwriting psi when done<br>
gateTEvol(gates,ttotal,tstep,psi,{"Cutoff=",cutoff,"Verbose=",true});</p>
<p>printfln("Maximum MPS bond dimension after time evolution is %d",maxLinkDim(psi));</p>
<p>outfile <<tt<<" "<<real(innerC(psi0,psi))<< endl;</p>
<p>outfile.close();<br>
return 0;<br>
}</p>
http://itensor.org/support/2366/how-to-calculate-spectrum-function-by-using-itensorFri, 17 Jul 2020 16:09:33 +0000Looking for recommendations for applying Tensor Networks for simple problems (Julia).
http://itensor.org/support/2362/looking-recommendations-applying-networks-simple-problems
<p>This is more asking for recommendations than suggestions, but I have just recently learned about DMRG and Tensor Networks, and was hoping to get some hands on practice in Julia, using ITensor. I wanted to try to use ITensor for something simple, like the Ising Model.</p>
<p>I've gone through much of the Julia tutorials on the page, but am still struggling to apply the knowledge to real physics problems. Does anyone have recommendations on where I can look for a guide/walkthrough on how to approach a specific problem? (There doesn't necessarily need to be code samples, I'm more looking to learn how to think about and approach problems.) I know this isn't a standard question to be asked, but I wasn't really sure where else to look!</p>
http://itensor.org/support/2362/looking-recommendations-applying-networks-simple-problemsFri, 17 Jul 2020 00:16:29 +0000Copying MPS into vector
http://itensor.org/support/2354/copying-mps-into-vector
<p>Hi,<br>
In order to compute the excited states there is a formula described here<br>
<a rel="nofollow" href="https://www.itensor.org/docs.cgi?vers=cppv3&page=formulas/excited_dmrg">https://www.itensor.org/docs.cgi?vers=cppv3&page=formulas/excited_dmrg</a><br>
which mentions that we need a std::vector that contains the states that should be orthogonal to the excited state.</p>
<p>In the code it is done by</p>
<pre><code>auto wfs = std::vector<MPS>(1);
wfs.at(0) = psi0;
</code></pre>
<p>Doesn't this copy psi0 into wfs? If this is true, then this is expensive for large MPS so what is the best way to get around this? Perhaps starting with a vector already containing psi0 and then modifying its value through the original dmrg that finds the ground state is the better way?</p>
<p>Thanks for the help.</p>
http://itensor.org/support/2354/copying-mps-into-vectorSat, 11 Jul 2020 14:48:13 +0000Storing MPS Tensors as Text/HDF5 file in Julia
http://itensor.org/support/2347/storing-mps-tensors-as-text-hdf5-file-in-julia
<p>Hi,</p>
<p>This is a rudimentary question and maybe have been answered already but I couldn't find it myself. So here is my problem:</p>
<p>I am trying to store and access the MPS tensors that I get out of a DMRG algorithm. For example, in a chain of N=10 sites, I want to look at the MPS at the middle site and perform numerical operations using it. So, I use the code:</p>
<p>energy,psi = dmrg(H,psi0,sweeps).</p>
<p>I expect the middle site MPS to be of the dimension 2* D* D and I want to look at 2 of the D*D matrices that in contained there. In Matlab, this would correspond to something like:</p>
<p>psi[5] (1, :, :) and psi[5] (2, :, :) ; so my first question is if there is an equivalent way of accessing the tensors in Julia?</p>
<p>If not, how can I print the tensors out in a text/HDF5 file with their indices included so that they can be read off by a Matlab script? </p>
http://itensor.org/support/2347/storing-mps-tensors-as-text-hdf5-file-in-juliaFri, 10 Jul 2020 09:55:02 +0000Intel MKL error
http://itensor.org/support/2345/intel-mkl-error
<p>I have installed Itensor and I am using the Intel MKL libraries for lapack and blas. My codes compile, but sometimes when I try to run them I get error messages. For example, the following code : </p>
<p>auto expH = expHermitian(H,-beta), </p>
<p>gives the error: </p>
<p>Intel MKL ERROR: Parameter 5 was incorrect on entry to DSYEV.</p>
<p>Intel MKL ERROR: Parameter 5 was incorrect on entry to DSYEV.<br>
terminate called after throwing an instance of 'std::runtime_error'<br>
what(): Error condition in diagHermitian<br>
Aborted </p>
<p>Do you know what the problem might be?</p>
http://itensor.org/support/2345/intel-mkl-errorThu, 09 Jul 2020 17:33:05 +0000Trying to understand "product" function in projmps.jl and how to generalize to n-site DMRG (Julia)
http://itensor.org/support/2344/trying-understand-product-function-projmps-generalize-julia
<p>I am working on generalizing DMRG, for which only the 2-site version is currently supported, to a generalized n-site DMRG. I opened a pull request for it here (<a rel="nofollow" href="https://github.com/ITensor/ITensors.jl/pull/434),">https://github.com/ITensor/ITensors.jl/pull/434),</a> and it passes all of the provided tests. But I later realized that it still throws an error if one tries to call DMRG with an MPS vector as an input (i.e. if one is trying to compute excited states, as opposed to just the ground state). After examining the error messages and scouring the repository for a while, I am now fairly certain that the issue is that I have yet to adapt the following function, which appears in ITensors.jl/src/mps/projmps.jl:</p>
<pre><code>function product(P::ProjMPS,
v::ITensor)::ITensor
if nsite(P) != 2
error("Only two-site ProjMPS currently supported")
end
Lpm = dag(prime(P.M[P.lpos+1],"Link"))
!isnothing(lproj(P)) && (Lpm *= lproj(P))
Rpm = dag(prime(P.M[P.rpos-1],"Link"))
!isnothing(rproj(P)) && (Rpm *= rproj(P))
pm = Lpm*Rpm
pv = scalar(pm*v)
Mv = pv*dag(pm)
return noprime(Mv)
end
</code></pre>
<p>I understand that this function multiplies a ProjMPS object and an ITensor object, and that there is a similar function "product(P::ProjMPS, v::ITensor)::ITensor" in ITensors.jl/src/mps/projmpo_mps.jl that calls this first one repeatedly. I also understand that this ultimately works in service of adding a penalizing term w|psi><psi| to the Hamiltonian for some weight w and MPS |psi>. However, I am generally finding this method itself very hard to parse. Would it be possible to get a simple explanation of what this method is really doing, as well as an explanation of what would need to be changed to adapt this to n-site DMRG (and how hard you expect this to be)?</p>
http://itensor.org/support/2344/trying-understand-product-function-projmps-generalize-juliaThu, 09 Jul 2020 09:33:24 +0000Non-consecutive swap gates
http://itensor.org/support/2330/non-consecutive-swap-gates
<p>Hello,</p>
<p>I'm interested in simulating next-to-nearest neighbor (nnn) interactions using trotter gates, which requires swap gates.</p>
<p>For a lattice of site N, this requires implementing 6(N-2) gates when doing a right/left sweep</p>
<ul>
<li>Swap gate between j+1,j+2</li>
<li>nnn gate between j,j+2</li>
<li>swap gate between j+1,j+2</li>
<li>repeat for right sweep</li>
</ul>
<p>However, one could think about first ordering the sites in an odd/even order, apply the nnn gates right and left and reorder the sites again. This method only requires 4(N-2) gates. </p>
<ul>
<li>Swap gates such that the final order is: 1357...2468...</li>
<li>Apply the nnn gates in the right sweep: (13)(35)...(24)(46)...</li>
<li>Apply the nnn gates in the left sweep</li>
<li>Inverse swap gates such that the final order is: 12345....</li>
</ul>
<p>My question are the following: </p>
<ol>
<li>if I'm careful enough to check that the position is set to the first site before applying the nnn gates, does this construction respect the orthogonality condition? </li>
<li>Since swap gates don't accept two sites far apart, I was thinking about grouping the swap gates into an MPO and use applyMPO. However, this MPO scales with N because we will swap sites very far apart. Could one instead apply the gates without the svdBond and the position steps?</li>
</ol>
<p>Thank you for the help!</p>
http://itensor.org/support/2330/non-consecutive-swap-gatesMon, 06 Jul 2020 10:04:43 +0000How to implement a truly periodic MPS? (Julia)
http://itensor.org/support/2327/how-to-implement-a-truly-periodic-mps-julia
<p>I am interested in implementing an MPS that is truly periodic in ITensors.jl. By this, what I mean is that sites 1 and N have a common index, the same way that sites j and j+1 have a common index for j = 1, 2, ..., N-1. Here is what I am thinking:</p>
<p>(1) Make a <code>sweepnext_periodic</code> function so that, rather than turning around when it reaches the end of the chain, it just repeatedly works its way around the loop. For instance, if it were 3-site DMRG on an N-site chain, it would do sites 1:2:3, then sites 2:3:4, and so on, until sites (N-2):(N-1):N, then sites (N-1):N:1, then sites N:1:2, and that would complete the sweep. The next sweep will begin with 1:2:3 again.</p>
<p>(2) Make a <code>productMPS_periodic</code> function that includes an ITensors Index object for site N during initialization. Right now, Index objects are created to follow sites 1 through N-1, but this new site will connect sites N and 1.</p>
<p>(3) Create a <code>replacebond_periodic!</code> function so that it understands "wrapping around." For instance, if it is fed index N, it should understand that it is to look at sites N and 1, rather than throwing an error.</p>
<p>Is there anything else I am fundamentally missing, or is anything fundamentally wrong about what I am proposing above? Are there better ways to implement what I am thinking about implementing? For example, should I just make new objects rather than adding methods to the old ones? (I wouldn't want to do this unless the differences are just way too much to accommodate.) Making this work will likely take many hours of coding, so I want to make sure I have some sense of what I am doing before I begin.</p>
<p>This would also be a good time to double-check my understanding of the difficulties associated with My understanding is that this is not natively in the code primarily because it has poor performance on large chains. Is this correct? If not, what is (are) the primary obstacle(s) to the implementation of truly periodic matrix product states?</p>
<p>In case you may be wondering about my initial motivation for doing this, basically it is that I want to implement a lattice formulation of the Schwinger model. Up until now, I have tried to avoid this issue in a number of ways, but at this point, I think I am out of alternatives. In particular, the combination of DMRG and local gauge constraints makes it imperative that the last site and the first site are actually connected in the MPS and not just in the Hamiltonian. Otherwise, the last site gets "stuck" because, if you want to respect the gauge constraint, there is no way to alter that site without altering the first or second site.</p>
http://itensor.org/support/2327/how-to-implement-a-truly-periodic-mps-juliaSun, 05 Jul 2020 03:01:56 +0000convert a quantum-number MPS to a no-quantum-number MPS
http://itensor.org/support/2320/convert-a-quantum-number-mps-to-a-no-quantum-number-mps
<p>What I want to do is to compute <psi1|OP|psi2>,</p>
<pre><code>inner (psi1, OP, psi2);
</code></pre>
<p>where psi1 and psi2 are MPS and OP is an MPO. Here psi1 and psi2 have conserved but different quantum numbers (particle number), but OP does not. For example psi1 and psi2 have 1 and 2 electrons respectively, and OP is the annihilation operator.</p>
<p>In my task, psi1 and psi2 are loaded from files, and OP is generated by the program. Since OP does not conserve quantum number, I cannot use the SiteSet from psi1 to create OP, while the function "inner" requires psi1, psi2 and OP have the same Site indices. What is the proper way to do such tasks? Thanks!</p>
http://itensor.org/support/2320/convert-a-quantum-number-mps-to-a-no-quantum-number-mpsFri, 03 Jul 2020 09:31:37 +0000How to measure the momentum of an MPS?
http://itensor.org/support/2319/how-to-measure-the-momentum-of-an-mps
<p>Hi,</p>
<p>I was trying to measure the momenta of some MPSs in the Electron site class. Here is my attempt:</p>
<p>I got the desired results when I measure the momentum @@P@@ using toMPO. However, when I used the function toExpH to exponentiate the momentum operator and get the usual translation operator @@T@@, I got the following error message:</p>
<pre><code>From line 885, file itensor.cc
div(T1)=QN({"Nf",0,-1},{"Sz",0}) must equal div(T2)=QN({"Nf",1,-1},{"Sz",-1}) when adding T1+T2
div(T1)=QN({"Nf",0,-1},{"Sz",0}) must equal div(T2)=QN({"Nf",1,-1},{"Sz",-1}) when adding T1+T2
Aborted (core dumped)
</code></pre>
<p>I wasn't able to figure out what this message is saying? Also is this the right way to measure the momenta of some MPSs, and is this the best way to exponentiate some MPO? Below is the code for obtaining the MPOs for the operators @@P@@ and @@T@@.</p>
<pre><code># define PI 3.1415926535897932
MPO Momentum(Electron const& sites)
{
auto N = length(sites);
auto ampo = AutoMPO(sites);
for(int k = 1; k <= N; ++k)
{
for(int i = 1; i <= N; ++i)
{
for(int j = 1; j <= N; ++j)
{
ampo += 2.0*PI/(N*N)*k*std::exp(Cplx_i*2.0*PI/N*k*(i-j)),"Cdagup",j,"Cup",i;
ampo += 2.0*PI/(N*N)*k*std::exp(Cplx_i*2.0*PI/N*k*(i-j)),"Cdagdn",j,"Cdn",i;
}
}
}
auto T = toExpH(ampo,1.0,{"Cutoff=",1E-20});
auto P = toMPO(ampo,{"Cutoff=",1E-20});
return T; //or P
}
</code></pre>
<p>Thanks,<br>
WunderNatur</p>
http://itensor.org/support/2319/how-to-measure-the-momentum-of-an-mpsThu, 02 Jul 2020 07:23:23 +0000size() in gmres
http://itensor.org/support/2313/size-in-gmres
<p>Dear ITensor, </p>
<p>I'm using the gmres algorithm. I'm wondering how should the size() function be defined in the BigMatrix type. </p>
<p>I was assuming that, since it's a Krylov space method, size() should be n, if the BigMatrix is nxn when written as a matrix. gmres in Itensor works very well in most cases. However, I find that sometimes it does not give the correct answer. However, if I change n to n^2 in the size() function, gmres does give the correct answer. Is n^2 supposed to be the correction return for size()? </p>
<p>Thanks, <br>
Yantao </p>
http://itensor.org/support/2313/size-in-gmresTue, 30 Jun 2020 20:59:42 +0000Sweeping algorithm utilizing ITensor capabilities as best as possible.
http://itensor.org/support/2305/sweeping-algorithm-utilizing-itensor-capabilities-possible
<p>Hi, sorry if this question is a bit naive. I want to implement a sweeping type algorithm, and I want to utilize as much of ITensor's capabilities to enhance efficiency. What I need to do is calculate the matrix elements</p>
<p>(psidag| S_i^z |in)</p>
<p>for all i in the lattice. The calculation is at finite T, so I have an ancilla that I don't need matrix elements on. What I currently do is create all sets of tensors to the left and right by</p>
<pre><code>L[1] = ( psidag(P[1])*in(P[1]) ) * ( psidag(A[1]) * in(A[1]) );
R[N] = psidag(A[N])*in(A[N]);
for(auto i : range1(2,N))
{
auto I = N-i+1;
L[i] = L[i-1] * ( ( psidag(P[i])*in(P[i]) ) * ( psidag(A[i]) *in(A[i]) ) );
R[I] = R[I+1] * ( ( psidag(P[I+1])*in(P[I+1]) ) * ( psidag(A[I]) *in(A[I]) ) );
}
</code></pre>
<p>Where P[i] is the ith physical site, and A[i] is the ith ancilla site, they are consecutive (p[1] = 1, A[1]=2, P[2] = 3, A[2] =4, etc.). Then, the ith matrix element is</p>
<pre><code>auto res = L[i-1] * psidag(P[i]) * noPrime(in(P[i]) * op(sites,"Sz",P[i])) * R[i];
</code></pre>
<p>Now, my question is if there is a better way to do this with ITensor? I have noticed it's quite inefficient with increased bond dimensions. My initial thought was that this is better than just using 'inner', as I'm saving the majority of the tensor contraction from one value of i to the next. Space complexity is not a major factor for me, but time is.</p>
http://itensor.org/support/2305/sweeping-algorithm-utilizing-itensor-capabilities-possibleMon, 29 Jun 2020 22:34:52 +0000Unable to adjust last site due to local constraint with neighbors --> Is it possible to "rotate" a state? (Julia)
http://itensor.org/support/2295/unable-adjust-constraint-neighbors-possible-rotate-julia
<p>I am interested in developing on ITensors.jl the lattice Schwinger model with alternating (anti)fermion sites and links (representing electric flux). Each spatial site has 4 ITensors sites--first a fermion site, then a link, then an antifermion site, and then another link. It incorporates a local constraint given by Gauss's Law, and I've gotten it to mostly work (I think) by using a few tricks.</p>
<p>However, I am still running into one problem. Basically, the smallest "unit" that you can change without changing anything else is a unit consisting of two (anti)fermion sites and the link between them. For example, I can change sites 1-3 without changing anything else; similar for 3-5, 5-7, etc. This is why I run 3-site DMRG (this isn't natively in ITensors; I developed this code and have put a pull request for it here: <a rel="nofollow" href="https://github.com/ITensor/ITensors.jl/pull/434).">https://github.com/ITensor/ITensors.jl/pull/434).</a> However, this spells trouble when you reach the end. One of the "units" that you should be able to change is that consisting of sites 4N-1, 4N, and 1, where N is the number of spatial sites. However, DMRG doesn't do such a thing, because it only works on a bundle of adjacent sites. This means that, due to the Gauss's Law constraint enforced by sites 4N, 1, and 2, site 4N is stuck unless one also changes either site 1 or site 2, which only happens if one uses k-site DMRG for k=4N-1 or 4N (i.e. adjusting the whole state, minus at most one site, in each step). For example, for 2 spatial sites, I need 7-site DMRG to be able to change site 8 at all, and for 3 spatial sites, I need 11-site DMRG. This is simply infeasible for any lattice larger than 3 spatial sites.</p>
<p>I am wondering whether anyone has any ideas about how to handle this or has dealt with something similar before. One idea I had was "rotating" the state between or during sweeps in the DMRG process, so that every site has at least some time not being the one at the end, which is stuck in place. As an example, one could "rotate" the state so that the last two sites are now the first two, and then sites 4N, 1, and 2 (which are now sites 2-4), are together and can be optimized. And then one can rotate the state back and complete the rest of the sweep. But I'm not sure how one would do such a thing, or whether it would really produce the desired results. Does anyone know of a feasible fix for this, whether by rotating the state or by any other means?</p>
<p>It is true that this error should in principle become relatively small for a sufficiently large number of spatial sites, but in my research, I will mostly be working with fairly small lattices, for which such limits won't apply. Also, I need my code to be accurate in finding the ground state so that I can accurately evaluate excited states, as well as assess my code against existing results on the Schwinger model produced using other computational methods (e.g. exact diagonalization). Any help on this would be greatly appreciated.</p>
http://itensor.org/support/2295/unable-adjust-constraint-neighbors-possible-rotate-juliaMon, 29 Jun 2020 05:04:14 +0000Loop over Args
http://itensor.org/support/2293/loop-over-args
<p>Hello, </p>
<p>Is there a way to loop over the Args elements?</p>
<pre><code>for(Val const & a: args){
//Do something with a
}
</code></pre>
<p>I'm using Args to simplify the construction of operators. Since this construction is quite general, I don't know what Args have been added so I would like to loop over all elements. Thank you very much.</p>
<p>Best,<br>
João</p>
http://itensor.org/support/2293/loop-over-argsSun, 28 Jun 2020 17:12:56 +0000Questions about checks for ITensors.jl pull request
http://itensor.org/support/2290/questions-about-checks-for-itensors-jl-pull-request
<p>Slightly less than a week ago, I submitted a pull request for generalized n-site DMRG (as opposed to 2-site DMRG, which is the default). You can find the pull request here (<a rel="nofollow" href="https://github.com/ITensor/ITensors.jl/pull/434).">https://github.com/ITensor/ITensors.jl/pull/434).</a></p>
<p>Just as an example of this, on the "Tests / Julia 1.4 - macOS-latest - x64 (pull_request)" test set, I don't see any failed tests for broadcast.jl. However, when I run the tests on my computer, I see that broadcast.jl has 9 failed tests, even though I didn't change any of the methods that those tests are using (which are all extremely basic functions, I should add).</p>
<p>In addition, I see that there are 2 broken tests for broadcast.jl (which actually should happen, according to comments on the code) and 2 broken tests for empty.jl. The broken tests are never given any explanation, even when you run the test files locally on your computer, so what do they mean?</p>
<p>Another thing I saw was an extremely basic failure. In the mps.jl test file, I got an error from the test on like 16, <code>@test str[1] == "MPS"</code>. I don't see why an error like this should happen, because again, this is a very basic thing and I haven't done anything to change it. The error message is shown below.</p>
<pre><code>MPS Basics: Test Failed at c:\Users\user\ITensors.jl\test\mps.jl:16
Expression: str[1] == "MPS"
Evaluated: "ITensors.MPS" == "MPS"
</code></pre>
<p>Overall, my main questions are: (1) What do the "broken" tests mean? (2) Why do some of the tests seem to fail for functions I never modified (including some extremely basic ones, like object types and basic operations on tensors)?</p>
<p>I did find some mistakes in my code that I am currently working to fix (I should probably have these done by Monday or Tuesday), but they are related to intricacies of DMRG, and none of them are related to the test failures that I have mentioned above. (In particular, I found one big typo in my code, and even after I fixed that a few hours ago, my code still breaks on the DMRG method that projects out certain states with the goal of finding excited states.) Any help on this would be greatly appreciated.</p>
http://itensor.org/support/2290/questions-about-checks-for-itensors-jl-pull-requestSun, 28 Jun 2020 07:46:39 +0000Symbol lookup error
http://itensor.org/support/2279/symbol-lookup-error
<p>Hello, </p>
<p>I've successfully compiled version V3 of ITensor however when calling some functions the following error occurs</p>
<p>./two: symbol lookup error: ./two: undefined symbol: <em>ZN7itensor3svdERKNS</em>7ITensorERKNS<em>8IndexSetENS</em>4ArgsE</p>
<p>This error occurs when running the tutorial two but not the tutorial one, per example. I think this has to do with library linking but from the error message, I cannot understand which libraries...</p>
<p>A few things that didn't work:</p>
<ol>
<li>I've tried to make clean and then make</li>
<li>The debug message is the same</li>
<li>I'm currently using MKL but have tried just the LAPAK</li>
</ol>
<p>Thank you for the support</p>
http://itensor.org/support/2279/symbol-lookup-errorFri, 26 Jun 2020 14:42:43 +0000CPS collapse of finite-T in the tutorial (Minimally entangled typical thermal state algorithms)
http://itensor.org/support/2276/collapse-tutorial-minimally-entangled-typical-algorithms
<p>Hello! I have some question about CPS collapse in the Minimally entangled typical thermal state algorithms.<br>
Assume we have know the projection operator Pi(m), which project the ith site state to |m>. When we collapse from the first site of a METTS, the probability is p1(m) = (psi|P1(m)|psi).<br>
after a collapse, the wave function should be updated as follow:(NJP, 12 (2010) 055026, Annals of Physics 326(2011) 96-192 sec. 8.3) </p>
<pre><code> A_{1N}^{s_1} = <s_1|m>
A_{2N}^{s_2}= <m|s1> A_{1O}^{s1} A_{2O}^{s2}/sqrt(p1(m))
Latex:
A_{1N}^{s_{1}}=\left\langle s_{1}|m\right\rangle
A_{2N}^{s_{2}}=p_{1m}^{-\frac{1}{2}}\left\langle m|s_{1}\right\rangle A_{1O}^{s_{1}}A_{2O}^{s_{1}}
</code></pre>
<p>lower index N and O represent new and old respectively, and summation is assumed.<br>
In the finite-T tutorial of ITensor 3.1.3 , the related code is:</p>
<pre><code>ITensor jstate = (st==1) ? upState : downState;
if(j < N)
{
auto newA = psi(j+1)*(dag(jstate)*psi(j));
newA /= norm(newA);
psi.set(j+1,newA);
}
//Set site j tensor
psi.set(j,jstate);
</code></pre>
<p>here newA is not divided by the square root of the probability, newA /= norm(newA) normalize the projected state. But I noticed that <a rel="nofollow" href="https://github.com/emstoudenmire/finiteTMPS/blob/master/collapse.h"> the square root of the probability occurs here</a>. For newA = psi(j+1)<em>(dag(jstate)</em>psi(j)), should it be like this newA = psi(j+1)<em>(dag(jstate))</em>psi(j) ?</p>
<p>For the absence of the square root of the probability here, can I understand like this:<br>
when we divide the newA by the square root of the probability, we just multiply the wave function by a real number. It will not affect the collapse probability for the next step(if we do a normalization). And for the measurements, because of the normalization there is also no affect?</p>
http://itensor.org/support/2276/collapse-tutorial-minimally-entangled-typical-algorithmsFri, 26 Jun 2020 03:17:50 +0000How to project into zero-momentum sector? (Julia)
http://itensor.org/support/2266/how-to-project-into-zero-momentum-sector-julia
<p>In certain cases, one may wish to consider only zero-momentum states, i.e. translation-invariant states. Such a notion is only well-defined for periodic boundary conditions (PBC), but one can approximate it with open boundary conditions (OBC) as well.</p>
<p>An example of this is the lattice Schwinger model. If one is using OBC (as described in Equation 2.6 of <a rel="nofollow" href="https://arxiv.org/pdf/1305.3765.pdf),">https://arxiv.org/pdf/1305.3765.pdf),</a> then one can find many low-lying states, compute some momentum proxy operator for each of these states, and identify those that have an expectation of the operator very close to zero. This is what the aforementioned paper does, as shown in Figure 3 and Equation 3.4. This works because the paper is interested in the first three zero-momentum states, and these aren't that bad. The first two zero-momentum states are the first two states anyway, and the third one only requires you to find about 10-15 extra states.</p>
<p>However, this method is unsuitable if one is going to have to comb through a great deal of states with momentum to find the very few with zero momentum. If it were possible, a far better method would be to somehow project into the zero-momentum sector, as described in <a rel="nofollow" href="https://arxiv.org/abs/1803.03326.">https://arxiv.org/abs/1803.03326.</a> This is only possible when the Hamiltonian uses periodic boundary conditions, i.e. it has the appropriate terms connecting the last site (or last few sites) with the first site (or first few sites), so it is not possible for the Hamiltonian presented in the first paper, but it is possible for the Hamiltonian presented in Equation 2 of the second paper. Appendix A of this paper gives a detailed explanation of momentum, charge, and parity conjugation in this particular lattice, and in particular it mentions that zero-momentum states are translation-invariant. However, I don't know how to restrict to only this set of states in ITensors.jl, especially since DMRG will explicitly make the state fail to be translation-invariant when it performs a local optimization.</p>
<p>My first thought is to make a projection operator P that kills every state of nonzero momentum while maintaining every state of zero momentum, and then optimizing the modified Hamiltonian H' = P^dagger HP, but I can't really think of a principled way of doing this, and the projector P would make H' significantly more complicated than H, probably to the point of it being unworkable when combined with other constraints. I feel that there must be some other way.</p>
<p>Does anybody know of an efficient way to restrict one's DMRG search to zero-momentum (i.e. translation-invariant) states in ITensors.jl, whether it is the above suggested method or any other method? Any help with this would be greatly appreciated.</p>
http://itensor.org/support/2266/how-to-project-into-zero-momentum-sector-juliaWed, 24 Jun 2020 08:00:23 +0000Bug in MPOs with products of operators? (Julia version)
http://itensor.org/support/2258/bug-in-mpos-with-products-of-operators-julia-version
<p>Hi,</p>
<p>I have codes in which I perform DMRG and then compute < S^2 >.<br>
Before I updated ITensor to the latest version, these codes were giving correct results and now they are not. I know that the previous results were correct because I benchmarked with simple models for which I can do exact diagonalization.</p>
<p>One simple example that may help to identify this apparent bug is the following:</p>
<p>Model: DMRG for S=1 antiferromagnetic Heisenberg dimer. <br>
The groundstate should be a singlet.<br>
I compute < Sz > and I get 0. That's good.<br>
I compute < S^2 > and I get different than 0. That's not right.</p>
<p>I defined the S^2 operator as follows:</p>
<pre><code>function S2_op(Nsites,sites)
ampo = AutoMPO()
for i in 1:Nsites
for j in 1:Nsites
ampo += 1.,"S+",i,"S-",j
ampo += 1.,"Sz",i,"Sz",j
end
ampo += -1.,"Sz",i
end
S2 = MPO(ampo,sites)
return S2
end
</code></pre>
<p>I also tried to define it in a different manner: (EDIT: this is wrong)</p>
<pre><code>function S2_op_other(Nsites,sites)
ampo = AutoMPO()
for i in 1:Nsites
ampo += 1.,"S+*S-",i
ampo += 1.,"Sz*Sz",i
ampo += -1.,"Sz",i
end
S2 = MPO(ampo,sites)
return S2
end
</code></pre>
<p>Both cases give values that are not 0. Also, they give different results, which I think is also telling. In the first case, I get 2/3. In the second case, I get 4. None of these numbers makes any physical sense.</p>
<p>The exact same thing happened when I tried to create an MPO of the Sz^2 operator and compute its average.</p>
<p>Best,<br>
Gonçalo Catarina</p>
http://itensor.org/support/2258/bug-in-mpos-with-products-of-operators-julia-versionMon, 22 Jun 2020 19:03:45 +0000Low number of states for large chains means metastable states? Is it possible work with arbitrary precision in Itensor?
http://itensor.org/support/2249/chains-metastable-states-possible-arbitrary-precision-itensor
<p>Hi!</p>
<p>I'm trying to explore the ionic hubbard model in 1d, but I have some problems for large chains. For some set of parameters I could compute ground state energy, charge and spin gap energies with enough accuracy for large chain (up to 300 sites) but there is some regions of parameters where a metastable state seems to appear because the algorithm does not need a large number of states to converge, high noise and number of the states even does not solve my problem (even I have this problem in other code without tensor network in Fortran 98)</p>
<p>I'm thinking that, for large chains and some parameters, the numerical error of elementary operations can be of the same order that the fluctuations of the dmrg iterations such that the current precision in the double floating point is actually low. Is there some how I can work with an arbitrary precision? Or Someone have an idea of how I can explore large chains?</p>
http://itensor.org/support/2249/chains-metastable-states-possible-arbitrary-precision-itensorMon, 22 Jun 2020 06:59:03 +0000std::bad_alloc when measuring two point correlation functions with periodic boundary condition.
http://itensor.org/support/2246/bad_alloc-measuring-correlation-functions-boundary-condition
<p>Hi Miles,</p>
<p>I am working with a 20-site electron system with periodic boundary condition. I obtained the ground state with dmrg and measure the spin correlation functions following <a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv3&page=formulas/correlator_mps">this formula</a>. However, when the largest bond dim @@\gtrsim 500@@, I always got the error message </p>
<pre><code>terminate called after throwing an instance of 'std::bad_alloc'
</code></pre>
<p>If I run the code in gdb, I got the following error message:</p>
<pre><code>Program received signal SIGABRT, Aborted.
0x00007ffff640570f in raise () from /lib64/libc.so.6
</code></pre>
<p>This seems to be an issue of running out of memory. However, I have ~400G memory and this program seems only using @@\gtrsim@@10G memory. I am not sure whether this is an issue of my code or I really run out of memory. The relevant part of the code is the following function:</p>
<pre><code>Real TwopointCorrelation(const Electron& sites, MPS& psi, string Opi, string Opj, int site_i, int site_j)
{
int N = length(sites);
auto op_i = op(sites,Opi,site_i);
auto op_j = op(sites,Opj,site_j);
//'gauge' the MPS to site i
//any 'position' between i and j, inclusive, would work here
psi.position(site_i);
//Create the bra/dual version of the MPS psi
auto psidag = dag(psi);
//Prime the link indices to make them distinct from
//the original ket links
psidag.prime("Link");
//index linking i-1 to i:
auto li_1 = leftLinkIndex(psi,site_i);
auto C = prime(psi(site_i),li_1) * op_i * prime(psidag(site_i),"Site");
for(int k = site_i+1; k < site_j; ++k)
{
C *= psi(k) * psidag(k);
}
//index linking j to j+1:
auto lj = rightLinkIndex(psi,site_j);
C *= prime(psi(site_j),lj) * op_j * prime(psidag(site_j),"Site");
auto result = elt(C); //or eltC(C) if expecting complex
return result;
}
</code></pre>
<p>Thank you so much!<br>
WunderNatur</p>
http://itensor.org/support/2246/bad_alloc-measuring-correlation-functions-boundary-conditionSun, 21 Jun 2020 23:18:07 +0000How to calculate the first, second... to 15 excited state in Tensor
http://itensor.org/support/2243/how-to-calculate-the-first-second-15-excited-state-in-tensor
<p>Hi ITensor developer,<br>
Thanks for your reply. I want to calculate The first, second, third,..... (to fifteen exited state) in 1D Heisenberg chain.(my ITensor is version 2 ). Please help me (give some sample) , Thank you very much !<br>
Best,<br>
Sugar</p>
http://itensor.org/support/2243/how-to-calculate-the-first-second-15-excited-state-in-tensorSat, 20 Jun 2020 09:51:34 +0000Write MPS to file in Julia
http://itensor.org/support/2234/write-mps-to-file-in-julia
<p>Hi,</p>
<p>Using the code below</p>
<pre><code>using HDF5
fo = h5open("output.h5", "w")
write(fo, "MPS", psi)
close(fo)
</code></pre>
<p>I manage to write an MPS to a file, but only when QNs are not conserved.<br>
Is there any way to do the same with QNs conserved?</p>
<p>Thanks a lot.<br>
Best regards,<br>
Gonçalo Catarina</p>
http://itensor.org/support/2234/write-mps-to-file-in-juliaFri, 19 Jun 2020 14:11:40 +0000How to create the MPO of the transverse-field Ising model Hamiltonian with AutoMPO?
http://itensor.org/support/2230/create-transverse-field-ising-model-hamiltonian-with-autompo
<p>Dear Itensor, </p>
<p>I'm trying to create the MPO of the transverse-field Ising model Hamiltonian with AutoMPO. The piece of the code that Itensor reports an error is</p>
<p>int N = 8; <br>
auto sites = SpinHalf(N); <br>
auto ampo = AutoMPO(sites); <br>
for(int j = 1; j <=N; ++j)<br>
{ ampo += 2, "Sx", j;}<br>
auto H = toMPO(ampo); </p>
<p>The error message is <br>
"Trying to set element: <br>
Index: (dim=2|id=13|"n=1,Site,S=1/2") <br>
1: 1 QN({"Sz",1})<br>
2: 1 QN({"Sz",-1}), Val: 2<br>
Index: (dim=2|id=13|"n=1,Site,S=1/2")' <br>
1: 1 QN({"Sz",1})<br>
2: 1 QN({"Sz",-1}), Val: 1<br>
Element flux is: QN({"Sz",2})<br>
ITensor flux is: QN({"Sz",-2})<br>
From line 327, file ~/itensor3/itensor/itensor_impl.h<br>
In .set, cannot set element with flux different from ITensor flux"</p>
<p>It seems that ITensor is complaining that the Hamiltonian Sx is not block-spare with respect to the Sz basis. Is there any way to circumvent this difficulty? </p>
<p>More generally, it seems that indices with quantum numbers are automatically used in the Site classes. Is there anyway to tell ITensor that these quantum numbers are not important? </p>
<p>Thanks very much, <br>
Yantao </p>
http://itensor.org/support/2230/create-transverse-field-ising-model-hamiltonian-with-autompoFri, 19 Jun 2020 05:55:27 +0000Questions about spin and charge gap on Holstein-Hubbard model
http://itensor.org/support/2229/questions-about-spin-and-charge-gap-holstein-hubbard-model
<p>I'm following an article: arXiv:0808.1675. When I calculate the spin and charge gap of Fig.2, I can't get the correct answer,my codes is:</p>
<pre><code>#include "itensor/all.h"
</code></pre>
<p>using namespace itensor;</p>
<p>int<br>
main()<br>
{<br>
using Holstein =MixedSiteSet<ElectronSite,BosonSite>;<br>
auto N=60;<br>
auto U=1.0;<br>
auto t=1.0;<br>
auto eplison=1.25;<br>
auto omega=5.0;<br>
auto sites=Holstein(N,{"ConserveNf",true,"ConserveNb",false,"MaxOcc=",4});</p>
<pre><code>auto ampo =AutoMPO(sites);
for(int j=1;j<=N-2;j=j+2)
{
ampo += -t,"Cdagup",j+2,"Cup",j;
ampo += -t,"Cdagdn",j+2,"Cdn",j;
ampo += -t,"Cdagup",j,"Cup",j+2;
ampo += -t,"Cdagdn",j,"Cdn",j+2;
}
for(int j=1;j<=N;j=j+2)
{
ampo += U,"Nup",j,"Ndn",j;
ampo += -sqrt(eplison*omega),"Nup",j,"A",j+1;
ampo += -sqrt(eplison*omega),"Nup",j,"Adag",j+1;
ampo += -sqrt(eplison*omega),"Ndn",j,"A",j+1;
ampo += -sqrt(eplison*omega),"Ndn",j,"Adag",j+1;
ampo += omega,"Adag",j+1,"A",j+1;
}
auto H=toMPO(ampo);
auto sweeps =Sweeps(20);
sweeps.noise()=1E-6,1E-6,1E-8,1E-12;
sweeps.maxdim()=10,20,100,100,200,400,800;
sweeps.cutoff()=1E-10;
auto state =InitState(sites);
for(auto j:range1(N))
{
if(j%4==1)state.set(j,"Dn");
else if(j%4==3)state.set(j,"Up");
else state.set(j,"0");
}
auto psi0=randomMPS(state);
auto [energy,psi]=dmrg(H,psi0,sweeps,{"Quiet=",true});
auto state1=InitState(sites);
for(auto j:range1(N))
{
if(j==1)state1.set(j,"UpDn");
else if(j%4==1&&j!=1)state1.set(j,"Dn");
else if(j%4==3)state1.set(j,"Up");
else state1.set(j,"0");
}
auto psi1=randomMPS(state1);
auto [energyadd,psi2]=dmrg(H,psi1,sweeps,{"Quiet=",true});
auto state2=InitState(sites);
for(auto j:range1(N))
{
if(j==3)state2.set(j,"Emp");
else if(j%4==1)state2.set(j,"Dn");
else if(j%4==3&&j!=3)state2.set(j,"Up");
else state2.set(j,"0");
}
auto psi3=randomMPS(state2);
auto [energyminus,psi4]=dmrg(H,psi3,sweeps,{"Quiet=",true});
auto state3=InitState(sites);
for(auto j:range1(N))
{
if(j==1)state3.set(j,"Up");
else if(j%4==1&&j!=1)state3.set(j,"Dn");
else if(j%4==3)state3.set(j,"Up");
else state3.set(j,"0");
}
auto psi5=randomMPS(state3);
auto [energyspin,psi6]=dmrg(H,psi5,sweeps,{"Quiet=",true});
printfln("spin gap=",energyspin-energy);
printfln("charge excitation=", energyadd+energyminus-2*energy);
return 0;
}
</code></pre>
<p>When I calculate N=60 in the code(actually the system is 30) , lambda=0.625, boson is 4. the spin gap is 0.351311, the charge gap is 0.442756. They are not correct. I try the other ways, but it doesn't work. Whether I ignore something? </p>
http://itensor.org/support/2229/questions-about-spin-and-charge-gap-holstein-hubbard-modelFri, 19 Jun 2020 01:39:44 +0000Source and purpose of @timeit_debug macro in dmrg.jl (in Julia version of code)?
http://itensor.org/support/2216/source-purpose-%40timeit_debug-macro-dmrg-julia-version-code
<p>I have been trying to write a modified version of the dmrg and sweepnext functions in Julia for my work on the lattice Schwinger model with periodic boundary conditions. However, when I do so, I am confronted with the following error message:</p>
<pre><code>ERROR: LoadError: LoadError: UndefVarError: @timeit_debug not defined
</code></pre>
<p>When I looked in the original dmrg.jl code, I see @timeit_debug used four times. There is no indication of it being defined earlier in the file or being imported from somewhere else. The first one looks like this:</p>
<pre><code>@timeit_debug GLOBAL_TIMER "position!" begin
position!(PH, psi, b)
end
</code></pre>
<p>When I try to look up this macro, the only thing I can find is this GitHub repository (<a rel="nofollow" href="https://github.com/KristofferC/TimerOutputs.jl/blob/b91912e12902a41425d030fed9d3f418134279ff/src/TimerOutput.jl).">https://github.com/KristofferC/TimerOutputs.jl/blob/b91912e12902a41425d030fed9d3f418134279ff/src/TimerOutput.jl).</a> However, when I look in my Julia files and packages, I cannot find this repository or anything like it.</p>
<p>So anyway, my questions are:<br>
(1) What is the purpose of this macro? In particular, is it necessary for the functioning of DMRG, or is it just some helpful addition? (Guessing by the name of the macro, I'm guessing it's the latter, but I want to be sure.)<br>
(2) Where exactly is ITensors.jl getting this macro from?<br>
(3) If I write my own methods in a separate Julia file that are meant to imitate ones in the repository but with certain modifications, what steps do I need to follow to incorporate this macro without getting the above error?</p>
http://itensor.org/support/2216/source-purpose-%40timeit_debug-macro-dmrg-julia-version-codeWed, 17 Jun 2020 06:21:05 +0000randomMPS method can not be used with Zn symmetry (Julia)
http://itensor.org/support/2214/randommps-method-can-not-be-used-with-zn-symmetry-julia
<p>I have created a new Z3 sitetype using</p>
<pre><code>const Z3Site = TagType"Z3"
function siteinds(::Z3Site, Num::Int;kwargs...)
conserve_qns = get(kwargs,:conserve_qns,false)
if conserve_qns
s = [ QN(("P", n, 3)) => 1 for n = 0:2]
return [Index(s;tags="Site,Z3,n=$n") for n=1:Num]
end
return [Index(N,"Site,Z3,n=$n") for n=1:Num]
end
function state(::Z3Site,
st::AbstractString)
if st == "s1"
return 1
elseif st == "s2"
return 2
elseif st == "s3"
return 3
end
</code></pre>
<p>when I use these site type to initialize a random mps with</p>
<pre><code>sites=siteinds("Z3",N,conserve_qns=true)
state = ["s1" for n in 1:N]
randomMPS(sites,state,10)
</code></pre>
<p>It throws the error that</p>
<p><em>"Indices must have the same spaces to be replaced"</em></p>
<p>This error can be reproduced using the following minimal code</p>
<pre><code>sites = siteinds("Z3",N,conserve_qns=true);
s1 = sites[1];
s2 = sites[2];
M = randomITensor(QN(),s1',s2',dag(s1),dag(s2));
U,S,V = svd(M,(s1',s2'));
replaceind!(U,ind(S,1),ind(S,2))
</code></pre>
<p>because</p>
<pre><code>space(ind(S,2))!=space(ind(S,1))
</code></pre>
<p>However, when I print the space of the two index space, it seems that they are the same when module 3</p>
<pre><code>space(ind(S,2))
3-element Array{Pair{QN,Int64},1}:
QN("P",-2,3) => 3
QN("P",-1,3) => 3
QN("P",0,3) => 3
space(ind(S,1))
3-element Array{Pair{QN,Int64},1}:
QN("P",1,3) => 3
QN("P",2,3) => 3
QN("P",0,3) => 3
</code></pre>
<p>Is there something wrong when I define the Z3 sitetype?</p>
<p>Thank you very much for the answer!</p>
http://itensor.org/support/2214/randommps-method-can-not-be-used-with-zn-symmetry-juliaSun, 14 Jun 2020 01:53:17 +0000How hard is it to modify DMRG to optimize over a different number of sites at a time? (Julia)
http://itensor.org/support/2212/modify-dmrg-optimize-over-different-number-sites-time-julia
<p>To my understanding, DMRG works by optimizing every consecutive pair of sites in turn. So it goes something like this: optimize sites 1-2 while holding the rest fixed, then optimize sites 2-3 while holding the rest fixed, then optimize sites 3-4 while holding the rest fixed, and so on. Eventually it reaches the end of the chain and turns around, and once it returns to the beginning, that's one sweep. I know that a version of DMRG exists where only one site is modified at a time, but the 2-site DMRG is considered superior for various reasons, which is why it's the one that is used.</p>
<p>My question is the following: how hard would it be to perform a modified version of this where the number of sites one optimizes at a time is some number other than 2 (such as 3), and where one did not necessarily optimize over every grouping of adjacent sites? In particular:</p>
<p>(1) How hard would it be to write code for in Julia, given that we can reference the original DMRG code at <a rel="nofollow" href="https://github.com/ITensor/ITensors.jl/blob/3b44ec3039a43870d6a3299f49ea79462febc174/src/mps/dmrg.jl?">https://github.com/ITensor/ITensors.jl/blob/3b44ec3039a43870d6a3299f49ea79462febc174/src/mps/dmrg.jl?</a><br>
(2) What might one expect from the runtime?<br>
(3) What other complications might arise?</p>
<p>I ask this in particular with respect to the lattice Schwinger model, which has alternating spin-1/2 sites (for the fermions and antifermions) and link sites (for the electric flux values), as shown in equation (2) of <a rel="nofollow" href="https://arxiv.org/abs/1803.03326.">https://arxiv.org/abs/1803.03326.</a> Basically, this setup has local constraints enforced by Gauss's Law (this was also mentioned in <a rel="nofollow" href="http://itensor.org/support/2140/implementing-local-gauge-symmetries).">http://itensor.org/support/2140/implementing-local-gauge-symmetries).</a> As a result, one cannot modify one or even two sites in isolation. The "most elementary" modification one can make to a state is to add or remove an adjacent fermion-antifermion pair and change the value of the link between them by +/- 1. Notice that this modifies three sites.</p>
<p>Because of this, it seems to me that isolating two adjacent sites and optimizing them while holding the rest fixed will lead to problems when trying to perform DMRG on such a Hamiltonian. However, if one were to hold three sites fixed at a time, and only do every other consecutive triple, then it might work. This would look something like the following: optimize sites 1-2-3 while holding the rest fixed, then optimize sites 3-4-5 while holding the rest fixed, then optimize sites 5-6-7 while holding the rest fixed, and so on.</p>
http://itensor.org/support/2212/modify-dmrg-optimize-over-different-number-sites-time-juliaSat, 13 Jun 2020 23:47:38 +0000ITensor can calculate imaginary time correlation function?
http://itensor.org/support/2200/itensor-can-calculate-imaginary-time-correlation-function
<p>Dear ITensor,<br>
I follow tutorial in order to calculate imaginary time correlation function such as <S^{z}<em>{1}(L/2)S^{z}</em>{1}>. here is my naive code. it can run but I get wrong answer (compare my QMC datas). so please help me check my naive code, Thanks!!!</p>
<p>int main()<br>
{<br>
ofstream outfile;<br>
outfile.open("cor_t.dat",ios::app);</p>
<p>int length[7]={12,16,24,32,48,64,80};</p>
<p>for(int &N : length)<br>
{ <br>
auto sites = SpinHalf(N);<br>
auto state = InitState(sites);<br>
for(int i = 1; i <= N; ++i)<br>
{<br>
//Neel state<br>
state.set(i,i%2==1 ? "Up" : "Dn");<br>
}<br>
auto psi0 = MPS(state);<br>
auto psi = MPS(state);</p>
<p>auto ampo = AutoMPO(sites);<br>
//Make the Heisenberg Hamiltonian<br>
for(int b = 1; b < N; ++b)<br>
{<br>
ampo += 0.5,"S+",b,"S-",b+1;<br>
ampo += 0.5,"S-",b,"S+",b+1;<br>
ampo += "Sz",b,"Sz",b+1;<br>
}<br>
auto H = MPO(ampo);</p>
<p>auto sweeps = Sweeps(30);<br>
sweeps.maxm() = 100,200,800,800,1000;<br>
sweeps.cutoff() = 1E-10;<br>
sweeps.niter() = 2;<br>
sweeps.noise() = 1E-7,1E-8,1E-9;<br>
println(sweeps);</p>
<p>//<br>
// Begin the DMRG calculation<br>
//<br>
auto energy = dmrg(psi,H,sweeps,"Quiet");<br>
//</p>
<p>auto Sz_1=sites.op("Sz",1);</p>
<p>auto tau =0.1;<br>
auto expHL0 = toExpH(ampo,tau);<br>
auto expHR0 = toExpH(ampo,-tau);</p>
<p>auto args = Args("Cutoff=",1E-9,"Maxm=",3000);<br>
auto ttotal = N/4;<br>
auto nt = int(ttotal/tau+(1e-9*(ttotal/tau)));</p>
<p>// left part <tau(t)|S^{z}<br>
for(int n = 1; n <= nt; ++n)<br>
{<br>
psi = exactApplyMPO(expHL0,psi,args);<br>
normalize(psi);<br>
}</p>
<p>auto newpsi= Sz_1*psi.A(1);<br>
newpsi.noprime();<br>
psi.setA(1,newpsi);</p>
<p>// Right part exp(-H\tau)*S^{z}|g.s></p>
<p>auto newpsi0 = Sz_1*psi0.A(1);<br>
newpsi0.noprime();</p>
<p>psi0.setA(1,newpsi0);</p>
<p>for(int n = 1; n <= nt; ++n)<br>
{<br>
psi0 = exactApplyMPO(expHR0,psi0,args);<br>
normalize(psi0);<br>
}</p>
<p>//Print(psi0);<br>
auto result=overlapC(psi,psi0).real();<br>
//Print(result);<br>
outfile <<N<<" "<<abs(result)<< endl;<br>
}<br>
outfile.close();<br>
return 0;<br>
}</p>
http://itensor.org/support/2200/itensor-can-calculate-imaginary-time-correlation-functionFri, 12 Jun 2020 12:56:47 +0000Momentum-resolved entanglement spectrum
http://itensor.org/support/2197/momentum-resolved-entanglement-spectrum
<p>Hi Miles and Matt,</p>
<p>I have been using ITensor (C++, v2) to study spin systems on cylinder geometries. Thank you for all your great work with this package.</p>
<p>Recently, I was interested in calculating the momentum-resolved entanglement spectrum and I was wondering if there is an efficient way to do so in ITensor. To begin with, I have been able to compute the (unresolved) entanglement spectrum as follows:</p>
<pre><code>int b = Nx*Ny/2; count = 1;
psi.position(b);
ITensor wf = psi.A(b)*psi.A(b+1);
auto U = psi.A(b);
ITensor S,V;
auto spectrum = svd(wf,U,S,V);
SvN = 0.0;
for(auto p : spectrum.eigs())
{
if(p > 1E-12) SvN += -p*log(p);
if(count <=10)
{fprintf(myfile,"%.12f\n",-log(p));
count++;
}
}
</code></pre>
<p>Since I’m working on a cylinder, the momentum in the y direction should be a good quantum number but how would one obtain this from the DMRG-optimized MPS wavefunction? Let me also note that my Hamiltonian does not have any other conserved (spin) quantum numbers so I am using ITensors instead of IQTensors.</p>
<p>In particular, I have seen the procedure outlined in Appendix C of <a rel="nofollow" href="https://arxiv.org/abs/1208.2623">arXiv:1208.2623</a>, but I am not exactly sure of how to implement it. If you happen to have a code snippet (or any existing ITensor functionality) for this purpose, which I could use as a starting point, that would be extremely helpful. Thanks so much!</p>
<p>Best wishes,<br>
RS </p>
http://itensor.org/support/2197/momentum-resolved-entanglement-spectrumThu, 11 Jun 2020 15:47:13 +0000Breaking the Sz symmetry using an ITensor
http://itensor.org/support/2192/breaking-the-sz-symmetry-using-an-itensor
<p>Follow up on this question: <a rel="nofollow" href="https://itensor.org/support/2072/products-of-2-site-and-4-site-wavefunctions">https://itensor.org/support/2072/products-of-2-site-and-4-site-wavefunctions</a></p>
<p>The tetramers that I used to have are:<img src="https://latex.codecogs.com/gif.latex?%5Cfrac%7B1%7D%7B%5Csqrt%7B12%7D%7D%28%7C%7B%5Cuparrow_1%5Cuparrow_2%5Cdownarrow_3%5Cdownarrow_4%7D%3E-%7C%7B%5Cuparrow_1%5Cdownarrow_2%5Cuparrow_3%5Cdownarrow_4%7D%3E-2%7C%7B%5Cuparrow_1%5Cdownarrow_2%5Cdownarrow_3%5Cuparrow_4%7D%3E-2%7C%7B%5Cdownarrow_1%5Cuparrow_2%5Cuparrow_3%5Cdownarrow_4%7D%3E-%7C%7B%5Cdownarrow_1%5Cuparrow_2%5Cdownarrow_3%5Cuparrow_4%7D%3E+%7C%7B%5Cdownarrow_1%5Cdownarrow_2%5Cuparrow_3%5Cuparrow_4%7D%3E%29" alt="here:"> </p>
<p>Now my purpose is instead of having only 6 states for each tetramer (the Sz=0 part) is having all 2^4 = 16 states (adding the 3 ups-1 down, 1 up-3 downs, 4 ups, 4 downs cases).</p>
<p>I tried:</p>
<pre><code> for(int n = 1; n <= N; n += 4)
{
auto s1 = sites(n);
auto s2 = sites(n+1);
auto s3 = sites(n+2);
auto s4 = sites(n+3);
normalization = 0;
int pos = n/4*ms;
for (int i=pos; i<=pos+ms-1; i++)
normalization += pow(gsl_vector_get(cicoeff,i),2);
auto wf = ITensor(s1,s2,s3,s4);
wf.set(s1(1),s2(1),s3(2),s4(2), gsl_vector_get(cicoeff, pos)/sqrt(normalization));
wf.set(s1(1),s2(2),s3(1),s4(2), gsl_vector_get(cicoeff, pos+1)/sqrt(normalization));
wf.set(s1(1),s2(2),s3(2),s4(1), gsl_vector_get(cicoeff, pos+2)/sqrt(normalization));
wf.set(s1(2),s2(1),s3(1),s4(2), gsl_vector_get(cicoeff, pos+3)/sqrt(normalization));
wf.set(s1(2),s2(1),s3(2),s4(1), gsl_vector_get(cicoeff, pos+4)/sqrt(normalization));
wf.set(s1(2),s2(2),s3(1),s4(1), gsl_vector_get(cicoeff, pos+5)/sqrt(normalization));
wf.set(s1(2),s2(1),s3(1),s4(1), gsl_vector_get(cicoeff, pos+6)/sqrt(normalization));
wf.set(s1(1),s2(2),s3(1),s4(1), gsl_vector_get(cicoeff, pos+7)/sqrt(normalization));
wf.set(s1(1),s2(1),s3(2),s4(1), gsl_vector_get(cicoeff, pos+8)/sqrt(normalization));
wf.set(s1(1),s2(1),s3(1),s4(2), gsl_vector_get(cicoeff, pos+9)/sqrt(normalization));
wf.set(s1(2),s2(2),s3(2),s4(1), gsl_vector_get(cicoeff, pos+10)/sqrt(normalization));
wf.set(s1(2),s2(2),s3(1),s4(2), gsl_vector_get(cicoeff, pos+11)/sqrt(normalization));
wf.set(s1(2),s2(1),s3(2),s4(2), gsl_vector_get(cicoeff, pos+12)/sqrt(normalization));
wf.set(s1(1),s2(2),s3(2),s4(2), gsl_vector_get(cicoeff, pos+13)/sqrt(normalization));
wf.set(s1(2),s2(2),s3(2),s4(2), gsl_vector_get(cicoeff, pos+14)/sqrt(normalization));
wf.set(s1(1),s2(1),s3(1),s4(1), gsl_vector_get(cicoeff, pos+15)/sqrt(normalization));
psi.ref(n) = ITensor(s1);
psi.ref(n+1) = ITensor(s2);
auto [U,S,V] = svd(wf,{inds(psi.ref(n))},{"Cutoff=",1E-8});
psi.ref(n) = U;
psi.ref(n+1) = S*V;
psi.ref(n+2) = ITensor(s3);
ITensor U2(commonIndex(psi.ref(n), psi.ref(n+1)),inds(ITensor(s2))),S2,V2;
svd(S*V,U2,S2,V2);
psi.ref(n+1) = U2;
psi.ref(n+2) = S2*V2;
psi.ref(n+3) = ITensor(s4);
ITensor U3(commonIndex(psi.ref(n+1), psi.ref(n+2)),inds(ITensor(s3))),S3,V3;
svd(S2*V2,U3,S3,V3);
psi.ref(n+2) = U3;
psi.ref(n+3) = S3*V3;
}
</code></pre>
<p>but I am getting a "Setting Tensor element non-zero would violate its symmetry." error. The code above works perfectly if I consider only the Sz=0 part, so I am pretty sure that the problem is that I consider more Sz sectors now. </p>
<p>Is there a way to code that? Reading the Itensor's documentation, I found the mixedIQTensor() function, but I didn't quite understand if it does exactly what I want to do.</p>
<p>Any thoughts on that?</p>
<p>Thank you very much,<br>
Thanos</p>
http://itensor.org/support/2192/breaking-the-sz-symmetry-using-an-itensorWed, 10 Jun 2020 16:40:36 +0000Questions about random initial MPS under QN conservation ("randomMPS(sites, state, linkdim)" in Julia)
http://itensor.org/support/2186/questions-random-initial-conservation-randommps-linkdim
<p>I am exploring the "randomMPS(sites, state, linkdim)" function in the Julia version of the code, used to initialize a random MPS under QN conservation. I toyed around with the following basic code:</p>
<pre><code>N = 100
linkdim = 1
sites = Index[]
sites = siteinds("S=1/2", N, conserve_qns=true)
ampo_H = AutoMPO()
for j = 1:N-1
add!(ampo_H, 1, "S+", j, "S-", j+1)
end
H = MPO(ampo_H, sites)
sweeps = Sweeps(10)
maxdim!(sweeps, 10,20,100,100,200)
cutoff!(sweeps, 1E-10)
init_state = [isodd(n) ? 1 : 2 for n = 1:N]
psi0 = randomMPS(sites, init_state, linkdim)
energy, psi = dmrg(H, psi0, sweeps)
println("Ground state energy = $energy")
</code></pre>
<p>When I used linkdim = 0 or linkdim = 1, I got the following (the times were different, but the energies after each sweep were identical):</p>
<pre><code>After sweep 1 energy=-20.093813857715 maxlinkdim=3 time=46.208
After sweep 2 energy=-19.645716775053 maxlinkdim=6 time=0.633
After sweep 3 energy=-23.704160971099 maxlinkdim=21 time=0.837
After sweep 4 energy=-21.976581439869 maxlinkdim=50 time=1.242
After sweep 5 energy=-17.979053940609 maxlinkdim=113 time=2.240
After sweep 6 energy=-12.781825304274 maxlinkdim=200 time=4.182
After sweep 7 energy=-18.735327685101 maxlinkdim=200 time=6.456
After sweep 8 energy=-17.554817334205 maxlinkdim=200 time=6.428
After sweep 9 energy=-11.592260452089 maxlinkdim=200 time=6.489
After sweep 10 energy=-18.150972193173 maxlinkdim=200 time=6.039
Ground state energy = -18.150972193173168
</code></pre>
<p>When I used linkdim = 2, I got the following:</p>
<pre><code>After sweep 1 energy=-17.138433694197 maxlinkdim=7 time=16.842
After sweep 2 energy=-19.329082230479 maxlinkdim=20 time=0.785
After sweep 3 energy=-14.965351818888 maxlinkdim=55 time=1.271
After sweep 4 energy=-14.037715046585 maxlinkdim=100 time=2.089
After sweep 5 energy=-18.253177305167 maxlinkdim=200 time=4.063
After sweep 6 energy=-17.967870954570 maxlinkdim=200 time=6.248
After sweep 7 energy=-19.513691584655 maxlinkdim=200 time=6.625
After sweep 8 energy=-18.245438077285 maxlinkdim=200 time=6.188
After sweep 9 energy=-17.493978866991 maxlinkdim=200 time=6.266
After sweep 10 energy=-17.804622748715 maxlinkdim=200 time=5.827
Ground state energy = -17.804622748714813
</code></pre>
<p>Finally, when I used linkdim = 10, I got the following:</p>
<pre><code>After sweep 1 energy=-18.432676648899 maxlinkdim=10 time=17.006
After sweep 2 energy=-19.905158282446 maxlinkdim=20 time=0.990
After sweep 3 energy=-23.774621818681 maxlinkdim=65 time=1.544
After sweep 4 energy=-16.035532730501 maxlinkdim=100 time=2.895
After sweep 5 energy=-10.002545372991 maxlinkdim=200 time=5.878
After sweep 6 energy=-25.311587050851 maxlinkdim=200 time=7.119
After sweep 7 energy=-17.279971718254 maxlinkdim=200 time=7.238
After sweep 8 energy=-13.021013397538 maxlinkdim=200 time=7.013
After sweep 9 energy=-18.874581289730 maxlinkdim=200 time=7.202
After sweep 10 energy=-28.130306372441 maxlinkdim=200 time=6.768
Ground state energy = -28.13030637244088
</code></pre>
<p>These results were quite perplexing. Furthermore, in a more complicated setup, I ended up getting an error "MPS center bond dim less than requested". (I was trying to set up the Schwinger model, in line with <a rel="nofollow" href="http://itensor.org/support/2140/implementing-local-gauge-symmetries"></a><a rel="nofollow" href="http://itensor.org/support/2140/implementing-local-gauge-symmetries">http://itensor.org/support/2140/implementing-local-gauge-symmetries</a>. I can post the code if you want, but I'm not sure how helpful it would be here.) I got this error with several values of linkdim, including 4, 10, and 100, although I did not get it with the default linkdim = 1.</p>
<p>As a result of all of these things, I had a number of questions:</p>
<p>(1) As you can see in all of the above examples, the energy is not decreasing with each sweep as one would naturally expect. Instead it is jumping all over the place. Am I doing something fundamentally wrong here?</p>
<p>(2) As you can see above, one can set linkdim to 0, and that it gives the same answer as linkdim=1. Why is a linkdim of 0 even allowed? Maybe I'm totally misunderstanding what this is representing here, but I thought it had to be at least 1. I assume an answer to this will also explain why the code gives identical results for linkdim=0 and linkdim=1.</p>
<p>(3) What is the source of the error "MPS center bond dim less than requested", and how does one make sure it doesn't happen? I looked for it in the code, but I really didn't understand it.</p>
<p>(4) More broadly, are there some general pointers for how one should choose the linkdim value for a given situation? It seems based that the default of linkdim=1 will just return the state you specified without introducing any randomness, so I am assuming you should not pick this for sure.</p>
http://itensor.org/support/2186/questions-random-initial-conservation-randommps-linkdimTue, 09 Jun 2020 23:37:16 +0000DMRG does nothing in certain cases if initial state chosen deterministically? (Julia)
http://itensor.org/support/2181/nothing-certain-initial-state-chosen-deterministically-julia
<p>I am finding a problem with something seemingly very simple. Basically, the following Julia code implements a Hamiltonian that is just Sz on each of N spin-1/2 sites. Clearly the ground state energy is -N/2.</p>
<pre><code>N = 100
sites = siteinds("S=1/2", N)
ampo_H = AutoMPO()
for j = 1:N
add!(ampo_H, 1, "Sz", j)
end
H = MPO(ampo_H, sites)
sweeps = Sweeps(5)
maxdim!(sweeps, 10,20,100,100,200)
cutoff!(sweeps, 1E-10)
init_state = [n % 3 == 0 ? "Up" : "Dn" for n=1:N]
psi0 = productMPS(sites, init_state)
# psi0 = randomMPS(sites)
energy, psi = dmrg(H, psi0, sweeps)
println("Ground state energy = $energy")
</code></pre>
<p>However, if you run the code, you will not get a ground state energy of -50. DMRG will simply stay put at an energy of -17, which you may notice is just the energy of the initial state. Feel free to try other deterministic choices of psi0; you should see the same thing happen.</p>
<p>In contrast, if you remove the deterministic choice of psi0 and uncomment the line that says "psi0 = randomMPS(sites)", you should now see that DMRG immediately converges to the right answer, as one would expect.</p>
<p>I know that I have run DMRG on a lattice formulation of the Schwinger model (Kogut-Susskind staggered lattice with Jordan-Wigner transformation and open boundary conditions) with successful results. I used a deterministic initial state for that, and that lattice was also on spin-1/2 sites, so I'm not sure why this one isn't working.</p>
<p>What exactly is going on here? If DMRG is looking for the ground state energy, why should it matter whether the initial state was chosen randomly or deterministically? Any clarification on this would be greatly appreciated.</p>
http://itensor.org/support/2181/nothing-certain-initial-state-chosen-deterministically-juliaTue, 09 Jun 2020 07:42:51 +0000Compress an MPS without an operation.
http://itensor.org/support/2178/compress-an-mps-without-an-operation
<p>Hi,</p>
<p>I was wondering if there is a way to compress an MPS without doing another operation? The context is that I want to apply an MPO to an MPS, then process the resulting MPS, and then reduce the bond dimension. So I basically want to postpone compressing the MPS until after I process, rather than after the MPO is applied.</p>
<p>Best,<br>
Nick</p>
http://itensor.org/support/2178/compress-an-mps-without-an-operationTue, 09 Jun 2020 00:05:28 +0000A particular initial guess for DMRG calculation
http://itensor.org/support/2166/a-particular-initial-guess-for-dmrg-calculation
<p>Dear all</p>
<p>I am interested to specify a kind of pair-singlet initial guess to do DMRG, instead of "auto psi0 = randomMPS(sites)"</p>
<p>Let me be more clear: assume we have 6 spins-1/2 and they make pairs as follows [(1,5),(2,3),(4,6)], and psi0 should be a tensor product of these singlet-pairs as below: see here: <img src="https://ibb.co/DKgrRkt" alt="singlet"></p>
<p><a rel="nofollow" href="https://ibb.co/DKgrRkt">https://ibb.co/DKgrRkt</a></p>
<p>here is the latex formula: </p>
<p>psi0=\otimes<em>{\rm singlest-pairs} |o</em>{ij}\rangle,~~ |o<em>{ij}\rangle=\frac{|\uparrow</em>i\downarrow<em>j\rangle-|\uparrow</em>j\downarrow_i\rangle}{\sqrt{2}}</p>
<p>Many thanks for your help <br>
Bests regards<br>
Javad</p>
http://itensor.org/support/2166/a-particular-initial-guess-for-dmrg-calculationThu, 04 Jun 2020 18:12:28 +0000I think diagHermitian may not be working properly.
http://itensor.org/support/2160/i-think-diaghermitian-may-not-be-working-properly
<p>Here is some code that is essentially what I am doing. H is an XYZ model with different couplings in all directions. psi is the ground state of the Heisenberg model. N(L) = 4. NumCenter = 1 for the LocalMPO as well.</p>
<pre><code>/* psi is ground state with QNs removed,
MaxDim=10. */
sites = SpinHalf(N);
auto ampo = AutoMPO(sites);
for(auto j : range1(N-1))
{
ampo += 0.5,"S+",j,"S-",j+1;
ampo += -0.5,"S-",j,"S+",j+1;
ampo += 0.317,"Sz",j,"Sz",j+1;
}
auto H = removeQNs(toMPO(ampo));
psi.position(1);
LocalMPO PH(H,*args);
PH.numCenter(1);
PH.position(1,psi);
auto R = PH.R();
auto Heff = PH.H()(1)*R;
ITensor d;
ITensor U;
diagHermitian(Heff,U,d);
auto res = U*d*prime(U);
PrintData(Heff);
PrintData(res);
auto dif = res - Heff;
PrintData(norm(dif));
</code></pre>
<p>The result for the printouts are</p>
<pre><code>Heff =
ITensor ord=4: (dim=2|id=213|"n=1,Site,S=1/2") (dim=2|id=213|"n=1,Site,S=1/2")' (dim=2|id=925|"l=1,Link") (dim=2|id=925|"l=1,Link")'
{norm=0.69 (Dense Real)}
(1,1,1,1) -0.026417
(2,2,1,1) -0.170760
(1,2,2,1) -0.455342
(2,1,1,2) 0.4553418
(1,1,2,2) -0.170760
(2,2,2,2) -0.026417
res =
ITensor ord=4: (dim=2|id=213|"n=1,Site,S=1/2")' (dim=2|id=925|"l=1,Link")' (dim=2|id=213|"n=1,Site,S=1/2") (dim=2|id=925|"l=1,Link")
{norm=0.69 (Dense Real)}
(1,1,1,1) -0.026417
(2,1,2,1) -0.170760
(1,2,2,1) 0.4553418
(2,1,1,2) 0.4553418
(1,2,1,2) -0.170760
(2,2,2,2) -0.026417
norm(dif) = 0.910684
</code></pre>
<p>We see the error lies in the (1,2,2,1) element.</p>
<p>I've tried leaving QNs on the tensors, and different equivalent forms for res, and I'm not sure what's wrong here. Any help would be greatly appreciated.</p>
<p>Best,<br>
Nick</p>
http://itensor.org/support/2160/i-think-diaghermitian-may-not-be-working-properlyWed, 03 Jun 2020 15:27:07 +0000Various questions about QN conservation in Julia
http://itensor.org/support/2156/various-questions-about-qn-conservation-in-julia
<p>I think I get the gist of how QN conservation works in ITensors.jl, but now that I want to try doing more complicated things, I want to make sure I really understand it properly. To that end, I had a few questions.</p>
<p>(1) Do the quantum numbers have to be integers? If so, is there a fundamental reason for forcing them to be this way in the code?</p>
<p>(2) Here is code taken from the spinone.jl file. Other examples will have similar things:</p>
<pre><code>if conserve_sz
up = QN("Sz",+2) => 1
z0 = QN("Sz", 0) => 1
dn = QN("Sz",-2) => 1
return [Index(up,z0,dn;tags="Site,S=1,n=$n") for n=1:N]
end
</code></pre>
<p>What does the "=> 1" mean here, and why are all three of up, z0, dn being mapped to 1?</p>
<p>(3) Can the code handle arbitrarily many conserved QNs at once? If so, would it be possible/feasible to implement local gauge symmetries (such as the Gauss's Law constraint on the lattice formulation of the Schwinger model, which was mentioned in another question) using conserved QNs?</p>
<p>(4) My understanding is that, if you are conserving some QN, each term in an MPO that you create has to have a definite QN flux--for instance, if you are conserving total Sz, then you need to use S+ and S- operators instead of Sx and Sy operators. However, in an MPO I constructed for the Hamiltonian of the lattice Schwinger model, even though I am pretty sure I only used allowed operators, I got a different error saying:</p>
<pre><code>LoadError: No block found with QN equal to QN(("Sz",-4))
</code></pre>
<p>I can post some code, but it would be a bit long, and I'm not sure how helpful it would be. For context, the lattice has alternating spin-1/2 sites (for the fermions and antifermions) and spin-1 sites (for the links, which I am truncating at 1 for now, which is why I can describe them as spin-1 sites). My best guess at what is going on here is that there is a term in the Hamiltonian that, when applied to a state, changes the total Sz by -4. But why is this an issue? Does this mean that every term in the MPO must not change the total Sz? If not, then what is the relevant constraint?</p>
<p>I tried to look at some of the other source files to understand these things better, but I wasn't getting any clarity. Any help on this would be greatly appreciated.</p>
http://itensor.org/support/2156/various-questions-about-qn-conservation-in-juliaTue, 02 Jun 2020 20:04:07 +0000