ITensor Support Q&A - Recent questions and answers
http://itensor.org/support/qa
Powered by Question2AnswerAnswered: The tensors calculated by idmrg do not obey the right orthogonality condition.
http://itensor.org/support/1242/tensors-calculated-idmrg-obey-right-orthogonality-condition?show=1605#a1605
<p>Hi, sorry for the very slow reply. I think the issue may be where you write</p>
<pre><code>psi.A(ni-1)
</code></pre>
<p>The .A method of an MPS is 1-indexed. On the other hand, it does allow you to input A(0), but this retrieves the "center" tensor which has no site index, and is the singular values resulting from a Schmidt decomposition of the infinite system done between two unit cells. So it should not obey the right-orthogonal gauge. I understand this is not well documented. So for version 3 we are moving the iDMRG code to a separate "code" project and planning to replace it with a better implementation that is also better documented.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1242/tensors-calculated-idmrg-obey-right-orthogonality-condition?show=1605#a1605Wed, 17 Jul 2019 03:55:20 +0000Answered: svd compiling error with itensor v3
http://itensor.org/support/1602/svd-compiling-error-with-itensor-v3?show=1603#a1603
<p>Hi, thanks for reporting this issue. However, I was not able to reproduce it unfortunately. Could you please post some minimal code that you were trying to compile that led to getting this message? (So like the contents of myappname.cc?) Thanks!</p>
<p>Miles</p>
http://itensor.org/support/1602/svd-compiling-error-with-itensor-v3?show=1603#a1603Wed, 17 Jul 2019 03:37:54 +0000Answered: whether itensor can realize cavity induced model?
http://itensor.org/support/1599/whether-itensor-can-realize-cavity-induced-model?show=1600#a1600
<p>Hi Weijie,<br>
Yes, DMRG and ITensor can be used to study a Hamiltonian of this type (and any Hamiltonian which is a sum of local terms on a lattice). </p>
<p>But special care has to be taken with bosons, as you know, since one has to make their Hilbert space finite in some way. So you could use the Boson site set in ITensor and adjust the MaxOcc parameter to make sure your results are converged with the maximum boson occupancy per site. </p>
<p>Your other question about Hubbard-Holstein might be relevant for others reading this question, so I'm linking it here: <a rel="nofollow" href="http://itensor.org/support/1502/how-to-realize-hubbard-holstein-model?show=1502#q1502">http://itensor.org/support/1502/how-to-realize-hubbard-holstein-model?show=1502#q1502</a></p>
http://itensor.org/support/1599/whether-itensor-can-realize-cavity-induced-model?show=1600#a1600Tue, 16 Jul 2019 15:06:02 +0000Answered: Get partial tensor
http://itensor.org/support/1592/get-partial-tensor?show=1596#a1596
<p>Hi Aditya,<br>
Good to meet you in person and discuss, but I'll also post the answer here.</p>
<p>To fix, clamp, or set an index to a particular value, a good solution is to contract the tensor with another tensor produced by the "setElt" function. (See setElt on this page: <a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv3&page=classes/itensor).">http://itensor.org/docs.cgi?vers=cppv3&page=classes/itensor).</a> Calling setElt(i=n) makes an ITensor which has the index "i" and has a component 1.0 in the nth entry, and zero otherwise.</p>
<p>Then you can multiply it by your tensor T like: T *= setElt(i=n).</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1592/get-partial-tensor?show=1596#a1596Mon, 15 Jul 2019 14:37:46 +0000Answered: Write a CMatrix type to file.
http://itensor.org/support/1588/write-a-cmatrix-type-to-file?show=1590#a1590
<p>Hi Nick,<br>
This was just something that was missing; I didn't define reading and writing of the "range" type that matrices use to store their column and row size. I just defined that and pushed the change to Github. So if you do "git pull" and recompile ITensor you should now be able to use writeToFile with CMatrix.</p>
<p>Thanks for the bug report!</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1588/write-a-cmatrix-type-to-file?show=1590#a1590Wed, 10 Jul 2019 13:58:43 +0000Answered: Can I use ITensor for CTMRG?
http://itensor.org/support/1586/can-i-use-itensor-for-ctmrg?show=1589#a1589
<p>Hi Tatsuo,<br>
Yes, you can definitely use ITensor to perform CTMRG calculations. However, we do not have a pre-written CTMRG code that we provide, so you would have to write it yourself. </p>
<p>As you know, the key steps of CTMRG are tensor contractions and singular value decompositions of certain tensors. ITensor lets you do both of these operations very conveniently.</p>
<p>Please let me know if you do begin writing it and need help with how to perform a certain step.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1586/can-i-use-itensor-for-ctmrg?show=1589#a1589Wed, 10 Jul 2019 13:52:17 +0000Answered: Seg fault in sum
http://itensor.org/support/1582/seg-fault-in-sum?show=1587#a1587
<p>I solved this issue by adding</p>
<pre><code> V[0].position(c);
WP[0].position(c);
WP[0].replaceSiteInds(siteInds(V[0]));
</code></pre>
<p>To make sure the positions and the indices matched before adding. For some reason the sum function that takes a vector of MPS' does not work, but at least this does.</p>
http://itensor.org/support/1582/seg-fault-in-sum?show=1587#a1587Wed, 10 Jul 2019 06:29:01 +0000Error when calculating excited states (with conserved quantities)
http://itensor.org/support/1581/error-when-calculating-excited-states-conserved-quantities
<p>Hi!</p>
<p>The issue I have is similar to one found <a rel="nofollow" href="http://itensor.org/support/441/segmentation-fault-in-calculation-of-excited-states?show=441#q441">here</a>. It looks like it's still there.</p>
<p>I want to calculate few excited states for spin-1/2 XY model. <br>
Since total Sz is conserved, I want to restrict myself to a sector with fixed nonzero Sz (equal to <strong>SzSector</strong> in the code below). I do so by picking <strong>InitState</strong> which belongs to this sector, and putting <strong>ConserveQNs=true</strong>.</p>
<p>However, I still can catch the segfault, with the following error message:</p>
<blockquote>
<p>div(T1)=QN({"Sz",-2}) must equal div(T2)=QN() when adding T1+T2</p>
</blockquote>
<p>While for SzSector=+1 I get:</p>
<blockquote>
<p>div(T1)=QN({"Sz",2}) must equal div(T2)=QN({"Sz",0}) when adding T1+T2</p>
</blockquote>
<p>The minimal (non-)working example code is following:</p>
<pre><code>#include "itensor/all.h"
using namespace itensor;
int main(int argc, char* argv[]) {
int N = 20;
int SzSector = -1;
int nstates = 2;
// Building Hamiltonian
auto sites = SpinHalf(N, {"ConserveQNs=", true});
auto ampo = AutoMPO(sites);
for (int x = 1; x <= N-1; x++) {
ampo += -1,"S+",x,"S-",x+1;
ampo += -1,"S-",x,"S+",x+1;
}
MPO H = toMPO(ampo);
// Preparing random initial state
InitState state(sites);
for (int i = 1; i <= N; i++) {
state.set(i, i <= N/2 + SzSector ? "Up" : "Dn");
}
//MPS psi0 = randomMPS(state);
MPS psi0(state);
// Initializing sweep parameters
auto sweeps = Sweeps(5);
sweeps.maxdim() = 200;
sweeps.cutoff() = 1e-9;
sweeps.niter() = 2;
sweeps.noise() = 1e-9;
// DMRG
std::vector<MPS> states;
std::vector<double> energies;
for (int i = 0; i < nstates; i++) {
auto [energy,psi] = dmrg(H, states, psi0, sweeps, {"Quiet=", true, "Weight=", 20.0});
states.push_back(psi);
energies.push_back(energy);
}
return 0;
}
</code></pre>
<p>The code with <strong>randomMPS(state)</strong> doesn't work as well.</p>
http://itensor.org/support/1581/error-when-calculating-excited-states-conserved-quantitiesMon, 08 Jul 2019 20:20:14 +0000Answered: Spin S Hamiltonians with quadratic terms
http://itensor.org/support/1578/spin-s-hamiltonians-with-quadratic-terms?show=1579#a1579
<p>Hi Jacopo,<br>
Although it sounds tedious, the approach you'll need to take is to just expand the dot product into a sum of products of non-vector-operator terms. It should only make your AutoMPO input for loops a bit more complicated but AutoMPO will be able to handle this input well and give you an optimally compressed MPO. </p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1578/spin-s-hamiltonians-with-quadratic-terms?show=1579#a1579Mon, 08 Jul 2019 13:51:30 +0000Answered: Compatibility problem for reading MPS from disk
http://itensor.org/support/1570/compatibility-problem-for-reading-mps-from-disk?show=1573#a1573
<p>Hi Yixuan,<br>
To answer your first question, at the moment the file formats used by ITensor are not guaranteed to be stable to version changes, due to the fact that we write out the binary representation of objects in memory. So they are also not guaranteed to work across different machines with different binary formats. So it's still a useful feature for writing objects to disk and reading them back throughout a single calculation or within the same version of ITensor, but not meant as a long-term storage solution.</p>
<p>One feature we are planning to add after we first address some other things is to add support for HDF5. Then we can have long-term stability of ITensors written to disk.</p>
<p>To answer your other question, I think you are right that combining TagSets and Index's in the prime function doesn't currently work. So as a work-around for now, please just call prime twice with the different arguments you would like to use and that should work. But also could you please file an issue about allowing this combination since I think it would be straightforward for Matt to add it.</p>
<p>Thanks,<br>
Miles</p>
http://itensor.org/support/1570/compatibility-problem-for-reading-mps-from-disk?show=1573#a1573Thu, 04 Jul 2019 17:14:25 +0000Answered: Apply a local operator to an MPS
http://itensor.org/support/1569/apply-a-local-operator-to-an-mps?show=1572#a1572
<p>Hi Nick,<br>
Yixuan's answer is correct and his solution is good. I also just added a code formula here with an answer to your question:<br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv3&page=formulas/mps_onesite_op">http://itensor.org/docs.cgi?vers=cppv3&page=formulas/mps_onesite_op</a></p>
<p>The formula I added is a bit more general, e.g. assuming the operator could come from anywhere and not only the op(sites,"Sz",i) function, though that is a very good way to get the "Sz" operator for your case. Also the formula does not call psi.position(i) because strictly speaking it's not necessary to do so for a one-site operation (since no truncation afterward is involved) but it can still be a good idea for reasons I discuss at the end of the formula page.</p>
<p>Miles</p>
http://itensor.org/support/1569/apply-a-local-operator-to-an-mps?show=1572#a1572Thu, 04 Jul 2019 17:06:24 +0000Answered: Create random initial MPS and IQMPS with given bond dimension
http://itensor.org/support/1567/create-random-initial-mps-and-iqmps-with-given-bond-dimension?show=1568#a1568
<p>Hi Jacopo,<br>
This is a good question, but unfortunately the answer is "no" right now. That's the short answer.</p>
<p>The longer answer is that we do plan to add this feature, so let me tell you our idea for how we want to do it, because maybe you can do it yourself if it's an important thing for you to have. What we have learned is that for making a random MPS of bond dimension m > 1 it's not really right to just randomize each tensor separately. Instead, the right thing to do, we think, is to make a unitary circuit where each 2-site unitary gate is a random unitary. Then by applying D layers of this circuit using a TEBD-like algorithm to a starting product state, one gets a (correctly) random MPS of bond dimension 2^D. This would not be too hard to code, as long as one figures out a correct way to make the random unitaries. We have a sample TEBD code on the website here: <a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv3&page=formulas/tevol_trotter">http://itensor.org/docs.cgi?vers=cppv3&page=formulas/tevol_trotter</a></p>
<p>For the quantum number conserving version there are some possibly tricky questions about the right way to make the random unitaries we aren't as sure about. So we'd have to do some thinking and some reading to be sure we know how to do that correctly. But we'd like to develop the non-QN version soon anyway, it's just right now we have some other pressing things to do. </p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1567/create-random-initial-mps-and-iqmps-with-given-bond-dimension?show=1568#a1568Fri, 28 Jun 2019 21:48:45 +0000Answered: MPO for truncated Hamiltonian and single qutrit gates
http://itensor.org/support/1561/mpo-for-truncated-hamiltonian-and-single-qutrit-gates?show=1562#a1562
<p>Hi Aditya,<br>
Thanks for the question. I see what you are wanting to do, but I think the AutoMPO approach might not be the best fit for it. Still, you are welcome to try (see #1 below) and see if it works for you. But there might be a nicer approach anyway (see #2 below) that you could try. </p>
<p>Approach #1:<br>
You could create a custom site set for AutoMPO to use. AutoMPO by itself does not define any operators, but gets them from the site set you provide to it. We don't have detailed tutorials on how to make a new site set, but you can copy one of the ones provided in ITensor which are in the itensor/mps/sites/ folder and use them as examples to copy and start from. For your case, mainly you would just remove all quantum numbers from the site object you create (in its constructor where it makes the Index it holds; this is referring to ITensor version 3+ code). Then you would change the op method to create and return the operators with the names and matrix elements that you want. Finally, you can try using your new site set in AutoMPO to see if it works well for you.</p>
<p>But one caution about this approach besides the question of getting AutoMPO to make what you want: if your next step is to do time evolution by exponentiating the Hamiltonian made from the AutoMPO, then although we provide some tools to do that, we and others have been finding that approach time evolution is not so accurate and has some practical issues. But maybe that's not what you were planning to do. So anyway see the next approach #2 below.</p>
<p>Approach #2:<br>
Because your circuit is made of local gates, you could make your initial "state" be an identity operator on N sites "folded over" or purified into a pure state on 2N sites. The resulting pure state is a product state of Bell pairs with neighboring even and odd sites perfectly entangled with each other. Then you could apply your gates on just the odd-numbered sites of this pure state using normal MPS time evolution techniques. Reinterpreted as an MPO, it would be the one that you want. </p>
<p>Finally, though, I am not sure if your overall idea of combining the MPO's together afterward together will scale well. The bond dimension of the resulting MPO might have to end up being as large as the most entangled possible state that could result from evolving with that sequence of MPOs starting from a product state. So just wanted to caution you about that, but most likely you are well aware of this challenge.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1561/mpo-for-truncated-hamiltonian-and-single-qutrit-gates?show=1562#a1562Thu, 27 Jun 2019 01:41:58 +0000Answered: Incorrect Hamiltonian from autompo of a spinless Majorana opeator
http://itensor.org/support/1554/incorrect-hamiltonian-autompo-spinless-majorana-opeator?show=1556#a1556
<p>Hi Victor,<br>
Thanks for the question. So the input you gave to AutoMPO is indeed @@C+C^\dagger@@ because as you can see on the first line you are saying ampo += C and on the second ampo += Cdag (which in words means "add C to the AutoMPO" then "add Cdag to the AutoMPO"). </p>
<p>To make a term with a product of C times Cdag, you need to write an input line like this:</p>
<pre><code>ampo += "C",i,"Cdag",j;
</code></pre>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1554/incorrect-hamiltonian-autompo-spinless-majorana-opeator?show=1556#a1556Wed, 26 Jun 2019 16:08:56 +0000Answered: How to use Matrix class
http://itensor.org/support/1551/how-to-use-matrix-class?show=1552#a1552
<p>Hello,</p>
<p>You can take a look at the unit tests for the ITensor Matrix class to get an idea for how it is used:</p>
<p><a rel="nofollow" href="https://github.com/ITensor/ITensor/blob/v3/unittest/matrix_test.cc#L922">https://github.com/ITensor/ITensor/blob/v3/unittest/matrix_test.cc#L922</a></p>
<p>Let us know if you have questions/some functionality that you need is not there.</p>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1551/how-to-use-matrix-class?show=1552#a1552Tue, 25 Jun 2019 19:15:37 +0000Answered: Computing specific heat
http://itensor.org/support/1548/computing-specific-heat?show=1549#a1549
<p>Hi Jacopo,</p>
<p>To create @@H^2@@, you could always create @@H@@ with <code>AutoMPO</code> and then use the function <code>nmultMPO</code> to multiply the MPO @@H@@ with itself.</p>
<p>Otherwise, to use <code>AutoMPO</code>, you would have to write out by hand all of the terms resulting from @@H^2@@, and input those terms into <code>AutoMPO</code>. This shouldn't be too bad for a Hamiltonian with local interactions.</p>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1548/computing-specific-heat?show=1549#a1549Fri, 14 Jun 2019 14:54:49 +0000Answered: MPO from combining two site gates
http://itensor.org/support/1545/mpo-from-combining-two-site-gates?show=1547#a1547
<p>Hello,</p>
<p>Do you mean an MPO that is a sum of gates, or a product of gates?</p>
<p>If the MPO is a sum of gates, you can use AutoMPO to easily create an MPO (as long as you write your gates in terms of products of local operators):</p>
<p><a rel="nofollow" href="https://itensor.org/docs.cgi?page=classes/autompo">https://itensor.org/docs.cgi?page=classes/autompo</a></p>
<p>If you mean a product of gates, there is a formula here that shows how to do it for a particular gate structure:</p>
<p><a rel="nofollow" href="http://www.itensor.org/docs.cgi?vers=cppv3&page=formulas/gates_to_mpo">http://www.itensor.org/docs.cgi?vers=cppv3&page=formulas/gates_to_mpo</a></p>
<p>The code would need to be adapted for other gate structures.</p>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1545/mpo-from-combining-two-site-gates?show=1547#a1547Wed, 12 Jun 2019 19:34:24 +0000Answered: Efficient matrix operation by directly accessing the storage of ITensor
http://itensor.org/support/1544/efficient-matrix-operation-directly-accessing-storage-itensor?show=1546#a1546
<p>I've come out with this solution:</p>
<p><code>for(auto i : range(u.size())) V[i] *= u[i];
for(auto i : range1(u.size())) V[0] += V[i];
phi = V[0];</code></p>
<p>it works fine. <strong>phi=sum_i (u[i]*V[i])</strong>, it seems that I'd consider this problem too complex at the first sight.</p>
http://itensor.org/support/1544/efficient-matrix-operation-directly-accessing-storage-itensor?show=1546#a1546Mon, 10 Jun 2019 12:47:37 +0000Answered: Construction of two site gate
http://itensor.org/support/1535/construction-of-two-site-gate?show=1541#a1541
<p>Hello,</p>
<p>Unfortunately in ITensor V2 this is admittedly a confusing situation. The following would be one way to do this:</p>
<pre><code>auto N = 4;
auto sites = SpinHalf(N);
auto init = InitState(sites);
for(auto n : range1(N))
{
init.set(n, "Up");
}
auto psi = MPS(init);
auto i = 2;
ITensor Sxi = sites.op("Sx",i);
ITensor Sxip = sites.op("Sx",i+1);
auto G = Sxi*Sxip;
PrintData(G);
</code></pre>
<p>The reason this works and what you tried did not is because by default, the <code>SpinHalf</code> SiteSet (and other SiteSets) create indices with QNs. That means operators like <code>sites.op("Sx",i)</code> must return an IQTensor. However, the "Sx" operator doesn't have a well defined QN. Through a little bit of a trick, we allow you to make this operator anyway, only so that it can get converted to an ITensor, for example using the line <code>ITensor Sxi = sites.op("Sx",i)</code>. Once the operators are converted to ITensors, you can use them as you would any other ITensor, but before you convert them, the multiplication <code>sites.op("Sx",i)*sites.op("Sx",i+1)</code> is not defined (which is why you get an error message mentioning <code>QMixed</code> storage, which is the storage type those IQTensors are created with).</p>
<p>The situation is greatly improved in ITensor V3, where you can do the following:</p>
<pre><code>auto N = 4;
auto sites = SpinHalf(N,{"ConserveQNs=",false});
auto init = InitState(sites);
for(auto n : range1(N))
{
init.set(n, "Up");
}
auto psi = MPS(init);
auto i = 2;
auto G = sites.op("Sx",i)*sites.op("Sx",i+1);
PrintData(G);
</code></pre>
<p>In ITensor V3, the IQTensor and ITensor classes have been merged, so all of the objects are ITensors. Putting <code>{"ConserveQNs=",false}</code> just makes the choice of whether or not the indices have QN information and whether or not the ITensors are block sparse. We would encourage you to try out ITensor V3 (<a rel="nofollow" href="http://www.itensor.org/docs.cgi?vers=cppv3&page=upgrade2to3">http://www.itensor.org/docs.cgi?vers=cppv3&page=upgrade2to3</a> ) for this and a variety of other improvements.</p>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1535/construction-of-two-site-gate?show=1541#a1541Fri, 31 May 2019 16:06:09 +0000Answered: problem with contracting the indices in a ITensor
http://itensor.org/support/1528/problem-with-contracting-the-indices-in-a-itensor?show=1531#a1531
<p>Hello,</p>
<p>If you are trying to calculate the matrix element of two different MPS, using the gauge conditions will not work for calculating a local operator. Please see this code formula: <a rel="nofollow" href="http://www.itensor.org/docs.cgi?vers=cppv2&page=formulas/two_mps">http://www.itensor.org/docs.cgi?vers=cppv2&page=formulas/two_mps</a> for information on how to calculate matrix elements involving two different MPS.</p>
<p>Also note that you could use the <code>overlap</code> function for this case, but it accepts input like <code>overlap(MPS,MPO,MPS)</code>, so requires that you write your local operator as an MPO. This would also be a reasonable thing to do, and nearly as efficient as writing it by hand (depending on how you represent the operator as an MPO).</p>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1528/problem-with-contracting-the-indices-in-a-itensor?show=1531#a1531Wed, 29 May 2019 14:07:46 +0000Answered: the Ising model in a transverse field, DMRG
http://itensor.org/support/1514/the-ising-model-in-a-transverse-field-dmrg?show=1520#a1520
<p>Hello,</p>
<p>I believe that website you are referencing is slightly wrong. The phase transition for the Hamiltonian they write down, written in terms of spin operators, should be <code>h/J=1/2</code>, not <code>h/J=1</code> (all of it looks correct if the Hamiltonian was written in terms of Pauli operators). If you change the line to:</p>
<pre><code>ampo += -2.0,"Sz",j,"Sz",j+1;
</code></pre>
<p>you should get the correct critical ground state (and the energy should match the formula they give, up to a factor of two, I believe also because of the confusion between using Pauli operators and spin operators).</p>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1514/the-ising-model-in-a-transverse-field-dmrg?show=1520#a1520Tue, 28 May 2019 15:50:04 +0000Answered: take advantage of sparsity of MPO for 2d system in DMRG
http://itensor.org/support/1508/take-advantage-of-sparsity-of-mpo-for-2d-system-in-dmrg?show=1509#a1509
<p>Hi Mingpu,<br>
Thanks for the question. We haven't taken too much advantage of MPO sparsity yet. It would be an interesting thing to try doing. One reason is that we just have many things we want to try with only a small number of developers so far. The other reason is that using the sparsity might not give a significant enough benefit except when the MPO is very large (you did mention 2D systems, yes). So one would have to just try.</p>
<p>I should mention that one thing we do employ sometimes is to split the Hamiltonian up into separate MPOs. Then we have a special mode of DMRG that performs a summation loop over all of these MPOs at each step of DMRG. So for cases like quantum chemistry systems this can give a nice speedup since the MPO has a block-diagonal (block-sparse) structure. </p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1508/take-advantage-of-sparsity-of-mpo-for-2d-system-in-dmrg?show=1509#a1509Wed, 22 May 2019 15:15:50 +0000Answered: How to realize Hubbard-Holstein model
http://itensor.org/support/1502/how-to-realize-hubbard-holstein-model?show=1507#a1507
<p>Hi Weijie,<br>
Ok thanks, that looks more like what I expected. So to implement this model, you will have to make a custom site set which is not one of the standard ones provided. But it should be easy to make.</p>
<p>Steps to do:</p>
<ol>
<li><p>upgrade to ITensor version 3 if you haven't already:<br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv3&page=upgrade2to3">http://itensor.org/docs.cgi?vers=cppv3&page=upgrade2to3</a></p></li>
<li><p>define your new site set "Holstein" as follows (outside of your main function):</p>
<p>using Holstein = MixedSiteSet<ElectronSite,BosonSite>;</p></li>
<li><p>now if you make a site set object like this:</p>
<p>auto sites = Holstein(N,{"MaxOcc=",3});</p></li>
</ol>
<p>then the odd numbered sites will be electron sites and the even numbered sites will be boson sites. The "MaxOcc" named argument is what sets the maximum occupancy of the boson sites. Of course in reality one would like this to be very large, but practically one has to limit this to a finite value; you should check that your results are converged in this value and that you have taken it large enough.</p>
<ol>
<li><p>when you make your AutoMPO, be sure to use only operators defined for the Electron site set (<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv3&page=classes/electron)">http://itensor.org/docs.cgi?vers=cppv3&page=classes/electron)</a> on odd-numbered sites and the boson site set (<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv3&page=classes/boson)">http://itensor.org/docs.cgi?vers=cppv3&page=classes/boson)</a> for even numbered sites</p></li>
<li><p>once your Hamiltonian gets made correctly (possibly after further discussion here), make sure to test it carefully on small systems and check, if possible, with results obtained using other methods, or at least in limits where you have a good understanding of what the results ought to be</p></li>
</ol>
<hr>
<p>Following up on the comments below, here is a complete working sample code (to be used with the very latest version of the v3 branch, dated May 29):</p>
<pre><code>#include "itensor/all.h"
using namespace itensor;
using Holstein = MixedSiteSet<ElectronSite,BosonSite>;
int
main()
{
auto N = 20;
auto U = 1.0;
auto J = 1.0;
auto g = 3.0;
auto K = 5.0;
auto sites = Holstein(N,{"ConserveNf=",true,
"ConserveNb=",false,
"MaxOcc=",3});
auto ampo = AutoMPO(sites);
for(int j=1;j <= N-2; j+=2)
{
ampo += -J,"Cdagup",j+2,"Cup",j;
ampo += -J,"Cdagup",j,"Cup",j+2;
ampo += -J,"Cdagdn",j+2,"Cdn",j;
ampo += -J,"Cdagdn",j,"Cdn",j+2;
}
for(int j=1;j < N; j += 2)
{
ampo += U,"Nup",j,"Ndn",j;
ampo += g,"Ntot",j,"A",j+1;
ampo += g,"Ntot",j,"Adag",j+1;
}
for(int j = 2; j <= N; j += 2)
{
ampo += K,"N",j;
}
auto H = toMPO(ampo);
auto sweeps = Sweeps(20);
//very important to use noise for this model
sweeps.noise() = 1E-6,1E-6,1E-8,1E-12;
sweeps.maxdim() = 10,20,100,100,200;
sweeps.cutoff() = 1E-10;
auto state = InitState(sites);
for(auto j : range1(N))
{
if(j%4==1) state.set(j,"Up");
else if(j%4==3) state.set(j,"Dn");
else state.set(j,"0");
}
auto psi0 = MPS(state);
auto [energy,psi] = dmrg(H,psi0,sweeps,{"Quiet=",true});
printfln("Ground State Energy = %.12f",energy);
auto checkNtot = 0.0;
println("Up Electron Density:");
for(int j = 1; j <= N; j += 2)
{
psi.position(j);
auto upd = elt(dag(prime(psi(j),"Site"))*op(sites,"Nup",j)*psi(j));
checkNtot += upd;
printfln("%d %.12f",j,upd);
}
println();
println("Dn Electron Density:");
for(int j = 1; j <= N; j += 2)
{
psi.position(j);
auto dnd = elt(dag(prime(psi(j),"Site"))*op(sites,"Ndn",j)*psi(j));
checkNtot += dnd;
printfln("%d %.12f",j,dnd);
}
println();
Print(checkNtot);
println("Boson Density:");
for(int j = 2; j <= N; j += 2)
{
psi.position(j);
auto bd= elt(dag(prime(psi(j),"Site"))*op(sites,"N",j)*psi(j));
printfln("%d %.12f",j,bd);
}
println();
return 0;
}
</code></pre>
http://itensor.org/support/1502/how-to-realize-hubbard-holstein-model?show=1507#a1507Tue, 21 May 2019 17:10:39 +0000Answered: Extrapolation with truncation error
http://itensor.org/support/1493/extrapolation-with-truncation-error?show=1501#a1501
<p>Hi R.,<br>
To briefly answer your questions:</p>
<p>1 & 2:<br>
The best practice for extrapolating in truncation error is to do <em>two sweeps</em> at a fixed maximum MPS bond dimension "m", then use the energy from the last half-sweep (the last of the four half-sweeps making up the two sweeps) and the corresponding truncation error computed at the central bond of the MPS. This is what is reported by our DMRG code by default, so if you set up your Sweeps object to do two sweeps of each bond dimension, then use the energy and truncation error reported for the second of each sweep, that should be what you need for extrapolation purposes.</p>
<p>If you want to get more detail, just turn off the "Quiet" named argument to DMRG or set it to false. Then you should get a report of the truncation error at every single step.</p>
<p>3: I don't actually know the answer to this - it's a good question. I think it would be a good exercise to convince yourself of why a linear extrapolation is justified by imagining you have a state which is within epsilon of the true ground state using the Euclidean norm / distance. And assume there is a gap to all excited states. Then you can probably recover the argument of the energy error scaling as epsilon to leading order. Then try repeating the argument for excited states (maybe just the first excited state) to see how much of it goes through. </p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1493/extrapolation-with-truncation-error?show=1501#a1501Mon, 20 May 2019 17:44:44 +0000install on linux Ubuntu 18.04
http://itensor.org/support/1497/install-on-linux-ubuntu-18-04
<p>Hi,</p>
<p>I run into problems when installing itensor on Linux(Ubuntu 18.04 ). Here is the error message after running the make file:</p>
<blockquote>
<p>Makefile:2: /home/essa/itensor/this<em>dir.mk: No such file or directory<br>
make: *** No rule to make target '/home/essa/itensor/this</em>dir.mk'. Stop.</p>
</blockquote>
<p>Do you have any idea what went wrong?</p>
<p>Thanks</p>
http://itensor.org/support/1497/install-on-linux-ubuntu-18-04Mon, 20 May 2019 10:53:39 +0000"make" chokes on "itensor_operators.cc" -- windows/cygwin
http://itensor.org/support/1489/make-chokes-on-itensor_operators-cc-windows-cygwin
<p>$ make</p>
<p>Configure: Writing current dir to this_dir.mk</p>
<p>Building ITensor library</p>
<p>make[1]: Entering directory '/cygdrive/c/Users/vadim/itensor/itensor'<br>
Compiling itensor/itensor_operators.cc in debug mode</p>
<p>/usr/lib/gcc/x86<em>64-pc-cygwin/7.4.0/../../../../x86</em>64-pc-cygwin/bin/as: .debug<em>objs/itensor</em>operators.o: section .debug<em>frame$</em>ZN7itensor6detail5FuncTINS0<em>8CallWrapINS0</em>12RegisterTaskINS0<em>7TwoArgsISt10shared</em>ptrINS<em>6ITDataEENS</em>6CPDataEEEONS<em>8ContractINS</em>7IQIndexEEENS<em>8NoneTypeEEESC</em>KNS<em>6ScalarISt7complexIdEEESE</em>S7<em>S8</em>EENS<em>8TypeListIJNS</em>6QDenseISI<em>EENS</em>9QCombinerENS<em>5QDiagIdEENSQ</em>ISI<em>EENS</em>6QMixedIdEENST<em>ISI</em>EENSG<em>IdEESJ</em>EEEE7applyToERKSO_: string table overflow at offset 10000178<br>
/tmp/ccoviA1e.s: Assembler messages:<br>
/tmp/ccoviA1e.s: Fatal error: can't close .debug<em>objs/itensor</em>operators.o: File too big<br>
Failure while executing command: g++ -std=c++11 -Wa,-mbig-obj -O2 -fPIC -c -I/cygdrive/c/Users/vadim/itensor -DDEBUG -g -Wall -pedantic -DPLATFORM_lapack -D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0 -o .debug_objs/itensor_operators.o itensor_operators.cc<br>
make[1]: *** [Makefile:64: .debug_objs/itensor_operators.o] Error 1<br>
make[1]: Leaving directory '/cygdrive/c/Users/vadim/itensor/itensor'<br>
make: *** [Makefile:14: itensor] Error 2</p>
http://itensor.org/support/1489/make-chokes-on-itensor_operators-cc-windows-cygwinTue, 14 May 2019 02:10:35 +0000Answered: LaTeX formulas not rendering properly on the website
http://itensor.org/support/1477/latex-formulas-not-rendering-properly-on-the-website?show=1479#a1479
<p>Hi, thanks for the bug report. Unfortunately I'm not able to reproduce this issue because it is working for me in Chrome, Safari, and iOS. Is it still not working for you? Perhaps it is because you have a firewall or some other internet situation that is blocking the content delivery network (CDN) that is used to render the MathJax (this is cdn.mathjax.org)?</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1477/latex-formulas-not-rendering-properly-on-the-website?show=1479#a1479Sun, 12 May 2019 16:19:52 +0000DMRG doesn't work with certain initial conditions in fermionic systems
http://itensor.org/support/1476/doesnt-work-certain-initial-conditions-fermionic-systems
<p>Hello,</p>
<p>I am running some calculations on a 4-site square chain with a tight-binding Hamiltonian, and have found an issue when applying the DMRG function to my system. Depending on the state I initialize the system, the DMRG can either run normally and return the expected value for the energy, or almost instantly return a (wrong) value of 0 for the ground state energy. Here is a sample code to demonstrate the problem:</p>
<pre><code>#include "itensor/all.h"
using namespace itensor;
int main()
{
int N = 4;
double t = 1.0;
int nsweeps = 5;
int maxm = 200;
double cutoff = 1E-15;
int niter = 2;
double noise = 0;
auto sites = Hubbard(N);
auto ampo = AutoMPO(sites);
ampo += -t,"Cdagup",1,"Cup",2;
ampo += -t,"Cdagup",2,"Cup",1;
ampo += -t,"Cdagdn",1,"Cdn",2;
ampo += -t,"Cdagdn",2,"Cdn",1;
ampo += -t,"Cdagup",1,"Cup",3;
ampo += -t,"Cdagup",3,"Cup",1;
ampo += -t,"Cdagdn",1,"Cdn",3;
ampo += -t,"Cdagdn",3,"Cdn",1;
ampo += -t,"Cdagup",2,"Cup",4;
ampo += -t,"Cdagup",4,"Cup",2;
ampo += -t,"Cdagdn",2,"Cdn",4;
ampo += -t,"Cdagdn",4,"Cdn",2;
ampo += -t,"Cdagup",3,"Cup",4;
ampo += -t,"Cdagup",4,"Cup",3;
ampo += -t,"Cdagdn",3,"Cdn",4;
ampo += -t,"Cdagdn",4,"Cdn",3;
//Use IQMPO or MPO to generate the hamiltonian
auto H = IQMPO(ampo);
Print(ampo);
//Define initial wavefunction MPS for IQMPS
auto state1 = InitState(sites);
state1.set(1,"Up");
state1.set(2,"Up");
state1.set(3,"0");
state1.set(4,"0");
//Create IQMPS
auto psi = IQMPS(state1);
//Overlap test
auto state2 = InitState(sites);
state2.set(1,"0");
state2.set(2,"Up");
state2.set(3,"Up");
state2.set(4,"0");
auto psi2 = IQMPS(state2);
println(overlap(psi2,H,psi));
//Define DMRG sweeps
auto sweeps = Sweeps(nsweeps);
sweeps.maxm() = maxm/20,maxm/10,maxm/2,maxm/2,maxm;
sweeps.cutoff() = cutoff;
sweeps.niter() = niter;
sweeps.noise() = noise;
auto energy = dmrg(psi,H,sweeps,{"Quiet",true});
return 0;
} //End of main
</code></pre>
<p>When I run this code exactly as it is, the DMRG returns a value of 0 for the ground state energy. The same happens if the two electrons are initialized in sites 3 and 4. However, if I change the initial conditions to initialize the electrons on other combinations of sites (for instance sites 1 and 3), I get the correct value for the energy (-2).</p>
<p>I've made some tests and found out this problem does not happen if I change the ordering of the sites to a cyclic chain, that is, with interactions 1-2, 2-3, 3-4, 4-1. However, since my goal is to work with larger chains, I figured I should number the sites the way I am doing in the sample code, as to avoid creating super-long-range interactions when working with more sites. Therefore, I think having a fix for this problem while still using my ordering would be ideal.</p>
<p>I believe the cause of this issue is the way the ITensor library handles the fermionic operators "Cdagup" and "Cup". Depending on the order they are applied when initializing the system and how many anticommutations are made when the Hamiltonian is applied, the final sign of the tight-binding interaction might become positive when it should be negative, thus "fooling" the DMRG algorithm into believing the system is already at the lowest energy level. To exemplify, if one calculates the overlap <0 Up Up 0| H |Up Up 0 0> in the sample code, instead of the expected result of -1 (given the sign of the hopping term), the code returns +1. </p>
<p>This overlap test made me think a simple change of signs on the Hamiltonian could solve everything. However, I discovered that changing the sign of the hopping term on the specific part of the Hamiltonian that annihilates one electron on the first site and creates it on the third site doesn't seem to completely fix the problem; although the overlap described above now returns a value of -1, the DMRG surprisingly still returns a value of 0 for the energy. </p>
<p>So, I wanted to ask if there is anyway I can have consistent (a.k.a. not dependent on the initial conditions) DMRG results for my system while keeping the ordering of the sites intact. I would appreciate any input into this. Thanks!</p>
http://itensor.org/support/1476/doesnt-work-certain-initial-conditions-fermionic-systemsThu, 09 May 2019 18:29:48 +0000Answered: define initial state in iTEBD
http://itensor.org/support/1467/define-initial-state-in-itebd?show=1474#a1474
<p>Hi, so unfortunately we can't provide official user support specifically for codes listed on the "ITensor codes" page. This is because those codes are written by a variety of people outside the ITensor development team, and we do not always understand their inner workings in detail. </p>
<p>But taking a quick look at that code, it appears that QNA and QNB are how you set an initial state. I believe that setting these creates an initial state which is a product state where each site (of the two sites) has a state defined by the quantum numbers QNA, and QNB, where these quantum numbers are defined through the IQIndex sites (but unfortunately the description of this part is vague, I agree, so you'll have to read the code or ask the code's developer).</p>
<p>He does describe the usage somewhat in the readme file here: <a rel="nofollow" href="https://github.com/hoihui/itebd">https://github.com/hoihui/itebd</a></p>
<p>The line "Sys(ampo,2,3)" is defining an object of type "itebd" and calling its constructor function, which takes an AutoMPO object and two integers. The itebd type is defined as "struct itebd ..." in the itebd.h file. </p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1467/define-initial-state-in-itebd?show=1474#a1474Wed, 08 May 2019 13:33:44 +0000Answered: Time Evolution of multi-band Hubbard Model Not Working
http://itensor.org/support/1449/time-evolution-of-multi-band-hubbard-model-not-working?show=1473#a1473
<p>Hi, thanks for the question but basically one would need to look more deeply into each step of the calculation to find out what is going on. But my suspicion is that the MPO approach is not well-suited for the kind of Hamiltonian you are evolving with.</p>
<p>I presume you are using the toExpH function to approximately exponentiate an AutoMPO then using that to do the time evolution? This approach to time evolution has actually been turning out not to work too well compared to other methods, especially for Hamiltonians with further-neighbor interactions (in the sense of the ordering of the sites of an MPS). But we put it into ITensor as an option for people to try, since it can work fine in certain cases and can be useful for benchmarking other, more accurate methods such as using Trotter gates.</p>
<p>Most likely for your case the best approach for time evolution would be to use the TDVP method. We don't have a TDVP code available in ITensor at the moment, but one of our colleagues is working on one so we hope to make that public sometime this summer. Also you could write a TDVP code yourself if you have the time & energy to do so. </p>
<p>Best regards,<br>
Miles</p>
<p>(Also, please see my question in the comment above about the long-rangedness of your Hamiltonian and the possibility of using Trotter gates.)</p>
http://itensor.org/support/1449/time-evolution-of-multi-band-hubbard-model-not-working?show=1473#a1473Wed, 08 May 2019 13:22:36 +0000Answered: initial state in the "toExpH" function
http://itensor.org/support/1470/initial-state-in-the-toexph-function?show=1471#a1471
<p>Hi,<br>
<code>toExpH</code> only converts ampo object to <strong>exp(−tauH)</strong>, you can use <code>exactApplyMPO</code> or <code>fitApplyMPO</code> to compute <strong>exp(−tauH)|psi></strong></p>
<p>e.g. <strong>psi1</strong> is the initial state:<br>
<code>auto expH = toExpH<ITensor>(ampo,tau);</code><br>
<code>psi1 = exactApplyMPO(expH,psi1,args);</code></p>
http://itensor.org/support/1470/initial-state-in-the-toexph-function?show=1471#a1471Wed, 08 May 2019 02:36:36 +0000Answered: Extract effective hamiltonian from LocalMPO
http://itensor.org/support/1450/extract-effective-hamiltonian-from-localmpo?show=1469#a1469
<p>The effective Ham support in modified localmpo.h and localop.h can be found <a rel="nofollow" href="https://github.com/empter/ITensor/commit/c12de4cee5ac21d90943bddd58748d68487b85e1">here</a>.<br>
With LocalMPO object PH</p>
<p><code>PH.position(b,psi);
Tenosr heff;
PH.localh(heff);</code><br>
gives the two-site (b,b+1) effective Hamiltonian held in <code>heff</code></p>
<p>The most challenging problem is how to calculate <strong>e^(-i Heff t)|psi></strong>, a possible way is using the Keylov subspace algorithm. In my practice, it is difficult to implemented this algorithm under itensor, because it needs expnonHermitian, or eigensystem of non-Hermitian matrix.</p>
http://itensor.org/support/1450/extract-effective-hamiltonian-from-localmpo?show=1469#a1469Tue, 07 May 2019 12:51:17 +0000Answered: Single site SVD - QR decomposition
http://itensor.org/support/1459/single-site-svd-qr-decomposition?show=1460#a1460
<p>Hi Jacopo,</p>
<p>That sounds like a good approach for doing what you want to do. In the code above, is <code>phi</code> a copy of <code>psi.A(b)</code>?</p>
<p>I am not sure why it would be seg faulting. The reason would not be that <code>U</code> and <code>psi.A(b)</code> have different ordering of indices, since ITensor doesn't care what the ordering of the indices are. Could you run your code in debug mode and see if it outputs any more specific errors?</p>
<p>In order to help debug it would be helpful to have a minimal working example of the code that is failing.</p>
<p>Here is a minimal example of how this approach would work (this runs correctly for me):</p>
<pre><code>auto N = 10;
auto sites = SpinHalf(N);
auto psi = MPS(sites);
auto b = 4;
// Set the center site gauge with ITensor
psi.position(b);
// Move the center gauge manually
auto lb = linkInd(psi,b);
ITensor U,S,V(lb);
svd(psi.A(b),U,S,V);
psi.setA(b,U);
psi.Aref(b+1) *= S*V;
</code></pre>
<p><code>linkInd(psi,b)</code> is a shorthand for <code>commonIndex(psi.A(b),psi.A(b+1),Link)</code>. Also note that if you put indices only on the <code>V</code> tensor, the <code>svd</code> function will use those to determine how to reshape the input tensor.</p>
<p>Note that a more efficient alternative to using <code>svd</code>, if you don't need extremely high accuracy of your singular values, is to use <code>denmatDecomp</code> ( <a rel="nofollow" href="http://itensor.org/docs.cgi?page=classes/decomp">http://itensor.org/docs.cgi?page=classes/decomp</a> ), which directly computes <code>T = U*B</code> where <code>B = S*V</code>.</p>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1459/single-site-svd-qr-decomposition?show=1460#a1460Tue, 30 Apr 2019 14:47:09 +0000Answered: Simple exact diagonalization missing code formula
http://itensor.org/support/1454/simple-exact-diagonalization-missing-code-formula?show=1456#a1456
<p>Thanks Joel - this was just an issue with the website, which we recently upgraded to let users switch between multiple versions of the documentation. Please check again and the code ought to appear for you now -</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1454/simple-exact-diagonalization-missing-code-formula?show=1456#a1456Mon, 29 Apr 2019 14:00:29 +0000Answered: main function
http://itensor.org/support/1452/main-function?show=1453#a1453
<p>Hi, so if you want to put ITensor code into a function (which is a good idea), you can do this in the same way as putting any other C++ code into a function.</p>
<ol>
<li><p>identify which variables you would like to be changeable or adjustable each time the function is run. (For the example of AutoMPO, let's say this is the Sz*Sz coupling called Jz.) Also you will need to pass variables to the function which are required for it to run, such as your site set needed to create your AutoMPO.</p></li>
<li><p>create a function which takes the needed variables (here it is your site set and Jz).</p></li>
<li><p>put the code into the function and then return the result of that code, in this case the MPO you create from the AutoMPO.</p></li>
</ol>
<p>Here is an example:</p>
<pre><code>MPO
makeH(SiteSet const& sites,
Real Jz)
{
auto N = sites.N();
auto ampo = AutoMPO(sites);
for(int j = 1; j < N; ++j)
{
ampo += 0.5,"S+",j,"S-",j+1;
ampo += 0.5,"S-",j,"S+",j+1;
ampo += Jz,"Sz",j,"Sz",j+1;
}
return MPO(ampo);
}
</code></pre>
<p>(Advanced C++ user note: If you put the function into a header file, don't forget to put the "inline" keyword at the front of the function definition.)</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1452/main-function?show=1453#a1453Sun, 28 Apr 2019 16:12:56 +0000Answered: tMPS and OpenBLAS
http://itensor.org/support/1446/tmps-and-openblas?show=1447#a1447
<p>Hi Jin,<br>
I think the answer to #1 is complicated. I'm not sure what the difference in error would be between the two methods without doing a careful theoretical error analysis. Barring that, I think if you're really very curious about both methods, or suspect one might not be accurate enough for what you need, then you could just code both of them and plot results to see how the errors behave.</p>
<p>Regarding BLAS parallelism, it's kind of complicated also. Sometimes we have seen speedups from letting the BLAS use multiple cores, but other times we've seen what you report, namely that it does a bad job and can even hurt speed. Basically this is a feature of your BLAS which is outside of ITensor and which we do not control. Also its effectiveness is highly dependent on the details of the algorithm you are doing, whether DMRG or another algorithm, and the sizes of the tensors, their block structure, etc. So again I think your best bet is just to adjust the settings as you have done and see what works best for your needs. Also you might get different results with a different BLAS implementation, such as MKL which is a very high quality BLAS code.</p>
<p>Best regards,<br>
Miles</p>
<p>P.S. about the BLAS, you might want to write a simple test code which just multiplies two very large matrices, and run that with different OPENBLAS NUM THREADS settings to see what results you get. If it doesn't work for that, i.e. if it doesn't give a speedup even for rather large matrices, you might conclude that it's just not a very useful feature of your BLAS. On the other hand, if you do see a speedup, you should see what matrix sizes are needed to see it and compare to the typical sizes in your DMRG calculation. Perhaps it could help if you turn it on for a very large DMRG calculation in the last few sweeps.</p>
http://itensor.org/support/1446/tmps-and-openblas?show=1447#a1447Fri, 19 Apr 2019 15:51:41 +0000Answered: Parallelization of Trotter with openMP
http://itensor.org/support/1444/parallelization-of-trotter-with-openmp?show=1445#a1445
<p>Hi, so we have not explored parallelism with OpenMP very much. But please do try it and let us know if you run into any issues. The kind of parallelism you are describing would sit outside of ITensor, which is why we have not documented it (it's not a feature of ITensor, but just a way of using ITensor inside of a larger code). </p>
<p>In the past, I have used ITensor within a multi-threaded code where I created a parallel for loop using the C++ threading library and it worked extremely well. So hopefully you can use an OpenMP parallel for loop in the same way. The reason I say "let us know if you run into any issues" is that there may be some special handling of certain parts of ITensor we need to put in to make things thread safe within OpenMP. We can do this and add a compiler flag to turn it on, but please just try it first.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1444/parallelization-of-trotter-with-openmp?show=1445#a1445Tue, 16 Apr 2019 14:49:13 +0000Quick code review: Possible misunderstanding of MPO/MPS
http://itensor.org/support/1439/quick-code-review-possible-misunderstanding-of-mpo-mps
<p>The below (< 50 lines) of code is the simplest way I could illustrate my possible misunderstanding. To be clear, this is <em>not</em> the actual problem I am trying to solve in my research (the solution is trivial); I'm just trying to find my way around ITensor and MPO/MPS.</p>
<p>Here is my current understanding of what this code <strong>should</strong> do: I construct an MPS of all "occupied" sites and two MPOs. The first is the Hamiltonian, which is supposed to subtract particles from occupied sites to yield empty sites, at a simple rate of 1. At each timestep, I apply the Hamiltonian times a small timestep @@h@@. This is the explicit Euler solution to the equation:</p>
<p>$$<br>
\frac{\mathrm{d} \mathbf{y}}{\mathrm{d} t} = A \mathbf{y}<br>
$$</p>
<p>The observable I want to record is the number of occupied sites, so I use the second MPO, constructed from the number operator, and apply it as @@\langle \psi, B \psi \rangle@@.</p>
<p>Examining the raw output, or even plotting the results, is not encouraging, because the total number of occupied states is increasing, not decreasing. I'm sure I've just misunderstood something along the way, but I can't think of any particcular reason why the method I've described wouldn't yield (something close to) the analytic solution,</p>
<p>$$<br>
y(t) = 3 e^{-t}.<br>
$$</p>
<p>As always, help is greatly appreciated.</p>
<pre><code>#include <itensor/all_basic.h>
#include <itensor/all_mps.h>
#include <iostream>
int main(int argc, char *argv[])
{
int N = 3;
auto sites = itensor::Spinless(N);
auto ampo = itensor::AutoMPO(sites);
auto ampo2 = itensor::AutoMPO(sites);
auto state = itensor::InitState(sites);
for (auto j : itensor::range1(N))
{
ampo += "A", j;
ampo2 += "N", j;
state.set(j, "Occ");
}
auto mpo = itensor::toMPO<itensor::ITensor>(ampo, { "Exact=", true });
auto mpo2 = itensor::toMPO<itensor::ITensor>(ampo2, { "Exact=", true });
auto mps = itensor::MPS(state);
double h = 1.e-6, t = 0;
for (auto i : itensor::range(1000))
{
mps.plusEq(h * itensor::applyMPO(mpo, mps, { "Exact=", true }));
t += h;
auto norm = itensor::overlap(mps, mps);
auto count = itensor::overlap(mps, mpo2, mps);
std::cout << std::scientific << t << " " << norm << " " << count
<< std::defaultfloat << std::endl;
}
return 0;
}
</code></pre>
http://itensor.org/support/1439/quick-code-review-possible-misunderstanding-of-mpo-mpsFri, 12 Apr 2019 17:58:08 +0000Answered: Efficient way to manually increase bond dimension of MPS or IQMPS
http://itensor.org/support/1419/efficient-way-manually-increase-bond-dimension-of-mps-iqmps?show=1438#a1438
<p>Just to give an official answer to summarize the comments above:</p>
<ol>
<li><p>As a technical problem of expanding the subspace of an IQMPS, it is not directly built into ITensor right now, though with some modification of existing code in itensor/mps/mpsalgs.cc it is not hard to do. For example, take a look at: <a rel="nofollow" href="https://gist.github.com/mtfishman/1804a3a473112cb7cb80722eeac47a8b">https://gist.github.com/mtfishman/1804a3a473112cb7cb80722eeac47a8b</a> which shows an implementation of a "partial direct sum" operation of two IQTensors, which should be sufficient for doing a subspace expansion of an IQMPS. This is something that we will try to support officially in ITensor as soon as possible.</p></li>
<li><p>A general question which is application dependent is how to choose the QNs of an expanded IQMPS subspace. The answer is that, when possible, it is best to determine the expanded subspace using the physics of your problem. For a single site DMRG calculation, a popular method seems to be ( <a rel="nofollow" href="https://arxiv.org/pdf/1501.05504.pdf">https://arxiv.org/pdf/1501.05504.pdf</a> ), but various methods have been proposed. Alternatively, a method that would work fairly generically would be to first perform a 2-site version of the MPS algorithm you are interested in (for example, 2-site DMRG or 2-site TDVP), which will automatically expand the subspace. Then, you can switch to a 1-site version once the desired bond dimension is reached.</p></li>
</ol>
http://itensor.org/support/1419/efficient-way-manually-increase-bond-dimension-of-mps-iqmps?show=1438#a1438Wed, 10 Apr 2019 19:22:08 +0000Answered: Trotter gates for ancilla/purification method
http://itensor.org/support/1426/trotter-gates-for-ancilla-purification-method?show=1427#a1427
<p>Hi Jacopo,<br>
Thanks for the question. So the problem here is on us, namely that we had not yet documented the gateTEvol method despite publicizing it. The key thing you are missing is that gateTEvol requires each of the gates passed to it to act only on consecutive (nearest-neighbor) site pairs. </p>
<p>I just started documenting it so people will know this in the future:<br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv2&page=classes/tevol">http://itensor.org/docs.cgi?vers=cppv2&page=classes/tevol</a></p>
<p>In order to do the ancilla technique with Trotter gates (which is a very good way to do it), you will need to insert "swap gates" into your gate list. You can use the "Gate = BondGate" class to make swap gates like this:</p>
<pre><code>auto swapij = Gate(sites,i,j);
</code></pre>
<p>In the upcoming version 3 of ITensor we're going to make a more intuitive interface for making gates. (Probably just separate functions such as <code>swapGate</code>, <code>realGate</code>, <code>imagGate</code> etc.)</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1426/trotter-gates-for-ancilla-purification-method?show=1427#a1427Wed, 10 Apr 2019 14:53:38 +0000Answered: Addition of onsite terms in trotter gates gives wrong overlap with ground state of H
http://itensor.org/support/1413/addition-onsite-trotter-gates-gives-wrong-overlap-ground-state?show=1415#a1415
<p>Hi, thanks for the question. The answer is that why this is happening could be due to many reasons, so it's hard to tell just from the description of the results you are seeing.</p>
<p>The most likely reason, if I had to guess, is that Trotter gates very generally incur a finite-time-step error, as you know. So the evolution is not exact. Therefore even if theoretically the overlap should stay very close to 1, in practice it will not. How close it stays should then depend on how small of a time step you use, how many steps you do, and how accurately you decompose/truncate the MPS after each step.</p>
<p>Another possibility is that there is a slight error or bug in your code.</p>
<p>If you try adjusting the time step and other accuracy parameters, and do other checks you can think of, but then think the results you are seeing cannot be right, please post a follow up comment or new question, perhaps with some code, and we can discuss more.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1413/addition-onsite-trotter-gates-gives-wrong-overlap-ground-state?show=1415#a1415Mon, 08 Apr 2019 14:49:32 +0000Answered: Computing the partial Kronecker product of two ITensors
http://itensor.org/support/1407/computing-the-partial-kronecker-product-of-two-itensors?show=1408#a1408
<p>Hello,</p>
<p>If I understand the operation correctly, I think you could do it this way:</p>
<pre><code>auto I1 = Index("I1",2);
auto I2 = Index("I2",2);
auto R1 = Index("R1",2);
auto R2 = Index("R2",2);
auto S1 = Index("S1",2);
auto S2 = Index("S2",2);
auto A = randomTensor(R1,R2,I1,I2);
auto B = randomTensor(S1,S2,prime(I1),prime(I2));
auto del1 = delta(I1,prime(I1),prime(I1,2));
auto del2 = delta(I2,prime(I2),prime(I2,2));
auto C = (A*del1*del2*B).noprime();
PrintData(C);
</code></pre>
<p>where here M=N=2, just for simplicity. For arbitrary M and N, it shouldn't be too hard to do it in terms of vectors of Indices and <code>delta</code> tensors.</p>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1407/computing-the-partial-kronecker-product-of-two-itensors?show=1408#a1408Fri, 05 Apr 2019 14:35:57 +0000Answered: Non-Uniform Density of Up States in First Neighbor Tight-Binding Model
http://itensor.org/support/1403/uniform-density-states-first-neighbor-tight-binding-model?show=1404#a1404
<p>Hi rmagaldi,<br>
Thanks for the question. So I think I may have figured out what's going wrong. The good news is that it does not appear to be the DMRG optimization itself, but the definition of the Hamiltonian.</p>
<p>What I did to test this is to observe that your system is just a periodic ring, so one can make the Hamiltonian in a simpler way:</p>
<pre><code>for(int j = 1; j <= N-1; j+=1)
{
ampo += -t,"Cdagup",j,"Cup",j+1;
ampo += -t,"Cdagup",j+1,"Cup",j;
ampo += -t,"Cdagdn",j,"Cdn",j+1;
ampo += -t,"Cdagdn",j+1,"Cdn",j;
}
ampo += +t,"Cdagup",1,"Cup",N;
ampo += +t,"Cdagup",N,"Cup",1;
ampo += +t,"Cdagdn",1,"Cdn",N;
ampo += +t,"Cdagdn",N,"Cdn",1;
</code></pre>
<p>This is just a nearest-neighbor hopping with an additional "long bond" connecting site 1 to site N. Note that the coupling has the opposite sign for the long bond. Choosing this sign gives a uniform density, regardless of the initial state. Choosing a -t coupling gives the behavior you reported.</p>
<p>So probably if one works through this carefully, the reason the +t is the correct coupling is because really one should think of the long bond as going from N to 1 with a -t, which is equivalent to going from 1 to N with a +t, due to the fact that C and Cdagger anti commute.</p>
<p>Hope that helps!</p>
<p>Miles</p>
http://itensor.org/support/1403/uniform-density-states-first-neighbor-tight-binding-model?show=1404#a1404Tue, 02 Apr 2019 22:05:19 +0000Using ITensor for computational not-quantum chemistry
http://itensor.org/support/1401/using-itensor-for-computational-not-quantum-chemistry
<p>This is an amazing piece of code and I'm delighted to have found it! I think it might be useful for an application I am working on. The goal is to solve the chemical master equation</p>
<p>$$<br>
\frac{\mathrm{d} P}{\mathrm{d} t} =\mathbf{A} P<br>
$$</p>
<p>where @@\mathbf{A}@@ is a matrix of connections and @@P@@ represents the vector of probabilities of being in each state. (See <a rel="nofollow" href="https://en.wikipedia.org/wiki/Master_equation">this Wikipedia page</a> for more details on master equations.) I got the idea for solving the master equation using the tensor formalism from <a rel="nofollow" href="http://dx.doi.org/10.1016/j.jcp.2017.04.007">this paper</a> and <a rel="nofollow" href="http://dx.doi.org/10.1016/j.jcp.2016.03.025">its companion paper</a>. Our system is similar in form to the CO oxidation model in the papers, but it has different chemical species and more complicated reactions.</p>
<p>To model this, I <em>think</em> I can use ITensor by applying an MPO (which may act on more than two sites!) to an MPS repeatedly and, at each timestep, measure the properties we are interested in (say, total number of atoms/molecules of each type). I haven't seen an example of this being done in ITensor yet, but <a rel="nofollow" href="https://en.wikipedia.org/wiki/Creation_and_annihilation_operators#Creation_and_annihilation_operators_for_reaction-diffusion_equations">this Wikipedia page</a> suggests that a reaction-diffusion system could be modeled as a time-evolving set of non-quantum states.</p>
<p><strong>Has anyone done something like this in ITensor before? Are there any fundamental problems with using the library this way, particularly since this isn't exactly the canonical use case?</strong></p>
<p>I also understand that <code>toExpH</code> doesn't work for MPOs that operate on more than two sites -- which, sadly, mine probably does. <strong>Barring the obvious numerical instabilities, is there any reason why I couldn't do something like an explicit Euler integration instead of using the matrix exponential form to solve the above equation?</strong></p>
http://itensor.org/support/1401/using-itensor-for-computational-not-quantum-chemistryMon, 01 Apr 2019 21:58:13 +0000Answered: Time evolution with IQTensors is slower than ITensors
http://itensor.org/support/1397/time-evolution-with-iqtensors-is-slower-than-itensors?show=1399#a1399
<p>Hi, thanks for raising this issue. So this is actually expected when tensors are sufficiently small. In that case the non-trivial overhead of book keeping the QNs can have a noticeable effect. Could you try making the MPS bond dimension bigger and see if the difference persists?</p>
<p>Thanks,<br>
Miles </p>
http://itensor.org/support/1397/time-evolution-with-iqtensors-is-slower-than-itensors?show=1399#a1399Sun, 31 Mar 2019 13:57:49 +0000Answered: Conserving difference of two bosonic species
http://itensor.org/support/1391/conserving-difference-of-two-bosonic-species?show=1392#a1392
<p>Hi, thanks for the question. So in version 2 (we've made this easier in the soon to be released version 3) the way the QNs work is that they are globally defined throughout your code. They are ordered tuples of pairs of integers.</p>
<p>The design you'll want to then do is define your QNs like this (all of them):</p>
<p>QN({na,1},{nb,1},{sz,1})</p>
<p>where na, nb, and sz are integers that are the number of A bosons; number of B bosons; and Sz quantum number of that site. If a site consists purely of one type of boson (say "A"), that's ok: just set nb=0. Similar for if a site carries no spin, just set sz=0. </p>
<p>If your A and B bosons reside on different sites, I'd recommend making two different site types, which could be named ABosonSite and BBosonSite, say. Then you can write code similar to that for BasicSiteSet (see line 376 of itensor/mps/siteset.h) except have the for loop switch the site type between odd and even sites. </p>
<p>If you want to post your code here I'd be happy to take a look.</p>
<p>An alternative is that you could go ahead and switch to version 3. To do this, just do "git checkout rc3" and then "make clean" and "make" from the top level of the ITensor folder. The rc3 branch means "release candidate 3". Howver, I should caution that one of the last parts of ITensor we're taking a hard look at before we finally release version 3 happens to be site sets! We probably won't change them too much, but there's a chance we might. </p>
<p>The advantage of version 3, though, is the new QN design. In that version, each quantum number within a QN object has a name string that goes with it, so for a case like yours you can just make QN's like QN({"A",na,1}) for A sites and QN({"B",nb,1}) for B sites and they will mix together just fine.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/1391/conserving-difference-of-two-bosonic-species?show=1392#a1392Fri, 29 Mar 2019 02:01:05 +0000Answered: Set the element in a sparse matrix
http://itensor.org/support/1384/set-the-element-in-a-sparse-matrix?show=1387#a1387
<p>It looks like right now <code>.set()</code> is not defined for diagonal storage, i.e.:</p>
<pre><code>auto i = Index("i",2);
auto j = Index("j",2);
auto A = delta(i,j);
A.set(i(1),j(1),2.0);
</code></pre>
<p>throws an error:</p>
<pre><code>terminate called after throwing an instance of 'itensor::ITError'
what(): doTask not defined for task SetElt and storage type DiagReal
</code></pre>
<p>From what I can tell, right now the only methods for actually modifying ITensors with Diag storage are <code>.apply()</code> and <code>.fill()</code>, so for example:</p>
<pre><code>A.apply([](Real x){ return 2*x; });
</code></pre>
<p>would double all of the values of the diagonals, and</p>
<pre><code>A.fill(3.);
</code></pre>
<p>would set all of the values to 3.</p>
<p>For more complicated element setting, you may have to store the original diagonal values (for example in a vector), manipulate them, and then use them in a <code>diagTensor</code> constructor to make a new ITensor with the diagonal values you want.</p>
<p>I think it would be good for us to define <code>.set()</code> for Diag/QDiag storage, and have it throw an error if a user tries to set an off-diagonal element. But I think many current cases can be covered by the current functionality, and worse case would be making a new diagTensor.</p>
<p>What is your particular use-case? Note that there is also a new <code>iterInds</code> function (<a rel="nofollow" href="http://www.itensor.org/support/1361/iterating-over-non-zero-elements-of-a-sparse-itensor)">http://www.itensor.org/support/1361/iterating-over-non-zero-elements-of-a-sparse-itensor)</a> that can help you visit all of the elements of an ITensor, in case that helps.</p>
<p>Cheers,<br>
Matt</p>
http://itensor.org/support/1384/set-the-element-in-a-sparse-matrix?show=1387#a1387Wed, 27 Mar 2019 14:54:06 +0000Answered: How to obtain eigenvalue of two-site reduced density matrix
http://itensor.org/support/1385/how-to-obtain-eigenvalue-of-two-site-reduced-density-matrix?show=1386#a1386
<p>Hi JR, <br>
The diagHermitian function should be what you need. You can read more about it on this page:<br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv2&page=classes/decomp">http://itensor.org/docs.cgi?vers=cppv2&page=classes/decomp</a></p>
http://itensor.org/support/1385/how-to-obtain-eigenvalue-of-two-site-reduced-density-matrix?show=1386#a1386Wed, 27 Mar 2019 14:15:38 +0000Answered: Use vector of doubles in Args
http://itensor.org/support/1380/use-vector-of-doubles-in-args?show=1381#a1381
<p>Hi jsf,<br>
While that's a clever way to store and retrieve values, the Args system is really intended to pass named arguments to functions, not as a database to hold arbitrary types. If we made it possible to do so, it would cause an unacceptably high performance penalty to most of the functions using Args and go beyond the intended purpose of that system.</p>
<p>Instead, you can already read and write most types used in ITensor, including standard library types such as std::vector, to files using the read and write functions provided with ITensor. Here is some example code showing how.</p>
<p>Writing objects to a file "myfile.dat":</p>
<pre><code>auto v = vector<int>(4);
v[0] = 1;
v[1] = 3;
v[2] = 5;
v[3] = 9;
auto i = Index("i",2);
auto T = randomTensor(i);
std::ofstream f("myfile.dat",std::ios::binary);
write(f,v);
write(f,i);
write(f,T);
f.close();
</code></pre>
<p>Reading the data back in from the file:</p>
<pre><code>std::ifstream f("myfile.dat",std::ios::binary);
vector<int> v;
read(f,v);
Index i;
read(f,i);
ITensor T;
read(f,T);
f.close();
Print(v.size());
Print(v[0]);
Print(v[1]);
Print(v[2]);
Print(v[3]);
Print(T);
</code></pre>
http://itensor.org/support/1380/use-vector-of-doubles-in-args?show=1381#a1381Mon, 25 Mar 2019 17:38:52 +0000Answered: Iterating over non-zero elements of a sparse ITensor
http://itensor.org/support/1361/iterating-over-non-zero-elements-of-a-sparse-itensor?show=1369#a1369
<p>Good suggestion, thanks. I think this is a feature we should definitely have, so I just added it! (You'll have to pull the latest version of ITensor to get it.)</p>
<p>What I added is a function called <code>iterInds</code> which you in a range-based for loop, which gives the behavior you asked about. </p>
<p>Here is a sample code using it:</p>
<pre><code>auto i = Index("i",2);
auto j = Index("j",3);
auto k = Index("k",4);
auto is = IndexSet(i,j,k);
auto T = randomTensor(i,j,k);
for(auto it : iterInds(T))
{
Print(it[0]);
Print(it[1]);
Print(it[2]);
Print(T.real(it));
println();
}
PrintData(T);
</code></pre>
http://itensor.org/support/1361/iterating-over-non-zero-elements-of-a-sparse-itensor?show=1369#a1369Tue, 12 Mar 2019 05:25:30 +0000