ITensor Support Q&A - Recent questions and answers
http://itensor.org/support/qa
Powered by Question2AnswerAnswered: Purpose of various actions and parameters in replacebond! function?
http://itensor.org/support/2418/purpose-various-actions-parameters-replacebond-function?show=2419#a2419
<p>Hi Sujay,</p>
<p>1) The Spectrum object returns the eigenspectrum of the density matrix (the squared singular values). The idea is that, in the process of calculating the factors <code>L</code> and <code>R</code>, the eigenspectrum is often easily calculated as well, and it is a useful quantity for determining things like the entanglement entropy. It is returned so that you don't have to do extra work to calculate the eigenspectrum from either <code>L</code> or <code>R</code>, and users may want to print the eigenspectrum or return it from dmrg and perform calculation with it.</p>
<p>2) You may want to set normalize to true in cases like imaginary time evolution with TEBD, where if you don't normalize then the state's normalization will approach zero after some number of steps. <code>replacebond!</code> is a convenient place for that normalization to occur. By default it is chosen to be false, since it is application-dependent when someone may want that to occur, and users might want to normalize manually in case they want to save the norm (if it is physically relevant, for example).</p>
<p>3) The MPS/MPO types in ITensor can mostly be thought of as just vectors of ITensors that make up the MPS/MPO. However, they are a little more sophisticated than that, since they keep track of the orthogonality of the MPS/MPO. Information about the orthogonality is useful in various functions, where if you know the orthogonality than you can simplify certain expressions. So <code>l = leftlim(M)</code> is supposed to be set to <code>l</code>, such that sites <code>1:l</code> are guaranteed to be left orthogonal, and <code>r = rightlim(M)</code> is supposed to be set to <code>r</code>, such that sites <code>r:length(M)</code> are guaranteed to be right orthogonal.</p>
<p>This is helpful so that certain functions can assume that an MPS has a certain orthogonality so that they don't have to do extra work to reorthogonalize. For example, the <code>sample</code> function, which takes random samples of an MPS, assumes a certain orthogonality of the MPS that is input. In functions that manipulate tensors of an MPS/MPO, it is therefore good practice to keep track of the orthogonality so that extra work doesn't have to be done to unnecessarily reorthogonalize the MPS (or check for the orthogonality, which would be nearly as much work). Not keeping track of the orthogonality wouldn't lead to wrong code, but in general would require extra unnecessary work to be done.</p>
<p>-Matt</p>
http://itensor.org/support/2418/purpose-various-actions-parameters-replacebond-function?show=2419#a2419Wed, 29 Jul 2020 13:21:24 +0000Answered: How 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?show=2416#a2416
<p>(Please see answer to question in discussion above.)</p>
http://itensor.org/support/2403/separate-product-itensor-objects-tensors-common-indices-julia?show=2416#a2416Tue, 28 Jul 2020 17:32:15 +0000Answered: Julia script for calculating energy gaps
http://itensor.org/support/2411/julia-script-for-calculating-energy-gaps?show=2412#a2412
<p>Hi Arnab,<br>
Thanks for the question - we do need to post a code example for this. Here is a short explanation though, and using it you ought to be able to adapt one of the other DMRG code examples to do excited states.</p>
<ol>
<li><p>say you calculate the ground state as follows:</p>
<p>energy0,psi0 = dmrg(H,psi0_i,sweeps)</p></li>
</ol>
<p>where here psi0_i is the initial guess for the ground state and psi0 is the optimized ground state.</p>
<ol>
<li><p>now you can calculate the first excited state as:</p>
<p>energy1,psi1 = dmrg(H,[psi0],psi1_i,sweeps;weight=weight)</p></li>
</ol>
<p>where psi1_i is the initial guess for the first excited state and <code>weight</code> is a positive number that you can adjust to penalize non-orthogonality of the ground and first excited state by different amounts (like a Lagrange multiplier).</p>
<ol>
<li><p>you can continue to calculate the second excited state as:</p>
<p>energy2,psi2 = dmrg(H,[psi0,psi1],psi2_i,sweeps; weight=weight)</p></li>
</ol>
<p>One tip is to do lots more sweeps for excited states than for ground states. Use your best judgement, and make sure that the energy is no longer changing over multiple sweeps before being sure things have converged. People often ask what value to take for the weight and I do not know because it is problem-dependent. Taking the weight to be 1.0 (the default) is good for most purposes though you can try other values to see if it speeds up convergence.</p>
<p>Hope that helps!</p>
<p>Miles</p>
http://itensor.org/support/2411/julia-script-for-calculating-energy-gaps?show=2412#a2412Tue, 28 Jul 2020 16:04:44 +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 +0000Answered: Swapping indices of an MPS for Hubbard
http://itensor.org/support/2379/swapping-indices-of-an-mps-for-hubbard?show=2409#a2409
<p>See the comments for an answer.</p>
http://itensor.org/support/2379/swapping-indices-of-an-mps-for-hubbard?show=2409#a2409Tue, 28 Jul 2020 00:59:29 +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 +0000Answered: Intel MKL error
http://itensor.org/support/2345/intel-mkl-error?show=2389#a2389
<p>(Please see the discussion above.)</p>
http://itensor.org/support/2345/intel-mkl-error?show=2389#a2389Fri, 24 Jul 2020 02:55:35 +0000Answered: Looking for recommendations for applying Tensor Networks for simple problems (Julia).
http://itensor.org/support/2362/looking-recommendations-applying-networks-simple-problems?show=2388#a2388
<p>Hi, thanks for the reply above. I’m still not totally sure what you are looking for, because applying DMRG to the Ising model does seem like a good way to start. But if you are looking for some other activities to practice using DMRG and MPS here is another thing you can do.</p>
<ol>
<li><p>take the example DMRG code from here:<br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=julia&page=formulas/mixed_sites_dmrg">http://itensor.org/docs.cgi?vers=julia&page=formulas/mixed_sites_dmrg</a></p></li>
<li><p>modify it to measure on every site at the end, after the MPS is optimized, using code similar to that in this “code formula” page:<br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=julia&page=formulas/measure_mps">http://itensor.org/docs.cgi?vers=julia&page=formulas/measure_mps</a></p></li>
</ol>
<p>The resulting magnetization should be rather flat!</p>
<ol>
<li>now change the logic of how the “siteinds” function is called at the top by changing the condition <code>isodd(n)</code> to <code>(n==1)</code> which will set the spin to be “S=1/2” only on the first site. The bulk sites and site N will be S=1 spins. Rerun the calculation. What’s changed about the magnetization? Can you explain why it’s still very flat on the right-hand side? (It has to do with the physics of SPT’s and the “AKLT” picture of the physics of the S=1 Heisenberg chain.)</li>
</ol>
<p>For something resembling a walk through, have you looked at the paper “DMRG in the Age of Matrix Product States” by Schollwoeck? It is essential reading for anyone wanting to become an expert in MPS techniques. </p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/2362/looking-recommendations-applying-networks-simple-problems?show=2388#a2388Fri, 24 Jul 2020 02:54:50 +0000Answered: Why is a ProjMPO callable but an ITensor not? (Julia)
http://itensor.org/support/2376/why-is-a-projmpo-callable-but-an-itensor-not-julia?show=2384#a2384
<p>It sounds like you are trying to pass the ITensor <code>M</code> as the operator directly to eigsolve. If that is the case, we have not defined the operation <code>M(v)</code>, since it is not clear what the definition of that should be in general (it makes sense if ITensor M has pairs of primed and unprimed indices, but doesn't for other ITensors). I had been considering defining <code>M(v)</code> for certain kinds of ITensors, but we were being conservative about it to start out.</p>
<p>In the meantime, you can define your own callable ITensor wrapper, which here I call an ITensorMap:</p>
<pre><code>using ITensors
using KrylovKit
i = Index(2)
M = randomITensor(i', dag(i))
v0 = randomITensor(i)
# λs, vs = eigsolve(M, v0)
# Gives:
# ERROR: MethodError: objects of type ITensor{2} are not callable
struct ITensorMap
A::ITensor
end
(M::ITensorMap)(v::ITensor) = noprime(M.A * v)
λs, vs = eigsolve(ITensorMap(M), v0)
@show norm(noprime(M * vs[1]) - vs[1] * λs[1])
</code></pre>
<p>This will be a way to test if you are making your custom projected MPO correctly.</p>
<p>However, in general, it is not as efficient to form the operator and then contract it with the ITensor <code>v</code>. Instead, you should define something like the ProjMPO that contains the ITensors of the projected Hamiltonian you are interested in (in your case, H[1], H[N], and then the contraction of the bulk tensors 2...N-1), and define your own function like the product function here:</p>
<p><a rel="nofollow" href="https://github.com/ITensor/ITensors.jl/blob/master/src/mps/projmpo.jl#L71">https://github.com/ITensor/ITensors.jl/blob/master/src/mps/projmpo.jl#L71</a></p>
<p>which takes the ITensor "vector" and applies the appropriate tensors. In the end the two approaches are equivalent, but the order of contraction is different, which can make a big difference in the efficiency of your algorithm.</p>
http://itensor.org/support/2376/why-is-a-projmpo-callable-but-an-itensor-not-julia?show=2384#a2384Thu, 23 Jul 2020 14:38:50 +0000Answered: When 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?show=2380#a2380
<p>Hi Sujay,<br>
I believe the reason you are seeing this is because you are creating new functions inside of the ITensors module (which is fine) but then not listing these function names as "exported". So they are only remaining accessible as <code>ITensors.function_name</code> rather than just <code>function_name</code>. Or you can explicitly import them by doing <code>import ITensors: function_name</code> in your driver code.</p>
<p>We keep all of the ITensors exports in the file src/exports.jl</p>
<p>Best,<br>
Miles</p>
http://itensor.org/support/2375/itensors-modifications-existing-functions-recognized-functions?show=2380#a2380Wed, 22 Jul 2020 17:51:21 +0000Answered: non-Hermitian DMRG in Julia
http://itensor.org/support/2367/non-hermitian-dmrg-in-julia?show=2371#a2371
<p>Hi Terry,<br>
The short answer is that this is not currently available in the Julia version at the level of an option you can pass to the <code>dmrg</code> function, if that's what you are asking. Similarly for the C++ version there is no such option, though as you noted we do offer an Arnoldi algorithm code.</p>
<p>But for both versions you could modify the DMRG code to use Arnoldi. For the Julia version this should actually be pretty straightforward, because the <code>eigsolve</code> function we call from Julia is a function offered by the package KrylovKit.jl and that same <code>eigsolve</code> function offers the ability to change the algorithm to Arnoldi. Here is a documentation page on eigsolve explaining about this:<br>
<a rel="nofollow" href="https://jutho.github.io/KrylovKit.jl/stable/man/eig/">https://jutho.github.io/KrylovKit.jl/stable/man/eig/</a></p>
<p>However, not having written non-Hermitian DMRG myself, I'm not sure off hand what other changes might be needed to the rest of the DMRG algorithm. Perhaps not very many other than changing the eigen solver? </p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/2367/non-hermitian-dmrg-in-julia?show=2371#a2371Mon, 20 Jul 2020 17:57:00 +0000Answered: Cluster Hamiltonian ground state MPS bond dimension
http://itensor.org/support/2369/cluster-hamiltonian-ground-state-mps-bond-dimension?show=2370#a2370
<p>Hi Arnab,<br>
Thanks for the question. I believe the reason for the bond dimension of 4 you're seeing is because you are using periodic boundary conditions. If you envision the MPS as going around a circle and having bond dimension 2 on every bond, but then flattening this topology into a line, now with the bond N->1 "folded" through or "doubled over" so that it overlaps with all of the bulk bonds then each bulk bond is now carrying both the usual local entanglement (requiring bond dimension 2) as well as the extra entanglement which is going from site 1 to site N, roughly speaking.</p>
<p>Another way of putting this is that while your Hamiltonian is periodic, your MPS isn't, so this mismatch leads to a larger bond dimension.</p>
<p>I tried your code, deleting the N->1 bond terms and sure enough I do get a bond dimension of 2 afterward.</p>
<p>Best,<br>
Miles</p>
http://itensor.org/support/2369/cluster-hamiltonian-ground-state-mps-bond-dimension?show=2370#a2370Mon, 20 Jul 2020 14:47:35 +0000Answered: How to calculate spectrum function by using ITensor?
http://itensor.org/support/2366/how-to-calculate-spectrum-function-by-using-itensor?show=2368#a2368
<p>Hi，SugarYu </p>
<p>the definition C^{z}(x,t)=<g.s|exp{iHt}S^{z}(x)exp(-iHt)S^{z}(0)|g.s> is right， but<br>
C^{z}(x,t)=innerC(psi,psi4) is not correct！ <br>
You need C^{z}(x,t)=innerC(psi,psi4) <em>(Exp(energy</em>tstep*n)), where energy is the groud-state energy, and n is Time evolve number( or n-1 , dependent on measurement before Time evolve or not)</p>
<p>Then Fourier transform will be performed to obtain S(q,\omega）.</p>
<p>p.s. the S^{z}{1} often acts on central spin，N/2 or N/2+1 to avoid the boundary effects.</p>
<p>Hope it can help you</p>
http://itensor.org/support/2366/how-to-calculate-spectrum-function-by-using-itensor?show=2368#a2368Mon, 20 Jul 2020 09:16:43 +0000Answered: Trying 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?show=2361#a2361
<p>Hi Sujay,<br>
To answer your question I thought it would be easier to show you some diagrams, which I uploaded to this link:</p>
<p><a rel="nofollow" href="https://itensor.org/miles/ProjMPS.pdf">https://itensor.org/miles/ProjMPS.pdf</a></p>
<p>Can you please let me know if those notes answer your question and give a clear enough idea of what the code there is doing? </p>
<p>The purpose of this ProjMPS overall is to make a Hamiltonian term that is equal to |M><M| for some state M (represented as an MPS) then include this Hamiltonian term in an efficient way within a DMRG calculation that's optimizing an MPS psi.</p>
<p>I think the code there already partially works for n-site DMRG, because you can see that makeL! and makeR! (which are called by position!) query a parameter P.nsite which right now is always set to 2 but could be adjusted. Then the code in <code>product</code> would need to be extended to multiply on the center "n" tensors of M in the lower part of the diagram in the notes, rather than just the two center tensors right now. These two tensors right now are getting included by the lines:</p>
<pre><code>Lpm = dag(prime(P.M[P.lpos+1],"Link"))
</code></pre>
<p>and </p>
<pre><code>Rpm = dag(prime(P.M[P.rpos-1],"Link"))
</code></pre>
<p>Best,<br>
Miles</p>
http://itensor.org/support/2344/trying-understand-product-function-projmps-generalize-julia?show=2361#a2361Thu, 16 Jul 2020 20:00:28 +0000Answered: Copying MPS into vector
http://itensor.org/support/2354/copying-mps-into-vector?show=2356#a2356
<p>Hi, I’d recommend Matt’s answer above as the correct one:</p>
<p>1) yes, the copy of an MPS does not copy the data right away. (Actually this is true even at the ITensor level, so applies to any container holding ITensors too.) So the copying only happens at the last possible minute, when you modify one of the MPS tensors and then have to copy it anyway.</p>
<p>2) most important is what Matt said about the timing. It’s not slow to copy data, or to do any operation, unless you can measure that it takes a significant percentage of your code’s running time. So if your code copies MPS thousands of times, or if the MPS itself is on a system with thousands of sites or has a bond dimension in the 10’s of thousands, then it might be a slow part of your code. But otherwise it should take probably only a handful of microseconds or at worst milliseconds at most for normal MPS sizes.</p>
<p>Please let us know if you are able to measure a slowdown of your code that is due to copying MPS and we can discuss ways to mitigate it in that case.</p>
<p>Best,<br>
Miles</p>
http://itensor.org/support/2354/copying-mps-into-vector?show=2356#a2356Sat, 11 Jul 2020 19:58:02 +0000Answered: Storing MPS Tensors as Text/HDF5 file in Julia
http://itensor.org/support/2347/storing-mps-tensors-as-text-hdf5-file-in-julia?show=2351#a2351
<p>Hi, thanks for the question. This is something we need to document even more about the Julia version of ITensor to make it clear it’s available and that you can use it for MPS too. </p>
<p>Here are the steps to write an ITensor to an HDF5 file, and you can use exactly the same steps to write a whole MPS to HDF5, just with T being an object of type MPS instead of type ITensor:</p>
<p><a rel="nofollow" href="http://itensor.org/docs.cgi?vers=julia&page=formulas/itensor_hdf5">http://itensor.org/docs.cgi?vers=julia&page=formulas/itensor_hdf5</a></p>
<p>Please let me know if you have any questions about that or if you run into any issues and I’d be happy to discuss. </p>
<p>Miles</p>
http://itensor.org/support/2347/storing-mps-tensors-as-text-hdf5-file-in-julia?show=2351#a2351Fri, 10 Jul 2020 15:22:21 +0000Answered: Non-consecutive swap gates
http://itensor.org/support/2330/non-consecutive-swap-gates?show=2333#a2333
<p>Thanks for the good question. To officially answer the question, I agree with Matt's answer above. Unless you have a very specific understanding of the entanglement properties of the wavefunction you're working with, such that it can be compactly represented as an MPS in both site orderings (which is very unlikely given how non-locally they are related to each other) then probably you will encounter very large bond dimensions going to the non-local site order.</p>
<p>If you are definitely going to stick to nnn interactions at most, though, and if you are interesting in doing some by-hand coding beyond just using the ITensor gateTEvol function, then there are some other things you may want to try. No guarantee these are faster though the first one probably is:</p>
<ol>
<li><p>instead of applying an explicit swap gate, do a "virtual swap gate" by just contracting the MPS tensors for sites j+1,j+2 then SVD'ing them back apart so that the "U" tensor carries the j+2 site index (and the left link index from the original j+1 MPS tensor). ITensor lets you control which indices end up on U by which indices you pass to the <code>svd</code> function. Then do a similar contract-and-SVD to 'swap' back. It saves the extra computation time of applying an explicit gate to the MPS.</p></li>
<li><p>try contracting 3 MPS tensors in a row, so j,j+1,j+2 and then applying all possible nn and nnn gates acting on those 3 sites. This has an advantage that it can reduce the total truncation errors incurred because no truncation is needed while applying those gates. Now use the SVD to factorize off the "j" site and left link index into an update MPS tensor for site j. Save the remaining (S*V) tensor from the SVD and contract it with the MPS tensor for site j+3 to go to the next configuration. This approach may not be the most efficient, though, due to working with the larger "core" tensor having one extra site index. But it could be more efficient due to less swapping and more accurate due to fewer truncations.</p></li>
</ol>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/2330/non-consecutive-swap-gates?show=2333#a2333Tue, 07 Jul 2020 14:29:14 +0000Answered: How to implement a truly periodic MPS? (Julia)
http://itensor.org/support/2327/how-to-implement-a-truly-periodic-mps-julia?show=2331#a2331
<p>Hi Sujay,<br>
This is a worthy goal to think about, but let me discuss what I know about the status of periodic MPS and a possible alternative.</p>
<p>First, would your technical issue with quantum numbers be solved also if you were to consider an infinitely-long system? As you likely know, MPS methods work well in an infinite setup and there are some very advanced and efficient algorithms for optimizing infinite MPS.</p>
<p>Truly periodic MPS, on the other hand, run into a number of crucial technical problems that to my knowledge have never been satisfactorily solved. They include:<br>
1. poor scaling or of periodic algorithms, which either involve a step that scales as bond dimension to the fourth power (so much worse that finite DMRG)<br>
2. alternatively, better scaling methods but at the cost slow updates like gradient descent optimization<br>
3. inability to efficiently compute a canonical form of periodic MPS, making steps like SVD'ing a two-site tensor or otherwise adapting the bond dimension either uncontrolled / inaccurate or inefficient</p>
<p>At the same time, for many systems either open boundary conditions are as good or an even better choice (believe it or not) though I do get that yours is a special case. But then there is the case of infinite MPS which of course is even better in some ways than periodic because it's completely free of finite-size effects.</p>
<p>Regarding the specific algorithm you sketched, I bet if you write it out in more detail you will see that it suffers from the first and third issues above, namely it will scale as the fourth power of bond dimension (thus hundreds of times slower than open DMRG) and the replacebond step will not occur in an orthogonal basis, making it an uncontrolled method.</p>
<p>Hope that helps -</p>
<p>Miles</p>
http://itensor.org/support/2327/how-to-implement-a-truly-periodic-mps-julia?show=2331#a2331Mon, 06 Jul 2020 12:03:44 +0000Answered: size() in gmres
http://itensor.org/support/2313/size-in-gmres?show=2326#a2326
<p>(Marked as answered by discussion in comments above)</p>
http://itensor.org/support/2313/size-in-gmres?show=2326#a2326Fri, 03 Jul 2020 16:11:32 +0000Answered: convert 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?show=2325#a2325
<p>Hi Chiamin,<br>
Thanks for the question. I realized we hadn't documented this feature well enough so I just added some information about it to the website.</p>
<p>The feature I'd recommend you use for this is the function <code>removeQNs(psi)</code> where <code>psi</code> is an MPS. You can call a similar function on an MPO. The <code>removeQNs</code> function returns an MPS (or MPO) with all of the zeros filled in and QN information removed from the indices.</p>
<p>So if you are able to make your operator as an MPO and your MPS as well, then you can call <code>removeQNs</code> on all of them to get dense versions and compute the quantity you want with <code>inner</code>. Note that depending on how you made each MPS or the MPO you may need to modify their site indices to be the same. But if e.g. you made the MPO with AutoMPO using the same site set as for the MPS then you should be fine.</p>
<p>Best,<br>
Miles</p>
http://itensor.org/support/2320/convert-a-quantum-number-mps-to-a-no-quantum-number-mps?show=2325#a2325Fri, 03 Jul 2020 16:11:05 +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 +0000Answered: Sweeping algorithm utilizing ITensor capabilities as best as possible.
http://itensor.org/support/2305/sweeping-algorithm-utilizing-itensor-capabilities-possible?show=2311#a2311
<p>Hi Nick,<br>
I think this is a good question - no problem. First of all, I wouldn't say there's much about ITensor specifically you can use to make this algorithm faster. By this I mean that the main things you can improve are mostly to do with the algorithm itself, and you would get the same characteristics (scaling, speed) with any reasonably efficient tensor library. So I'm just answering that part of your question first. Of course we do hope and believe that ITensor's interface makes such algorithms nice to write :^)</p>
<p>Now in terms of what you could do to make this faster, let me list a few ideas. Please note that I may have missed something in your code here or there, and I didn't run it or do a detailed sketch of the steps, so please discard or do not take too seriously any comments which you think don't apply or make sense:</p>
<ol>
<li><p>instead of building the L[i] and R[i] arrays across the whole system, do you not just need R[2] for the first step, then L[1] and R[3] for the second step, and so on? (Maybe I'm off-by-one on those numberings there but hopefully you see what I'm suggesting.) So potentially you could save a big factor here by only building the L's and R's needed at each step, and updating them as you do one sweep across rather than building them all up front.</p></li>
<li><p>the other thing I'd note is more vague, but I'm concerned by your statement that the code gets a lot slower as you increase the bond dimension. This kind of task should be rather fast for MPS of dimensions approaching 1000 at least, where I'd still expect it to take only 10's of minutes at most. So if it's much slower than that, then probably it's not scaling correctly. So then I'd recommend you print out each intermediate tensor and inspect its indices. Work out the scaling of each step and make sure it scales as chi^3 where chi is the typical bond dimension of the two MPS involved (just here assuming they have the same bond dimension for simplicity).</p></li>
</ol>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/2305/sweeping-algorithm-utilizing-itensor-capabilities-possible?show=2311#a2311Tue, 30 Jun 2020 16:56:49 +0000Answered: Questions about checks for ITensors.jl pull request
http://itensor.org/support/2290/questions-about-checks-for-itensors-jl-pull-request?show=2298#a2298
<p>Hi Sujay, thanks for the question.</p>
<p>(1) a broken test is one that is known to fail, and is marked as broken meaning "don't mark the whole test run as failing just because this test does, and we should fix this test later". It could be either because the test is out of date or was written incorrectly. For more information you can read about @test_broken here: <a rel="nofollow" href="https://docs.julialang.org/en/v1/stdlib/Test/#Broken-Tests-1">https://docs.julialang.org/en/v1/stdlib/Test/#Broken-Tests-1</a></p>
<p>(2) I'm not sure why that particular test was failing. As you know, the tests get run automatically with each pull request on 3 different operating systems, and have recently been working there. So it's hard to comment on this failure without detailed steps to reproduce. If you think it's a bug in the tests or the library, could you please file an issue with steps to reproduce? We'd definitely like to fix this if it's a bug.</p>
<p>Please let me know if I didn't answer one of your questions -</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/2290/questions-about-checks-for-itensors-jl-pull-request?show=2298#a2298Mon, 29 Jun 2020 14:23:49 +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 +0000Answered: Bug in MPOs with products of operators? (Julia version)
http://itensor.org/support/2258/bug-in-mpos-with-products-of-operators-julia-version?show=2287#a2287
<p>This bug should be fixed now in version 0.1.14 of Julia ITensor (ITensors.jl). Please let me know if it isn't! Thanks for pointing out this issue.</p>
<p>Best,<br>
Miles</p>
http://itensor.org/support/2258/bug-in-mpos-with-products-of-operators-julia-version?show=2287#a2287Sun, 28 Jun 2020 01:25:33 +0000Answered: Symbol lookup error
http://itensor.org/support/2279/symbol-lookup-error?show=2280#a2280
<p>Hi, thanks for the question but I'm also not sure why you'd be getting this error if you:<br>
1. fully did a make clean and make, and it built successfully<br>
2. used the provided Makefile to build your code</p>
<p>Could you please post some more output of your build, the compiler command and output, and the error message?</p>
<p>Did you happen to move the ITensor source folder to a different location on your computer from a previous location?</p>
<p>Best,<br>
Miles</p>
http://itensor.org/support/2279/symbol-lookup-error?show=2280#a2280Fri, 26 Jun 2020 16:21:27 +0000Answered: CPS collapse of finite-T in the tutorial (Minimally entangled typical thermal state algorithms)
http://itensor.org/support/2276/collapse-tutorial-minimally-entangled-typical-algorithms?show=2277#a2277
<p>Hi, thanks for the question. The answer is that the normalization is equal to the square root of the probability. So if you compute the norm from the formula (square root of probability) or just by computing the norm of the new “A” tensor of the MPS, you will get the same number. The real purpose of dividing by the square root of the probability is to normalize the state, so writing the code in a more general way that also normalizes the state is also ok to give the right answer.</p>
<p>Please let me know if that answers your question -</p>
<p>Best,<br>
Miles</p>
http://itensor.org/support/2276/collapse-tutorial-minimally-entangled-typical-algorithms?show=2277#a2277Fri, 26 Jun 2020 12:33:39 +0000Answered: Low 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?show=2275#a2275
<p>Hi, Miles!</p>
<p>Thanks for answer so soon and sorry for said a lot of strange things, may be I can explain better what I have seen in my simulation.</p>
<p>I'm trying to reproduce all results of the following paper of S. R. Manmana et. al "<a rel="nofollow" href="https://journals.aps.org/prb/abstract/10.1103/PhysRevB.70.155115">https://journals.aps.org/prb/abstract/10.1103/PhysRevB.70.155115</a>" about the Ionic Hubbard Model. In particular, I want to calculate the finite-size scaling behavior of spin gap for this model. </p>
<p>I have perfomed several calculations in the region with delta=20.0 and U=21.0 to U=22.0 for a lattice length from L=64 up to L=512. In all most values of this parameter region I have a good finite-size scaling of the gap as it is reported by Manmana, but fot values near to U=21.0 or less than this value, the spin gap suddenly jump for lattices with L>128. This is a figure of this behaviour.</p>
<p><img src="http://imgfz.com/i/MCZF0OP.png" alt="finite-size scaling of the spin gap L=64, 80, 96 , 112, 128, 144, 160"></p>
<p>I did check the information of DMRG steps by locking for some problem and I found out that the number of states were very small (from 64 to 100 states) with respect to the same calculation for a higher value of U (U=21.45 where at least 400 states are required for the same lattice length). Due to this problem I increase the number of states at least to 800 states, the maximum value considerer by Manmana, but I obtained the same result of the energy.</p>
<p>I'm trying to understand what is happening in this system and the only thing that could explain this behaviour is may be an accumulation of floating point roundoff error as you well interpreted from my first question. The strangest thing is that I have observed this behavior not only using tensor networks, but also in other Fortran code without mps.</p>
<p>This are the DMRG parameters for this simulations</p>
<pre><code> maxdim mindim cutoff niter noise
100 1 1E-5 6 1E-5
200 1 1E-6 6 1E-5
256 1 1E-7 6 1E-8
400 1 1E-8 5 1E-9
400 1 1E-8 5 1E-10
800 1 1E-9 5 1E-11
800 1 1E-9 4 1E-11
800 1 1E-9 4 1E-12
</code></pre>
http://itensor.org/support/2249/chains-metastable-states-possible-arbitrary-precision-itensor?show=2275#a2275Thu, 25 Jun 2020 01:18:06 +0000Answered: How to project into zero-momentum sector? (Julia)
http://itensor.org/support/2266/how-to-project-into-zero-momentum-sector-julia?show=2268#a2268
<p>I agree with Matt's comment than an infinite-size algorithm is what is called for here. It's usually a far superior way to get the main advantages of OBC, such as translation invariance and absence of boundary effects, while working much more naturally for tensor networks.</p>
<p>But regarding the specific question of whether one can directly "target" or go after states of a certain momentum I think it's still a bit of an active area of research. Of course one can just get the ground state and check what momentum it has. Also there are the excited-state methods (which are similar to the single-mode approximation) by Verstraete, Haegeman, et al. which are partly reviewed here: <a rel="nofollow" href="https://arxiv.org/abs/1810.07006.">https://arxiv.org/abs/1810.07006.</a> These might be what you are looking for.</p>
<p>Miles</p>
http://itensor.org/support/2266/how-to-project-into-zero-momentum-sector-julia?show=2268#a2268Wed, 24 Jun 2020 16:08:24 +0000Answered: Write MPS to file in Julia
http://itensor.org/support/2234/write-mps-to-file-in-julia?show=2247#a2247
<p>Hi Goncalo,<br>
An update: I recently added this capability to the Julia version of ITensor, beginning in version 0.1.12 which is the latest tagged version. Please now try doing "update ITensors" in the Julia package manager then re-running your code above and it should work. If it doesn't, please comment below to let me know.</p>
<p>Thanks,<br>
Miles</p>
http://itensor.org/support/2234/write-mps-to-file-in-julia?show=2247#a2247Sun, 21 Jun 2020 23:41:01 +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 +0000Answered: How 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?show=2244#a2244
<p>Hi, to do this you can use the excited state DMRG feature of ITensor. We have put “code formulas” (example codes) on the website at the following links, for each version of ITensor:</p>
<p>Version 2:<br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv2&page=formulas/excited_dmrg">http://itensor.org/docs.cgi?vers=cppv2&page=formulas/excited_dmrg</a></p>
<p>Version 3:<br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?page=formulas/excited_dmrg&vers=cppv3">http://itensor.org/docs.cgi?page=formulas/excited_dmrg&vers=cppv3</a></p>
<p>Please take care when using this method to compute highly excited states (or really any excited states). It’s important to converge the ground state very well. Also use many sweeps when converging the excited states. For the size of the “Weight” parameter you have to experiment to see what works best for the system you are studying.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/2243/how-to-calculate-the-first-second-15-excited-state-in-tensor?show=2244#a2244Sat, 20 Jun 2020 13:26:19 +0000Answered: How 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?show=2232#a2232
<p>According to this page in the ITensor documentation (<a rel="nofollow" href="https://itensor.org/docs.cgi?vers=cppv3&page=upgrade2to3),">https://itensor.org/docs.cgi?vers=cppv3&page=upgrade2to3),</a> physics-specific site sets (e.g. SpinHalf) carry QNs by default. You can see this point in the "Recommended, Optional Changes" section.</p>
<p>So all you need to do is put <code>{"ConserveQNs=",false}</code> when creating the sites object. In your case, you can do <code>auto sites = SpinHalf(N, {"ConserveQNs=",false});</code>.</p>
<p>As a side remark, I am only truly familiar with the Julia version of the ITensor code, and there they still have QNs as false by default, even for physics-specific site sets. I actually don't know whether this change will eventually be made in the Julia version of the code too.</p>
http://itensor.org/support/2230/create-transverse-field-ising-model-hamiltonian-with-autompo?show=2232#a2232Fri, 19 Jun 2020 08:38:39 +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 +0000Answered: randomMPS method can not be used with Zn symmetry (Julia)
http://itensor.org/support/2214/randommps-method-can-not-be-used-with-zn-symmetry-julia?show=2220#a2220
<p>Hi Runze,<br>
This issue should now be fixed as of version 0.1.10. So please do "update ITensors" in the package manager and try your first, randomMPS code again. Please let me know if it still doesn't work.</p>
<p>The issue I found was that a constructor which gets called when making QNs with modulus values other than 1 had a missing <code>return</code> keyword, which made it silently set the wrong QN value. So that was causing the error but now it's fixed.</p>
<p>Thanks again for bringing this to our attention -</p>
<p>Miles</p>
http://itensor.org/support/2214/randommps-method-can-not-be-used-with-zn-symmetry-julia?show=2220#a2220Wed, 17 Jun 2020 21:56:55 +0000Answered: How 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?show=2219#a2219
<p>Hi Sujay,<br>
The short answer to your question is that one can certainly write a 3-site (or even 4 or 5 site) DMRG algorithm and it can be a powerful way to handle cases that 2-site DMRG has difficulty reaching convergence for. One project I was involved in was greatly helped by switching to 3-site DMRG. It would be especially appropriate if your model has a certain unit cell size which is greater than 2 sites (though that's not to say that 2-site DMRG can't work well for larger unit cell sizes).</p>
<p>The main technical step one needs to do to implement 3-site DMRG is to implement the step of factoring the 3-site wavefunction "center" tensor back into 3 separate MPS tensors. Say one is currently sweeping to the right, and say that after optimization of this tensor, it has 3 site indices: s1, s2, s3, and two bond indices bl and br. Then you first do an SVD to split the indices (bl,s1) from the rest. Then multiply the resulting S<em>V to get the remainder R. Also grab the index "u" connecting U to S. Now SVD R, splitting the indices (u,s2) from the rest. The result is that the U from the first SVD becomes the first MPS tensor, the U from the second SVD becomes the second MPS tensor, and the S</em>V from the second SVD becomes the third MPS tensor.</p>
<p>You just do the steps in reverse, essentially, when sweeping back to the left. The key is to make sure that the orthogonality center is pushed rightward when sweeping right and leftward when sweeping left. It helps a lot to draw diagrams of these things.</p>
<p>The two other considerations needed are:<br>
1. making sure the outer loop using the iterator "sweepnext" is called as <code>sweepnext(N,3)</code> to set the number of center sites to 3<br>
2. modifying the ProjMPO class to stop the building of the Hamiltonian environment tensors earlier so that they are compatible with the 3-site wavefunction tensor</p>
<p>Hope that helps - it would be a bit of work so do consider carefully whether you need it </p>
<p>Miles</p>
http://itensor.org/support/2212/modify-dmrg-optimize-over-different-number-sites-time-julia?show=2219#a2219Wed, 17 Jun 2020 21:01:46 +0000Answered: Source 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?show=2217#a2217
<p>Hi Sujay,<br>
The @timeit_debug macro is provided by the library TimerOutputs.jl:<br>
<a rel="nofollow" href="https://github.com/KristofferC/TimerOutputs.jl">https://github.com/KristofferC/TimerOutputs.jl</a></p>
<p>You can see on the README page there that @timer_debug is discussed.</p>
<p>It's not necessary for the functioning of our ITensor DMRG code, but we just use it sometimes to check whether the code is running as quickly as we'd like to see. So if you're making your own code which doesn't have <code>using TimerOutputs</code> at the top, you can just remove the @timeit_debug macro and the associated begin..end block keywords.</p>
<p>The way it gets brought into ITensors.jl is that it's one of ITensors.jl's dependencies (see the Project.toml file at the top of the ITensors.jl source code if you'd like a list of all dependencies). But that doesn't mean that you will have TimerOutputs definitions available in your own code; you have to do <code>using TimerOutputs</code> for that.</p>
<p>Hope that helps & let me know if any of that doesn't seem correct because I'm still on a learning curve with Julia too -</p>
<p>Miles</p>
http://itensor.org/support/2216/source-purpose-%40timeit_debug-macro-dmrg-julia-version-code?show=2217#a2217Wed, 17 Jun 2020 18:37:06 +0000Answered: ITensor can calculate imaginary time correlation function?
http://itensor.org/support/2200/itensor-can-calculate-imaginary-time-correlation-function?show=2210#a2210
<p>(Marking this question as answered: please see the discussion above.)</p>
http://itensor.org/support/2200/itensor-can-calculate-imaginary-time-correlation-function?show=2210#a2210Sat, 13 Jun 2020 18:35:07 +0000Answered: Momentum-resolved entanglement spectrum
http://itensor.org/support/2197/momentum-resolved-entanglement-spectrum?show=2199#a2199
<p>Hi RS,<br>
What I think would be the best way to do what you want in ITensor is to change the local basis used for your DMRG calculation. So instead of computing your ground state in a real-space basis as you are doing now, and then desiring to transform your wavefunction as a secondary step into a y-momentum basis, I think it would be both much easier and more efficient to work in a y-momentum (and of course x-real-space) basis from the very beginning, at the level of defining your site indices and Hamiltonian.</p>
<p>So the broad steps to do this would be as follows:<br>
1.a. define a new site type that carries y-momentum quantum numbers, such as QN("Ky",0), QN("Ky",1), QN("Ky",-1), QN("Ky",2). Because the values of quantum numbers in ITensor are required to be integers, these integers are to be understood as QN("Ky",n) where the true momentum value is k<em>y=(2<em>pi</em>n)/N</em>y. So maybe a better name for these QN's would actually be QN("ny",0), QN("ny",1), etc. The name is really up to you.</p>
<p>1.b. to actually define such a new site type in the C++ version of ITensor unfortunately requires a bit of work and expertise with how to define a C++ class and its constructor and other similar things. If you are comfortable with this, and understand the general pattern of the existing site types included in ITensor such as in itensor/mps/sites/spinhalf.h, itensor/mps/sites/electron.h, etc. then it should not be too hard to make a new site type (call it KySpinHalf, say) and use it in your code instead of the SpinHalf sites. A key step here is that you'll have to take advantage of the fact that the named Args passed to the site type constructors gets a value "SiteNumber" passed to it, and you'll have to also pass "Ny" to it, so that these can be combined to work out what QN("ny",n) value that site should have based on where it's located around the cylinder. I can help you with this as I know this is probably the trickiest and least clear part.</p>
<ol>
<li><p>the next step is to transform your Hamiltonian to a hybrid y-momentum / x-real-space basis. This is just a standard excersise in changing variables to spin operators which are plane-wave linear combinations of real-space spin operators by substituting them into your real-space Hamiltonian. I'm not saying "standard" to imply it's obvious or easy: just that this part is a thing which is purely mathematical and outside of ITensor.</p></li>
<li><p>You can use the newly created site types along with AutoMPO to input your momentum-space Hamiltonian and get an MPO for it. It might be a slightly bigger MPO than a purely real-space one because now the spin interactions will be non-local in the y-direction around each ring or rung of the cylinder. But the extra savings coming from the block-sparsity of the momentum-conserving ITensors should easily make up for this extra cost.</p></li>
<li><p>Finally, and we may have to discuss the particulars of this more, you can SVD your ground state MPS after it's optimized to get the entanglement spectrum, except now the bond indices of your MPS will automatically be labeled by the QN("ny",n) quantum numbers. So by analyzing the spectrum along with these quantum number labels, you can work out which sector the different singular values correspond to. Basically this could be as easy as SVDing part of your MPS and just printing out the "S" tensor of singular values. But we can explore this in some follow-up questions if it turns out to be more complicated in practice for some reason.</p></li>
</ol>
<p>Hope that helps you to get started. One of the postdocs at Flatiron CCQ already implemented many of the steps above and it worked well, so if you email me I could put you in touch with him to see if he's willing to share some tips or perhaps even some code examples. We should ultimately put this into the library or at least the Code Formulas page of the website.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/2197/momentum-resolved-entanglement-spectrum?show=2199#a2199Thu, 11 Jun 2020 19:54:26 +0000Answered: Implementing local gauge symmetries
http://itensor.org/support/2140/implementing-local-gauge-symmetries?show=2198#a2198
<p>Here is an idea that I had (written using the Julia code). I still highly doubt it will work, for some reasons I will explain, but I have some hope that something like it may work. In particular, I think understanding why it doesn't work would still be helpful. Anyway, here is the code:</p>
<pre><code>ferm_full = QN("Sz",-1) => 1
ferm_vac = QN("Sz",0) => 1
antiferm_full = QN("Sz",+1) => 1
antiferm_vac = QN("Sz",0) => 1
even_link_p1 = QN("Sz",+2) => 1 # p1 = "positive 1"
even_link_0 = QN("Sz",0) => 1
even_link_n1 = QN("Sz",-2) => 1 # n1 = "negative 1"
odd_link_p1 = QN("Sz",-2) => 1
odd_link_0 = QN("Sz",0) => 1
odd_link_n1 = QN("Sz",+2) => 1
function Kogut_Susskind_sites(num_spatial_sites)
sites = Index[]
for i = 1:num_spatial_sites
push!(sites, Index(ferm_full,ferm_vac; tags="Site,S=1/2,n=$(4*i-3)"))
push!(sites, Index(odd_link_p1,odd_link_0,odd_link_n1; tags="Site,S=1,n=$(4*i-2)"))
push!(sites, Index(antiferm_full,antiferm_vac; tags="Site,S=1/2,n=$(4*i-1)"))
push!(sites, Index(even_link_p1,even_link_0,even_link_n1; tags="Site,S=1,n=$(4*i)"))
end
return sites
end
function Schwinger_Hamiltonian(sites, num_spatial_sites, x, μ)
N = num_spatial_sites * 2
ampo_H = AutoMPO()
for j=0:N-1
add!(ampo_H, 1, "Sz2", 2*j+2)
add!(ampo_H, (μ/2)*(-1)^j * 2, "Sz", 2*j+1)
if j != N-1
add!(ampo_H, x * 2*2/sqrt(2), "S+", 2*j+1, "S-", 2*j+2, "S-", 2*j+3)
add!(ampo_H, x * 2*2/sqrt(2), "S+", 2*j+3, "S+", 2*j+2, "S-", 2*j+1)
end
end
add!(ampo_H, x * 2*2/sqrt(2), "S+", 2*N-1, "S-", 2*N, "S-", 1)
add!(ampo_H, x * 2*2/sqrt(2), "S+", 1, "S+", 2*N, "S-", 2*N-1)
H = MPO(ampo_H, sites)
return H
end
function Schwinger_DMRG(num_spatial_sites)
sites = Kogut_Susskind_sites(num_spatial_sites)
H = Schwinger_Hamiltonian(sites, num_spatial_sites, x, μ)
sweeps = Sweeps(10)
maxdim!(sweeps, 10,20,100,100,200)
cutoff!(sweeps, 1E-10)
# construct initial state as completely empty
init_state = ["Up" for n = 1:4*num_spatial_sites] # just to initialize
for n = 1:4*num_spatial_sites
if n % 4 == 1
init_state[n] = "Dn" # empty fermion sites
elseif n % 4 == 3
init_state[n] = "Up" # empty antifermion states
else # n % 4 == 2 || n % 4 == 0
init_state[n] = "Up" # flux = 0 at all links
end
end
psi0 = randomMPS(sites, init_state, 100)
energy, psi = dmrg(H, psi0, sweeps)
println("Ground state energy = $energy")
return energy
end
</code></pre>
<p>In case you're wondering why I haven't already tested it, basically it's because I ran into some other more fundamental issue with the randomMPS function in Julia. This issue is mentioned on the Support Q&A (<a rel="nofollow" href="http://itensor.org/support/2186/questions-random-initial-conservation-randommps-linkdim)">http://itensor.org/support/2186/questions-random-initial-conservation-randommps-linkdim)</a> and on the GitHub page (<a rel="nofollow" href="https://github.com/ITensor/ITensors.jl/issues/424),">https://github.com/ITensor/ITensors.jl/issues/424),</a> so I think it will be fixed soon.</p>
<p>The idea is that, by assigning these particular quantum numbers, we have now made it so that each term in the Hamiltonian indeed has zero QN flux. So I think this means that, when the DMRG process varies the state, it will only end up doing things that respect the gauge symmetry? But maybe I'm misunderstanding.</p>
<p>The first problem I see with this is that I have still only defined one QN, so I'm pretty sure this QN conservation is not actually capturing the symmetry at each site. I believe there would be ways for DMRG to change the state in a way that respects this QN but doesn't respect the local constraints, in some way that I don't really understand. If this is the case, then I wonder whether setting up this type of quantum number for every site could be the way to go.</p>
<p>The second problem I see with this is that it is unclear to me how DMRG will work properly. Thanks to the gauge symmetries, the smallest "legal" operation is creating a fermion-antifermion pair on adjacent sites and changing the flux between the two particles by 1 (I'm assuming the fermion is negative, so +1 if the antifermion comes first and -1 if the fermion comes first), or the opposite (destroying a fermion-antifermion pair and making the corresponding flux change for the site between them). This means that one needs to change three adjacent sites (two particle sites and the link between them) to make a legal change to the state, and DMRG only isolates two sites at a time when performing the local optimization. This seems to me like something that would lead to trouble.</p>
<p>Anyway, I'm sorry to disappoint if you were expecting a definitive answer, but I thought this was extensive enough to put as an answer to at least get some thoughts going. I would love to hear people's thoughts on this.</p>
http://itensor.org/support/2140/implementing-local-gauge-symmetries?show=2198#a2198Thu, 11 Jun 2020 18:40:23 +0000Answered: Breaking the Sz symmetry using an ITensor
http://itensor.org/support/2192/breaking-the-sz-symmetry-using-an-itensor?show=2193#a2193
<p>Hi Thanos,<br>
Thanks for the question. If I understand correctly, you are now trying to make ITensors which do not have a well-defined total Sz quantum number. If that's correct, it's a perfectly fine thing to do but isn't allowed by our system while the Index objects you're using (s1,s2,s3,s4 in your code) carry Sz quantum numbers.</p>
<p>So the solution I'd propose is making your "sites" array (site set) not have quantum numbers. The way to do that is to construct it as </p>
<pre><code>auto sites = SpinHalf(N,{"ConserveQNs=",false});
</code></pre>
<p>for the SpinHalf site set and similar for other pre-defined site sets.</p>
<p>Let me know if you're looking for a different solution though.</p>
<p>Miles</p>
http://itensor.org/support/2192/breaking-the-sz-symmetry-using-an-itensor?show=2193#a2193Wed, 10 Jun 2020 16:49:21 +0000Answered: Questions about random initial MPS under QN conservation ("randomMPS(sites, state, linkdim)" in Julia)
http://itensor.org/support/2186/questions-random-initial-conservation-randommps-linkdim?show=2188#a2188
<p>Hi Sujay,<br>
Thanks for the detailed feedback: this is really helpful to make the code better. Some of the issues you are running into are typical of newer code, where we have not ironed out every bug or hardened it against every possible input. Let me address each of these as far as I can without running tests of my own:</p>
<p>(1) the reason for the energy jumping around is probably that your Hamiltonian MPO is not Hermitian. You only put S+ S- terms and no S- S+ terms. I’ve seen this kind of behavior before for non-Hermitian inputs to DMRG. Ideally we’d have a check that throws an error if the Hamiltonian is non-Hermitian, as we do not support this case.</p>
<p>(2) An input of linkdim=0 was not intended to be allowed, and is not a meaningful input. I’ll update the code to throw an error if linkdim < 1. I’m not sure what linkdim of zero would mean.</p>
<p>(3) The error about “MPS center bond dim” is something I need to work on. What the randomMPS algorithm currently does is act on the input product state with a random quantum circuit. It keeps applying layers of the circuit until the bond dimension grows to linkdim. So apparently there’s a case where this isn’t happening properly and I’ll look into it.</p>
<p>(4) For this code indeed linkdim = 1 just returns the product state you input. For the QN conserving case it’s hard to think of anything else it could do very easily. If returned state was a superposition of other product states of the same total QN then the bond dimension would have to be greater than 1. On the other hand if it was a totally random product state the total QN guarantee wouldn’t be satisfied, which would be a failure of the purpose of this function. So this behavior is the only consistent one. Really this function becomes more useful for linkdim > 1 and is not particularly useful for linkdim = 1, though I’m not sure we should have that case throw an error since the behavior is meaningful and well defined. I’m open to any suggestions you may have though.</p>
<p>Thanks,<br>
Miles</p>
http://itensor.org/support/2186/questions-random-initial-conservation-randommps-linkdim?show=2188#a2188Wed, 10 Jun 2020 01:50:02 +0000Answered: DMRG does nothing in certain cases if initial state chosen deterministically? (Julia)
http://itensor.org/support/2181/nothing-certain-initial-state-chosen-deterministically-julia?show=2183#a2183
<p>Hi Sujay,<br>
Thanks for the question. This is a good example of the DMRG "sticking problem" which is a long-standing issue with how the DMRG algorithm works, barring additional convergence tricks. Many people new to DMRG can find it surprising, so it's a question we get often and I mention it in the Guidelines for Asking Questions: <a rel="nofollow" href="http://itensor.org/support/2003/guidelines-for-asking-questions">http://itensor.org/support/2003/guidelines-for-asking-questions</a></p>
<p>First of all, as a formal statement DMRG is not rigorously guaranteed to converge and return the true ground state of the system. So care must be taken when working with challenging or unusual Hamiltonians, or with systems with a high degree of symmetry, to check that DMRG is working correctly. Examples of good checks include comparing to exact limits or comparing to exact diagonalization of small systems.</p>
<p>At a more intuitive level, it's not a bad cartoon of DMRG to think of it as a fancy version of the "power method" for finding dominant eigenvectors of matrices. So just like in the power method, if the initial guess vector is orthogonal to the eigenvector one seeks, then convergence will not happen. You can think of DMRG as taking the initial vector and enhacing the part that overlaps with the ground state while suppressing all of the other components. But if there's no overlap with the ground state at all, this can't be done.</p>
<p>So that's why random MPS are actually in some sense the best possible starting state: they have a non-zero overlap with the ground state with probability approaching 1.0 in the limit of the random MPS having a large bond dimension. In fact, one option we provide in the randomMPS function is the ability to make randomMPS of different bond dimensions by doing randomMPS(sites,chi) where chi is the requested bond dimension. If you choose it larger, you will generally see faster convergence of DMRG in terms of number of sweeps.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/2181/nothing-certain-initial-state-chosen-deterministically-julia?show=2183#a2183Tue, 09 Jun 2020 15:57:41 +0000Answered: Compress an MPS without an operation.
http://itensor.org/support/2178/compress-an-mps-without-an-operation?show=2179#a2179
<p>Hi Nick,<br>
The operation I believe you are looking for is <code>.orthogonalize()</code>. For an MPS <code>psi</code> you can call <code>psi.orthogonalize({"MaxDim=",maxdim,"Cutoff=",cutoff});</code> to compress its bonds using the truncation parameters maxdim and cutoff. Afterward it will be in right-orthogonal form with site 1 as the orthogonality center. This operation doesn't rely on any prior assumption about whether <code>psi</code> is in a well-defined gauge or canonical form or not.</p>
<p>Here's a documentation page that mentions it:<br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv3&page=classes/mps">http://itensor.org/docs.cgi?vers=cppv3&page=classes/mps</a></p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/2178/compress-an-mps-without-an-operation?show=2179#a2179Tue, 09 Jun 2020 01:34:51 +0000Answered: A particular initial guess for DMRG calculation
http://itensor.org/support/2166/a-particular-initial-guess-for-dmrg-calculation?show=2175#a2175
<p>Hi Javad,<br>
Thanks for the discussion above. I thought of a solution that could work well for what you want to do. I'll just give an outline, though happy to discuss some technical aspects of implementing it in ITensor (C++ v3).</p>
<p>First of all, prepare an MPS which is a product of singlets on sites (1,2), (3,4), (5,6), etc. To do so, you can use code similar to the following:<br>
<a rel="nofollow" href="https://github.com/ITensor/ITensor/blob/a1254d56a180d5e0b992c9b7d9a463bb06a5333d/tutorial/finiteT/ancilla.cc#L58">https://github.com/ITensor/ITensor/blob/a1254d56a180d5e0b992c9b7d9a463bb06a5333d/tutorial/finiteT/ancilla.cc#L58</a><br>
which is from the "tutorial/finiteT/ancilla.cc" code included with ITensor.</p>
<p>Then use "swap moves" to exchange MPS sites to obtain the pattern of singlets that you want. For example, if you merge the MPS tensors on sites 2 and 3:</p>
<pre><code>auto wf = psi(2)*psi(3);
</code></pre>
<p>then SVD these tensors back apart, but now grouping the 3rd physical index with the MPS bond index connecting MPS tensors 1 and 2:</p>
<pre><code>auto b1 = commonIndex(psi(1),psi(2));
auto [U,S,V] = svd(wf,{b1,sites(2)});
</code></pre>
<p>Finally, reassign U and (S*V) into the MPS to update it:</p>
<pre><code>psi.ref(2) = U;
psi.ref(3) = S*V;
</code></pre>
<p>Now the pattern of singlets will be (1,3),(2,4),(5,6),... and the bond dimensions of the MPS will be increased accordingly, and should now be: 2,4,2,1,2,1,... However note that the site indices will be out of order from the original ones you may want: they will be 1,3,2,4,5,... </p>
<p>Keep repeating the above steps to swap pairs of neighboring physical sites. It's ok if you ignore the MPS gauge (orthogonality) conditions as long as all of the SVD's you do are exact and don't truncate. </p>
<p>Finally, the site indices of the MPS will be very scrambled up compared to the original order. You can either fix this by doing code lik psi.ref(j).replaceInds({sites(n)},{sites(j)}); on each MPS tensor to put the physical index sites(j) back on MPS tensor j. Or you can just work with the new order of site indices if that's convenient to do. </p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/2166/a-particular-initial-guess-for-dmrg-calculation?show=2175#a2175Mon, 08 Jun 2020 18:36:54 +0000Answered: I think diagHermitian may not be working properly.
http://itensor.org/support/2160/i-think-diaghermitian-may-not-be-working-properly?show=2163#a2163
<p>Simple mistake, I used S+ and S- instead of Sx and Sy, and so my Hamiltonian was in fact not Hermitian. Fixing this solved the issue.</p>
http://itensor.org/support/2160/i-think-diaghermitian-may-not-be-working-properly?show=2163#a2163Wed, 03 Jun 2020 18:05:31 +0000Answered: Various questions about QN conservation in Julia
http://itensor.org/support/2156/various-questions-about-qn-conservation-in-julia?show=2157#a2157
<p>Hi Sujay,<br>
Thanks for the good & detailed questions. These touch on things we want everyone to understand when working in a more hands-on way with the QN conserving ITensor system. We're trying to find the best way to document and introduce them, and one way is just by building a knowledge base on this forum. As you probably know, the draft of the ITensor Book on the website also introduces some QN ITensor concepts: <a rel="nofollow" href="http://itensor.org/docs.cgi?vers=julia&page=book">http://itensor.org/docs.cgi?vers=julia&page=book</a> . And we will soon publish an ITensor paper that provides many details.</p>
<p>To answer your questions:</p>
<p>(1) yes we require the quantum numbers to be integers for reasons of efficiency and correctness. E.g. we wouldn't want to store them as floating point because that would introduce all sorts of complications. But your question (which others have asked before) does remind me that Julia has facilities for exact computations with rational numbers, which we might consider expanding QN's to use in the future. For now please just make an integer correspondence between the quantum numbers as used on paper and in ITensor (e.g. we have the convention of working in units of 1/2 for spin quantum numbers, so 1/2 becomes 1, 1 becomes 2, etc.).</p>
<p>(2) The notation <code>A => B</code> in Julia creates a <code>Pair(A,B)</code> object, which is just a struct holding the values A and B. It can be an unfamiliar notation coming from other languages, and it was for me too. So it is nothing specific to ITensor but just a convenient way to group two values together that we've adopted for this Index constructor. Each pair denotes a subspace of the Index, meaning that the entire index labels the basis of a vector space (of dimension 3 here) and each subspace occurs sequentially giving the space a direct-sum structure. The second number of each pair is the dimension of that subspace. So the 1's are saying that each subspace is of dimension 1.</p>
<p>(3) I'm not sure exactly in what sense you're asking about having an arbitrary number of QNs at once, but I can comment on a few relevant things here. One is that an Index can have as many QN subspaces as you want. So in code like:</p>
<pre><code>i = Index(QN(0)=>1, QN(1)=>2, Q(2)=4, ... )
</code></pre>
<p>the list of QN=>Int pairs can go on as long as you want, up to the memory limits of the machine. On the other hand, <em>within</em> a QN object itself, you can only have up to 4 different types of quantum numbers stored. So like <code>QN(("A",1),("B",0),("C",-1),("D",3))</code> would be reaching the limit of 4 different QN values. This is for reasons of efficiency as it greatly reduces allocations while on the other hand we've so far heard of few cases where more than 4 QN names were needed at once. But if you definitely do need more, we can work with you to lift this restriction.</p>
<p>I don't know much about the Schwinger model or its symmetries. Could you provide more information about how you're thinking of implementing it and the Hamiltonian used? Our ITensor QN system is currently only designed to handle the case of global, Abelian symmetries of a Hamiltonian. So it does not handle non-Abelian symmetries such as global SU(2) for example. But local symmetries such as in lattice gauge theories are an interesting case I think we've just not thought about. So it's not obvious to me whether our existing system can handle that case, or whether it could with some small changes, or even what is the right approach to such symmetries in tensor networks more broadly. This review could provide some information about the status of this topic: <a rel="nofollow" href="https://arxiv.org/abs/1810.12838">https://arxiv.org/abs/1810.12838</a></p>
<p>(4) Regarding the construction of QN-conserving MPOs, some of the precise details can get rather involved and at the same time many are just conventions and could vary from one implementation to another. The conventions we use in ITensor code are that for a QN-conserving MPO with total flux zero (such as the Hamiltonian, which by definition has to be total flux zero since it preserves the quantum numbers), all of the MPO tensors are themselves <em>individually</em> flux zero. This isn't formally necessary, but is a very natural and convenient convention. So when constructing each tensor, flux non-zero operators such as S+ or S- are "balanced" by bond or link indices of the MPO having subspaces which cancel out the flux of the operator to keep things net flux zero. </p>
<p>I gave a pretty detailed answer about some of these conventions in this forum question:<br>
<a rel="nofollow" href="http://itensor.org/support/2083/properly-handle-quantum-number-for-system-spin-half-moments?show=2083#q2083">http://itensor.org/support/2083/properly-handle-quantum-number-for-system-spin-half-moments?show=2083#q2083</a></p>
<p>Please take a look at that, even though the question is about a C++ code file that makes the Heisenberg MPO. Both my answer there as well as the C++ example itself could be helpful. If you'd like to discuss how some of that C++ code would be adapted to the Julia version we could discuss that in the future.</p>
<p>Ok hope all of that helps you to make some more progress - I understand it's a lot to digest.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/2156/various-questions-about-qn-conservation-in-julia?show=2157#a2157Tue, 02 Jun 2020 22:00:42 +0000Answered: Using Sx, Sy in SpinOne
http://itensor.org/support/2152/using-sx-sy-in-spinone?show=2154#a2154
<p>Adding on a bit to what JR said, basically, if you want to conserve total Sz, then you need to avoid the use of Sx and Sy operators directly in your code and express everything that requires Sx and Sy in terms of S+ and S-.</p>
<p>I agree that there are situations in which this can feel awkward; I remember asking this same question a while back on the GitHub page for the Julia version of this code.</p>
<p>The reasoning behind this design choice is that S+ and S- have a definite QN flux: an S+/S- operator on a site always increases/decreases the total Sz by 1. In contrast, Sx and Sy don't have this property: an Sx/Sy operator on a site has a component that increase total Sz by 1 and a component that decreases total Sz by 1.</p>
http://itensor.org/support/2152/using-sx-sy-in-spinone?show=2154#a2154Tue, 02 Jun 2020 05:01:08 +0000Answered: how to compute the ground state energy in a given symmetry sector?
http://itensor.org/support/2147/how-compute-the-ground-state-energy-in-given-symmetry-sector?show=2150#a2150
<p>Hi Yantao,<br>
Thanks for the question. This is a good question because it is one of the more subtle aspects of ITensor, though it is also very simple to use in the end.</p>
<p>The answer to your questions is that the way quantum-number-conserving tensors work in the ITensor library (both the C++ and Julia versions) is that they always change whichever quantum numbers you are conserving by a <em>definite amount</em>. And for the case of acting with the Hamiltonian or a "gate" which is an exponential of a Hamiltonian term, the change to the total quantum number is zero, so no change at all.</p>
<p>Practically what this means is the following:<br>
1. if you initialize an ITensor DMRG calculation with an MPS made of quantum-number conserving ITensors, then it is guaranteed that the resulting, optimized MPS will have the same total quantum numbers as the initial state<br>
2. if you do a calculation such as TEBD, then as long as your gates conserve the quantum numbers (are zero-flux QNITensors) then the total quantum numbers of your MPS will not change</p>
<p>So if you just prepare an initial state in the symmetry sector you want, the calculations will stay in that symmetry sector. You can check the total quantum number at any point during or after a calculation by calling <code>totalQN(psi)</code> (or <code>totalqn(psi)</code> in Julia) on an MPS <code>psi</code>.</p>
<p>Of course please comment below if you have more questions about this -</p>
<p>Miles</p>
http://itensor.org/support/2147/how-compute-the-ground-state-energy-in-given-symmetry-sector?show=2150#a2150Mon, 01 Jun 2020 14:51:18 +0000