ITensor Support Q&A - Recent questions and answers
http://itensor.org/support/qa
Powered by Question2AnswerAnswered: [Julia] What's the meaning of "overload" on calling of an custom Hilbert space external file?
http://itensor.org/support/3039/whats-meaning-overload-calling-custom-hilbert-space-external?show=3043#a3043
<p>Working in my example i see another kind of error. I'm using include("S=3/2.jl") in begining of my code and works well.</p>
<p>After defining an site<em>type function, the call @show(site) returns an correct array of Index Types "S=1" and "S=3/2". Now i'm getting an error in definition of my initial wavefunction with QN conservation. My codes definition of site</em>type and state folows : </p>
<pre><code>let
N = 64
function sites_type(n::Int)
if iseven(n) == true
return "S=3/2"
end
if iseven(n) == false
return "S=1"
end
end
sites = siteinds(n->sites_type(n), N; conserve_qns=true)
@show(sites)
J_1 = 1.0 #Same spin couplins
J_2 = 1.0 # \alpha_c = J_2/J_1 \approx 0.7621
ampo = AutoMPO()
# s-s interactions with coupling J_1
for j=1:4:N-4
ampo += 0.5*J_1,"S+",j,"S-",j+2
ampo += 0.5*J_1,"S-",j,"S+",j+2
ampo += J_1,"Sz",j,"Sz",j+2
end
# S-s interations with Coupling J_2
for j=2:4:N-4
ampo += 0.5*J_2,"S+",j,"S-",j+1
ampo += 0.5*J_2,"S-",j,"S+",j+1
ampo += J_2,"Sz",j,"Sz",j+1
end
# S-S interations with coupling J_1
for j=2:4:N-4
ampo += 0.5*J_1,"S+",j,"S-",j+2
ampo += 0.5*J_1,"S-",j,"S+",j+2
ampo += J_1,"Sz",j,"Sz",j+2
end
# S-s interations with coupling J_2
for j=4:4:N-4
ampo += 0.5*J_2,"S+",j,"S-",j+1
ampo += 0.5*J_2,"S-",j,"S+",j+1
ampo += J_2,"Sz",j,"Sz",j+1
end
H = MPO(ampo,sites)
#Definitions of Sz_tot =0 and Sz_tot=1 wave functions
state0, state1 = [], []
for n =1:N/4
push!(state0, "Z0", "Up", "Z0", "Dn")
end
push!(state1, "Up", "Up", "Z0", "Dn")
for n =2:N/4
push!(state1, "Z0", "Up", "Z0", "Dn")
end
psi0 = productMPS(sites,state0)
psi1 = productMPS(sites,state1)
</code></pre>
<p>I'm getting an Error in psi0 "ArgumentError : Overload of "state" function not found for Index tags "S=3/2,Site,n=2". </p>
http://itensor.org/support/3039/whats-meaning-overload-calling-custom-hilbert-space-external?show=3043#a3043Tue, 11 May 2021 12:44:32 +0000Transfer Matrix with iMPS (a further question)
http://itensor.org/support/3042/transfer-matrix-with-imps-a-further-question
<p>Dear ITensor,</p>
<p>I posted a question about this previously, but I thought I would create a new one since it was some time ago and I've made some progress. Please let me know if it would be better to just extend the original question.</p>
<p>I'm trying to calculate the fidelity per unit cell of an iMPS using a transfer matrix. From what I understand, the result of your idmrg code should be multiplied by psi(0) (at psi(1)) to give the orthogonalised wavefunction. I've implemented a class to use with arnoldi, which has the product function shown below. I've been testing it with a simple transverse Ising model. The MPSs psi1 and psi2 are stored in the class, which modifies them to have matching site indices and primes the links of psi2.</p>
<pre><code>void TMatrix::product(ITensor &other, ITensor &result) {
result = ITensor(other);
result = result * dag(psi1(0));
result = result * psi2(0);
for (int i = 1; i <= length(psi1); i++) {
result = result * dag(psi1(i));
result = result * psi2(i);
}
// "Fix" the indices (probably a bad idea). This runs with QNs but gets the wrong result.
//result = result.dag();
//result = result.conj();
// This gets nearly the correct result (using the PseudoInvert function from idmrg.h)
//auto z1 = psi1(0);
//auto z2 = dag(psi2(0));
//z1.apply(PseudoInvert(0));
//z2.apply(PseudoInvert(0));
//result *= z1;
//result *= z2;
}
</code></pre>
<p>However, this results in runtime errors with QN conservation enabled, as psi1(0) has both indices pointing "out" (as expected since it's the centre of an svd), which results in the leftmost link being flipped. It still doesn't get correct results with QNs disabled.</p>
<p>I tried a couple of things (commented out above): the first is to "fix" the link index so the multiplication works. However this produces incorrect results, out by a factor of 1/2. The other idea was to apply the inverse of psi(0) at the end of the product function, which results in an acceptable contraction of the indices and produces something very close to the correct result. I don't understand why this is the case, however. </p>
<p>I've studied various other questions here as well as the code in idmrg.h (which I understand only partially), but I don't seem to be able to get any further. Do you have any suggestions?</p>
<p>Thank you as always for your work on ITensor</p>
http://itensor.org/support/3042/transfer-matrix-with-imps-a-further-questionTue, 11 May 2021 02:16:45 +0000How do we implement custom global symmetries (generalized parity)?
http://itensor.org/support/3037/how-implement-custom-global-symmetries-generalized-parity
<p>I'm trying to write a generalized parity for a double-wire model of Fermions that conserves global number and the parity of the number of fermions in a given wire. Namely the model proposed in <a rel="nofollow" href="https://arxiv.org/pdf/1705.01786.pdf">https://arxiv.org/pdf/1705.01786.pdf</a> (equations 1-3) with the g term set to 0. The model has the usual nearest-neighbor tunneling, a nearest-neighbor potential energy term, and a cooper pair exchance term between two coupled quanutm wires. To implement this, I've mapped the two 1-d chains into a single 1-d chain with odd numbered sites corresponding to chain a and even numbered sites corresponding to chain b. The parity that is conserved is the parity of the number of fermions on one of the chains, say the odd number of sites. So I need to keep track of that parity as well as enforce global number conservation. The number conservation works fine, but the global parity does not. </p>
<p>I've attempted to adapt the Fermion.h file to include this generalized parity. The adapting the fermion.h file is based on some of the comments here, <a rel="nofollow" href="http://www.itensor.org/support/2030/3-component-hubbard-model?show=2030#q2030,">http://www.itensor.org/support/2030/3-component-hubbard-model?show=2030#q2030,</a> for a 3-component Fermi-hubbard model. </p>
<p>Here is my attempt to generalize the fermion.h file names have been changed to avoid an error that was being thrown about redefining things like Fermion and FermionSite. <br>
#pragma once</p>
<pre><code> #include "itensor/mps/siteset.h"
#include "itensor/util/str.h"
namespace itensor {
class FermionSiteAlt;
using FermionOddSitePar = BasicSiteSet<FermionSiteAlt>;
class FermionSiteAlt
{
Index s;
public:
FermionSiteAlt(Index I) : s(I) { }
FermionSiteAlt(Args const& args = Args::global())
{
auto ts = TagSet("Site,Fermion");
auto n = 1;
if(args.defined("SiteNumber"))
{
n = args.getInt("SiteNumber");
ts.addTags("n="+str(n));
}
auto conserveQNs = args.getBool("ConserveQNs",true);
auto conserve_Nf = args.getBool("ConserveNf",conserveQNs);
auto conserve_Pfodd = args.getBool("ConservePfodd",false);
auto oddevenupdown = args.getBool("OddEvenUpDown",false);
if(not conserveQNs)
{
s = Index(2,ts);
}
else if(not oddevenupdown) //usual case
{
if(conserve_Nf) //usual case
{
if(not conserve_Pfodd) //usual case
{
s = Index(QN({"Nf",0,-1}),1,
QN({"Nf",1,-1}),1,Out,ts);
}
else // conserve_Pfodd not usual case
{
if( n%2==1 ) {
s = Index(QN({"Nf",0,-1}),1,QN({"Pfodd",0,-2}),1,
QN({"Nf",1,-1}),1,QN({"Pfodd",1,-2}),1,
Out,ts);
}
if( n%2==0 ) {
s = Index(QN({"Nf",0,-1}),1,QN({"Pfodd",0,-2}),1,
QN({"Nf",1,-1}),1,QN({"Pfodd",0,-2}),1,
Out,ts);
}
}
}
else
{
s = Index(QN({"Pf",0,-2}),1,
QN({"Pf",1,-2}),1,Out,ts);
}
}
else
{
auto q_emp = QN({"Sz",0},{"Nf",0,-1});
QN q_occ;
if(n%2==1) q_occ = QN({"Sz",+1},{"Nf",1,-1});
else q_occ = QN({"Sz",-1},{"Nf",1,-1});
s = Index(q_emp,1,
q_occ,1,Out,ts);
}
}
Index
index() const { return s; }
IndexVal
state(std::string const& state)
{
if(state == "Emp" || state == "0")
{
return s(1);
}
else
if(state == "Occ" || state == "1")
{
return s(2);
}
else
{
throw ITError("State " + state + " not recognized");
}
return IndexVal{};
}
ITensor
op(std::string const& opname,
Args const& args) const
{
auto sP = prime(s);
auto Emp = s(1);
auto EmpP = sP(1);
auto Occ = s(2);
auto OccP = sP(2);
auto Op = ITensor(dag(s),sP);
if(opname == "N" || opname == "n")
{
Op.set(Occ,OccP,1);
}
else
if(opname == "C")
{
Op.set(Occ,EmpP,1);
}
else
if(opname == "Cdag")
{
Op.set(Emp,OccP,1);
}
else
if(opname == "A")
{
Op.set(Occ,EmpP,1);
}
else
if(opname == "Adag")
{
Op.set(Emp,OccP,1);
}
else
if(opname == "F" || opname == "FermiPhase")
{
Op.set(Emp,EmpP,1);
Op.set(Occ,OccP,-1);
}
else
if(opname == "projEmp")
{
Op.set(Emp,EmpP,1);
}
else
if(opname == "projOcc")
{
Op.set(Occ,OccP,1);
}
else
{
throw ITError("Operator \"" + opname + "\" name not recognized");
}
return Op;
}
//
// Deprecated, for backwards compatibility
//
FermionSiteAlt(int n, Args const& args = Args::global())
{
*this = FermionSiteAlt({args,"SiteNumber=",n});
}
};
//
// Deprecated, for backwards compatability
//
// Commented out
//// Rebels don't care about backwards compatability. Burn it down!
// using SpinlessSite = FermionSiteAlt;
// using Spinless = BasicSiteSet<SpinlessSite>;
} //namespace itensor
</code></pre>
<p>Continued in first comment below - character limit prevented posting both sets of code. </p>
http://itensor.org/support/3037/how-implement-custom-global-symmetries-generalized-paritySat, 08 May 2021 20:40:30 +0000Answered: Exited states of Hubbard model
http://itensor.org/support/3032/exited-states-of-hubbard-model?show=3033#a3033
<p>Hi, thanks for the question.</p>
<p>So this is not a bug in ITensor, but just a message telling you about incorrect usage of the code for the case you are doing. Therefore a git pull would not fix the problem; rather you need to use the code differently for your case.</p>
<p>The error message is saying that for the case of a quantum number (QN) conserving calculation, such as the one you are doing, it is not enough to initialize an MPS by just giving the site indices. Additionally, you have to provide a specific product state that you want the MPS to be initialized to, which has a well-defined total QN. </p>
<p>Here are some example codes where QN conservation is used, and you will see that the MPS is always initialized with an <code>InitState</code> object passed to the MPS constructor (<code>psi = MPS(state);</code>).</p>
<p><a rel="nofollow" href="https://github.com/ITensor/ITensor/blob/v3/sample/exthubbard.cc">https://github.com/ITensor/ITensor/blob/v3/sample/exthubbard.cc</a><br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv3&page=formulas/ladder">http://itensor.org/docs.cgi?vers=cppv3&page=formulas/ladder</a></p>
<p>Please let me know if that doens't answer your question or if you have more questions -</p>
<p>Miles</p>
http://itensor.org/support/3032/exited-states-of-hubbard-model?show=3033#a3033Fri, 07 May 2021 21:47:37 +0000Answered: Rotation beween two sites of the lattice, C++
http://itensor.org/support/3029/rotation-beween-two-sites-of-the-lattice-c?show=3031#a3031
<p>Hi Marcin,<br>
Thanks for the question. </p>
<p>First of all, when you say you are stuck in the construction of the rotation itself, which part are you stuck on? It seems like you have figured it out perfectly, namely that you can define a Hermitian ITensor (in this case Sy) and then use expHermitian to exponentiate it to construct your rotation operator. So is your question whether the procedure you are doing to make expSy the right one? Or is your question about applying expSy to an MPS?</p>
<p>If your question is about applying expSy to an MPS, then there are two distinct cases:</p>
<ol>
<li><p>if i and j are nearest-neighbors, such that j = i+1 say, then there is a tutorial about how to apply gates to MPS on neighboring sites here: <a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv3&page=formulas/gate">http://itensor.org/docs.cgi?vers=cppv3&page=formulas/gate</a><br>
Note that this necessarily involves <em>two</em> MPS tensors so it is not sufficient to just get the i'th MPS tensor (I say this since you mentioned psi.Aref(i)).</p></li>
<li><p>if i and j are not neighbors, then to apply a gate onto them you just first move one of the sites (say j) through the MPS using a series of "swap" moves in order to apply a gate, then move j back to its original position. There are various ways to do this, but it's much more technical so please let me know first if this is your situation. (Note that in the Julia version of ITensor this is done automatically for you but we don't have that in the C++ version.)</p></li>
</ol>
<p>Finally, please note that you don't need to call psi.ref unless it is to modify an MPS tensor. If you are just obtaining the MPS tensor to, say, contract it with some other tensor it's better to write psi(i) and this comes with some extra efficiencies.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/3029/rotation-beween-two-sites-of-the-lattice-c?show=3031#a3031Thu, 06 May 2021 19:24:38 +0000readFromFile() for custom mixed SiteSet
http://itensor.org/support/3025/readfromfile-for-custom-mixed-siteset
<p>Dear ITensor Team,</p>
<p>I have a problem with the readFromFile(FileName, sites) function. I am using a custom SiteSet "OpenSystemSite", which is a mixture of bosonic and fermionic sites. <br>
When compiling, the function throws an error</p>
<p>error: no matching function for call to ‘read(std::ifstream&, itensor::OpenSystemSite<itensor::BosonSiteOpen, itensor::ElectronSite>&)’</p>
<p>Reading in the MPS created on this SiteSet seems to work fine.<br>
Is the build-in function readFromFile() just not compatible with a mixed SiteSet or do you have an idea how I could fix this?</p>
<p>Best wishes and thanks for the great work on Itensor!</p>
<p>Luisa</p>
http://itensor.org/support/3025/readfromfile-for-custom-mixed-sitesetWed, 05 May 2021 06:31:37 +0000Answered: [Julia] DMRG simulation for an specific total magnetizagion Sector
http://itensor.org/support/3022/julia-dmrg-simulation-specific-total-magnetizagion-sector?show=3023#a3023
<p>Hi, yes so this is definitely something you can do with ITensor. The short answer is that if you use site indices which contain quantum number (QN) information and if you initialize your initial product state MPS to have a certain well-defined total Sz, then the MPS will remain in that same Sz sector throughout.</p>
<p>The following tutorial goes over this in more detail with an example:<br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=julia&page=getting_started/qn_dmrg">http://itensor.org/docs.cgi?vers=julia&page=getting_started/qn_dmrg</a></p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/3022/julia-dmrg-simulation-specific-total-magnetizagion-sector?show=3023#a3023Tue, 04 May 2021 23:39:22 +0000Answered: Manual construction of 2-sites local MPO
http://itensor.org/support/3016/manual-construction-of-2-sites-local-mpo?show=3017#a3017
<p>Hi Jacopo,<br>
Good question: yes this is a perfect thing to use ITensor for. There are a few different ways you can proceed. I'll outline some and we could chat more in comments below.</p>
<p>One way is to use the AutoMPO system if you MPO can be expressed as a sum of local operators. If so, then this would be the easiest way to construct your MPO.</p>
<p>A more flexible and powerful way is to just make your MPO directly, by forming the individual tensors and setting their elements. Essentially all you have to do is pre-define indices, construct ITensors, then set their elements in the usual way. Let us know if you need help with any of these steps. But a different pattern I have used is to "outer product" smaller tensors together and add them up to make MPO tensors. A specific example of that pattern is shown in the file sample/Heisenberg.h which is included with the C++ ITensor source code under the sample folder. It makes an MPO for the Heisenberg spin chain Hamiltonian. If that pattern is close to what you are looking for, please let me know if you have some questions about how that code works.</p>
<p>Best,<br>
Miles</p>
http://itensor.org/support/3016/manual-construction-of-2-sites-local-mpo?show=3017#a3017Mon, 03 May 2021 20:04:36 +0000Answered: Unitary operators on evolved state
http://itensor.org/support/3007/unitary-operators-on-evolved-state?show=3008#a3008
<p>Hi Amit,<br>
It's hard to immediately guess what it causing the error you're having, but I agree the result shouldn't be as you say.</p>
<p>Here are two possible issues I spotted right away (with #2 being more likely the culprit, though #1 is also important for improving your code):</p>
<ol>
<li><p>we would not recommend that you set elements of ITensors by accessing the storage directly, as you did in your second panel of code inside the function two<em>qubit</em>gate. I'd recommend either using the pattern you used in your "evoH" gate where you initialize an ITensor with a Julia matrix or array, or else setting the elements using the indices of the ITensor such through code like:</p>
<p>tq<em>gate[sind</em>i'=>1,sind<em>i=>1,sind</em>j'=>1,sind_j=>1] = 1.0</p></li>
</ol>
<p>and similar. Accessing the storage is not part of the interface of an ITensor and is error prone and subject to arbitrary future breaking changes.</p>
<ol>
<li>I noticed that in your SVD'd after applying a gate, you only put one of the site indices as the inded to go onto U. But once the MPS develops non-trivial link indices as the result of entanglement generated between sites, you would need to also include the appropriate link or bond index in the list of indices that should go onto U. Otherwise your algorithm will be incorrect and will not be equivalent to the standard "TEBD" algorithm for applying gates to an MPS.</li>
</ol>
<p>Happy to discuss more -</p>
<p>Miles</p>
http://itensor.org/support/3007/unitary-operators-on-evolved-state?show=3008#a3008Wed, 28 Apr 2021 14:49:08 +0000Answered: Create LocalMPO between different states
http://itensor.org/support/2993/create-localmpo-between-different-states?show=3003#a3003
<p>Hi Alex,<br>
Thanks for the question. I think for what you are asking it would be best to just reimplement the LocalMPO type and specialize it for you case. It was written assuming that the states on both sides would be the conjugate of each other. So you can just copy that code and have it take two different MPS as input then generalize the code appropriately. You should also rename the type to something besides LocalMPO to avoid any redefinition issues.</p>
<p>Also, you are probably well aware of this, but the "effective Hamiltonian" or effective operator that will result from using two different states may not be Hermitian. This may be what you want for your algorithm, but just in case you were planning to use it in our DMRG code for some reason, it will assume a Hermitian operator and will give wrong results, hang, or crash if you give it a non-Hermitian operator.</p>
<p>Best,<br>
Miles</p>
http://itensor.org/support/2993/create-localmpo-between-different-states?show=3003#a3003Tue, 27 Apr 2021 19:21:13 +0000Answered: Two-component Bose-Hubbard model
http://itensor.org/support/2973/two-component-bose-hubbard-model?show=3002#a3002
<p>Hi Marcin,<br>
Thanks for the question. First of all, to see a typical example of how to set up an alternating, mixed type of system for the C++ version of ITensor you can refer to this example:</p>
<p><a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv3&page=formulas/gs_holst_polaron">http://itensor.org/docs.cgi?vers=cppv3&page=formulas/gs_holst_polaron</a></p>
<p>which shows how to have your sites alternate between the site types included with ITensor.</p>
<p>But for your case of two kinds of bosons and conserving their particle numbers separately, the easiest approach will be to make a custom site set which slightly generalizes the boson.h one included with ITensor. Here are the steps:</p>
<ol>
<li><p>make a copy of the file itensor/mps/sites/boson.h and call it something like ab_boson.h</p></li>
<li><p>inside that file, rename the type "Boson" everywhere to something else like "ABBoson" so it doesn't conflict with the Boson type included with ITensor</p></li>
<li><p>now modify the constructor for ABBoson around line 55 of that file to instead do this logic:</p>
<p>if(n%2==1)<br>
{<br>
qints[n] = QNInt(QN({"NbA",n}),1);<br>
}<br>
else<br>
{<br>
qints[n] = QNInt(QN({"NbB",n}),1);<br>
}</p></li>
</ol>
<p>and that should be all you need.</p>
<p>Now just use this site set in your code as usual, meaning that you make your site set as:</p>
<p>auto sites = ABBoson(N);</p>
<p>And then it should "just work" in the sense of always conserving the number of A and B bosons separately. I'd encourage you to check that by computing and summing up the total density of bosons on odd (A) versus even (B) sites at various points in your calculation.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/2973/two-component-bose-hubbard-model?show=3002#a3002Tue, 27 Apr 2021 14:20:20 +0000Answered: Constructing an Mixed Unit-cell with three or more spins (Julia Version)
http://itensor.org/support/2997/constructing-mixed-unit-with-three-more-spins-julia-version?show=2998#a2998
<p>Hi, thanks for the question. So I think the main problem is that</p>
<p>isodd(n) ? "S=1/2" : "S=5/2" : "S=1/2"</p>
<p>is not valid Julia syntax. Did you mean</p>
<p>isodd(n) ? "S=1/2" : "S=5/2"</p>
<p>instead?</p>
http://itensor.org/support/2997/constructing-mixed-unit-with-three-more-spins-julia-version?show=2998#a2998Tue, 27 Apr 2021 01:17:00 +0000Answered: Julia script for calculating energy gaps
http://itensor.org/support/2411/julia-script-for-calculating-energy-gaps?show=2992#a2992
<p>There is now a detailed example here</p>
<p><a rel="nofollow" href="http://itensor.org/docs.cgi?vers=julia&page=formulas/excited_dmrg">http://itensor.org/docs.cgi?vers=julia&page=formulas/excited_dmrg</a></p>
http://itensor.org/support/2411/julia-script-for-calculating-energy-gaps?show=2992#a2992Sat, 24 Apr 2021 19:50:10 +0000Answered: Extract/Project IQTensor on a QN subspace
http://itensor.org/support/2879/extract-project-iqtensor-on-a-qn-subspace?show=2990#a2990
<p>To add on to Vittorio's post: as he deduced, @@delta@@ isn't quite the right tool for this case, since it is really meant for making a diagonal tensor with a uniform value along the diagonal (and right now I think only works if all of the diagonal blocks exist, though in principle it could be generalized). Here is a more general approach using some internal and custom made tools:</p>
<pre><code>using ITensors
# Get the range of values of a block
blockrange(i::Index, b::Block) = _blockrange(i, Int(b))
function _blockrange(i::Index, b)
start = 1
for j in 1:b-1
start += ITensors.blockdim(i, j)
end
return start:start+ITensors.blockdim(i, b)-1
end
function blockrange(i::Index, find_qn::QN)
# The block the QN is in
b = ITensors.findfirstblock(x -> qn(x) == find_qn, i)
return blockrange(i, b)
end
space = [QN(("Na",4),("Nb",4)) => 1, QN(("Na",4),("Nb",3)) => 3, QN(("Na",4),("Nb",2)) => 3, QN(("Na",4),("Nb",1)) => 1, QN(("Na",3),("Nb",4)) => 3]
i = Index(space)
# The QN we are projecting into
proj_qn = QN(("Na",4),("Nb",2))
r = blockrange(i, proj_qn)
T = emptyITensor(i', dag(i))
for n in r
T[n, n] = 1.0
end
# Alternative, remove the blocks completely
i2 = Index([proj_qn => length(r)])
T2 = emptyITensor(i2', dag(i))
for n in 1:length(r)
T2[n, n+first(r)-1] = 1.0
end
</code></pre>
<p>It is essentially the same as the @@setelt@@ version but uses indexing instead which should be faster. In addition, this handles an arbitrary QN, where the range of the QN is determined by the @@blockrange@@ function. This would be a good function to have in ITensors.jl to make operations like this easier.</p>
http://itensor.org/support/2879/extract-project-iqtensor-on-a-qn-subspace?show=2990#a2990Fri, 23 Apr 2021 18:23:07 +0000Answered: Correlation function with infinite boundary conditions
http://itensor.org/support/2982/correlation-function-with-infinite-boundary-conditions?show=2989#a2989
<p>Unfortunately we don't have that kind of functionality in a black box form yet, so you would need to develop most of it using basic ITensor building blocks.</p>
<p>I'm working on an infinite MPS package here: <a rel="nofollow" href="https://github.com/mtfishman/ITensorInfiniteMPS.jl">https://github.com/mtfishman/ITensorInfiniteMPS.jl</a> but it is in very early stages and will take some time to get into a usable form. There is some nontrivial functionality implemented like gauging an infinite MPS:</p>
<p><a rel="nofollow" href="https://github.com/mtfishman/ITensorInfiniteMPS.jl/blob/main/examples/infinitemps.jl">https://github.com/mtfishman/ITensorInfiniteMPS.jl/blob/main/examples/infinitemps.jl</a></p>
<p>and finding an infinite MPS approximation for a finite MPS:</p>
<p><a rel="nofollow" href="https://github.com/mtfishman/ITensorInfiniteMPS.jl/blob/main/examples/finite_mps_to_infinite_mps.jl">https://github.com/mtfishman/ITensorInfiniteMPS.jl/blob/main/examples/finite_mps_to_infinite_mps.jl</a></p>
<p>I started working on functionality for summing up infinite Hamiltonian terms with either local Hamiltonians or MPOs, but that functionality isn't quite working yet. </p>
<p>If you interested in trying something quite experimental, you could try contributing to that package. To get an idea of the interface, you can search through the source code, such as:</p>
<p><a rel="nofollow" href="https://github.com/mtfishman/ITensorInfiniteMPS.jl/blob/354b0cb309c0c437fd8cf073cd03207e00183812/src/orthogonalize.jl">https://github.com/mtfishman/ITensorInfiniteMPS.jl/blob/354b0cb309c0c437fd8cf073cd03207e00183812/src/orthogonalize.jl</a></p>
<p>which is code for gauging an infinite MPS,</p>
<p><a rel="nofollow" href="https://github.com/mtfishman/ITensorInfiniteMPS.jl/blob/main/src/infinitemps_approx.jl">https://github.com/mtfishman/ITensorInfiniteMPS.jl/blob/main/src/infinitemps_approx.jl</a></p>
<p>which takes a finite MPS and variationally computes an infinite MPS approximation of the bulk of the system by maximizing the overlap. There is also:</p>
<p><a rel="nofollow" href="https://github.com/mtfishman/ITensorInfiniteMPS.jl/blob/354b0cb309c0c437fd8cf073cd03207e00183812/src/vumps.jl">https://github.com/mtfishman/ITensorInfiniteMPS.jl/blob/354b0cb309c0c437fd8cf073cd03207e00183812/src/vumps.jl</a></p>
<p>which is the beginning implementation of the VUMPS algorithm (<a rel="nofollow" href="https://arxiv.org/abs/1701.07035),">https://arxiv.org/abs/1701.07035),</a> an improved iDMRG algorithm. However, there was something off about how I was summing up the Hamiltonian terms so it isn't quite working yet.</p>
<p>The goal is to provide basic building blocks like the InfiniteMPS/InfiniteMPO types, gauging, getting fixed points of transfer matrices, computing infinite sums of local operators, grabbing slices of an infinite MPS as a finite MPS with some boundary condition, etc. to make implementing algorithms like the one in that paper very simple.</p>
http://itensor.org/support/2982/correlation-function-with-infinite-boundary-conditions?show=2989#a2989Fri, 23 Apr 2021 16:10:59 +0000Answered: AutoMPO for mixture of fermionic and bosonic basis
http://itensor.org/support/2972/autompo-for-mixture-of-fermionic-and-bosonic-basis?show=2974#a2974
<p>Hi Chia-min, good question. Yes as long as you define an “F” operator for both types of sites it will work. Though please test on some small systems where you have independent or exact results, or by computing matrix elements of your Hamiltonian between various product state MPS. </p>
<p>Best regards,<br>
Miles </p>
http://itensor.org/support/2972/autompo-for-mixture-of-fermionic-and-bosonic-basis?show=2974#a2974Mon, 19 Apr 2021 13:41:33 +0000How to create and add MPS
http://itensor.org/support/2968/how-to-create-and-add-mps
<p>Hello there,</p>
<p>Sorry for the newbie question (and if that has been answered elsewhere but I haven't found approaching solutions) but here it is:</p>
<p>I want to create 2 MPS in Julia and add them. The first question is that I would like to customise the core MPS. As such, my first and last core MPS are different from the others in the indices they hold. Is there a way to do that ? I.e. do I have to create a MPS with say N sites and then customise one by one like MPS<a rel="nofollow" href="https://arxiv.org/pdf/2005.04351.pdf">1</a> = CustomTensor1; MPS[2] = CustomTensor2, etc... ? Then, I am not sure how would ITensor resolve the indexing then.</p>
<p>The other question is how to change the link dimension ? I heard about <code>pluss*</code> but not sure it was for Julia.</p>
<p>Finally, if I solve question 1 I assume I'd be able to sum them together. However, is that sum equivalent to the operations described in that <a rel="nofollow" href="https://arxiv.org/pdf/2005.04351.pdf">article</a> (bottom of page 7, top page 8) ? </p>
<p>Thanks for your help, that is really appreciated.</p>
<p>Kind regards,</p>
<p>Roland</p>
http://itensor.org/support/2968/how-to-create-and-add-mpsThu, 15 Apr 2021 14:01:58 +0000Answered: Periodic MPO
http://itensor.org/support/2953/periodic-mpo?show=2966#a2966
<p>Continueing from discussion above:</p>
<p>I don't understand all of the notation there, but indeed stat mech models are a bit outside the scope of AutoMPO. However, my understanding was that every MPO/operator should be expandable in terms of a sum of tensor products of single-site operators (for example for a qubit or spin-1/2 system, tensor products of pauli operators form a complete basis), so in principle if you could expand the MPO in a complete operator basis and then put it into AutoMPO. Maybe that is only the case for Hermitian operators and your example isn't Hermitian?</p>
<p>However, if you already have the analytic form of the MPO tensors, to make an MPO periodic really just requires making the first and last dangling indices equal. For example:</p>
<pre><code> function make_mpo_tensor(s, l, r)
T = ITensor(s, s', l, r)
# Code to set the elements of the MPO tensor goes here
end
# N site system
N = 4
l = [Index(3, "l$n") for n in 1:N]
s = [Index(2, "s$n") for n in 1:N]
M = MPO(N)
M[1] = make_mpo_tensor(s[1], l[N], l[1])
for n in 2:N
M[n] = make_mpo_tensor(s[n], l[n-1], l[n])
end
</code></pre>
<p>For smaller systems, you can contract them all together with <code>prod(M)</code> or <code>contract(M...)</code> to see that you are only left with site indices and it should be the exponentially large operator you are looking for.</p>
<p>Note that built-in ITensor functions like <code>inner(psi, M, psi)</code> won't generally work with these kinds of MPOs (but those shouldn't be hard to write on your own). You can also manually turn this kind of periodic MPO into an open boundary MPO with a larger bond dimension by running the extra link index through the system (essentially by contracting with an identity MPO that has link indices that are the same as the link indices at the edges of the system).</p>
http://itensor.org/support/2953/periodic-mpo?show=2966#a2966Wed, 14 Apr 2021 15:21:33 +0000Answered: distinguish complex or real ITensor in compiling
http://itensor.org/support/2962/distinguish-complex-or-real-itensor-in-compiling?show=2964#a2964
<p>Hi Chiamin,<br>
It's a good question but no, there is not a way at compile time to determine the element type, since it is handled dynamically in the way ITensor works.</p>
<p>What I would recommend doing inside your printing function is getting the element using eltC, which will always succeed. Then you can either print that number (call it "z") and just observe in the print out that it has a zero imaginary part, or you can use the functions std::imag(z) and std::real(z) to see if the absolute value of imaginary part is zero (or below some small threshold) and if so, only print the real part.</p>
<p>If you want to do the same for a more general kind of tensor, note that there are functions <code>isReal(T)</code> and <code>isComplex(T)</code> you can call on an ITensor <code>T</code> to see if it has purely real elements or has complex elements: <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></p>
<p>Best,<br>
Miles</p>
http://itensor.org/support/2962/distinguish-complex-or-real-itensor-in-compiling?show=2964#a2964Wed, 14 Apr 2021 14:20:31 +0000Answered: Calculating fidelity with iMPS
http://itensor.org/support/2931/calculating-fidelity-with-imps?show=2961#a2961
<p>The short answer is that in that equation, <code>E</code> is the dominant eigenvector of the transfer matrix. When you write down the overlap of an infinite MPS in canonical form with itself, it reduces to repeated unit cells of the transfer matrix. A helpful place to look to understand this is Section 5 of: <a rel="nofollow" href="https://arxiv.org/pdf/1306.2164.pdf.">https://arxiv.org/pdf/1306.2164.pdf.</a> So you would have to transform the MPS that is output from iDMRG into canonical form, and then use the canonical form MPS to compute the dominant eigenvector of the transfer matrix. Infinite MPS techniques are generally more technical and subtle than finite MPS techniques. Have you tried using finite MPS techniques first, and what limitations did you see?</p>
<p>We are working on an infinite MPS package in the Julia version which would make performing calculations like this easier (<a rel="nofollow" href="https://github.com/mtfishman/ITensorInfiniteMPS.jl)">https://github.com/mtfishman/ITensorInfiniteMPS.jl)</a> but it is not quite ready for general usage yet, I'm hoping to have some basic functionality like what you are asking for ready in the next month or so.</p>
http://itensor.org/support/2931/calculating-fidelity-with-imps?show=2961#a2961Wed, 14 Apr 2021 12:58:52 +0000Answered: How to use ITensor to simulate doped spinful Hubbard chain ?
http://itensor.org/support/2950/how-to-use-itensor-to-simulate-doped-spinful-hubbard-chain?show=2952#a2952
<p>Hi,<br>
Here are some comments I hope are helpful:</p>
<p>(1) your Hamiltonian is not Hermitian. This is likely the main reason you are getting inconsistent results. The terms you are missing are these:<br>
ampo += -t, "Cdagup",j+1,"Cup",j;<br>
ampo += -t, "Cdagdn",j+1,"Cdn",j;</p>
<p>(2) you may also be getting different results each time because you are not doing enough sweeps. For a doped electron systems, sometimes 10 sweeps is just not enough. Please keep increasing the number of sweeps until you see the energy become stable to quite a few digits, say 4 digits of accuracy at least.</p>
<p>(3) to check if the filling is correct, you can compute the total quantum number of your MPS as totalQN(psi) and print that out. From it you will see how many electrons the MPS has (the "Nf" quantum number value) and work out whether you are correctly at the filling you want.</p>
<p>(4) for a small enough system, you can do reliable DMRG of a periodic Hamiltonian just by adding Hamiltonian terms which connect the first and last sites. So like:<br>
ampo += "Cdagup",1,"Cup",N;<br>
ampo += "Cdagup",N,"Cup",1;<br>
ampo += "Cdagdn",1,"Cdn",N;<br>
ampo += "Cdagdn",N,"Cdn",1;</p>
<p>But you do need to do a lot of sweeps to converge on periodic Hamiltonians.</p>
<p>You could consider iDMRG, but our iDMRG code is not officially supported and not too well documented, so you have to know how to carefully use it. It would not be too hard for an entropy calculation, though, so we could discuss that if it's really necessary for your project.</p>
<p>Miles</p>
http://itensor.org/support/2950/how-to-use-itensor-to-simulate-doped-spinful-hubbard-chain?show=2952#a2952Mon, 12 Apr 2021 02:35:46 +0000Answered: Playing with MPS/ ITensors Indexing
http://itensor.org/support/2925/playing-with-mps-itensors-indexing?show=2945#a2945
<p>Hi Arnab,<br>
Thanks for the question. I'll give some brief answers and we can discuss more in comments below.</p>
<p>(1) "I can get the local 2-D tensors (at each) by doing setting the site-index to 1 or 2." This is not correct unless the MPS is a product (unentangled) state. I think what you are trying to do is to obtain the probability of finding some site j to be in the up state versus the down state. So you are looking for these two numbers, call them p<em>up and p</em>dn. These numbers are the diagonal elements of the reduced density matrix for site j. This reduced density matrix can be found by (a) first calling orthogonalize!(T,j) to make site j the orthogonality center of your MPS then (b) by creating the density matrix rho<em>j = T[j] * prime(dag(T[j]),"Site"). This density matrix will be a 2x2 matrix and its diagonal entries will be p</em>up and p_dn. Please check that they add to 1.0.</p>
<p>(2) to obtain the probabilities of up and down states in a different basis, such as the x basis, you can perform a change of basis by acting with a unitary operator on site j. First, make sure your MPS is orthogonalized to site j as in (1a) above. Then obtain the j'th MPS tensor: Aj = T[j]. Now act with the Hadamard gate which will change the basis to the X basis: Ajx = noprime(op("H",sites,j)*Aj). Finally, make the density matrix in the X basis: rhox_j = Ajx * prime(dag(Ajx),"Site"). The diagonal entries of rhox_j will be the probabilities for up and down in the X basis.</p>
<p>Best,<br>
Miles</p>
http://itensor.org/support/2925/playing-with-mps-itensors-indexing?show=2945#a2945Wed, 07 Apr 2021 14:22:15 +0000Answered: Change the size of the Index (the dimension of the vector space that the Index defines) but don't change the id
http://itensor.org/support/2919/change-size-index-dimension-vector-space-index-defines-change?show=2937#a2937
<p>(See discussion above.)</p>
http://itensor.org/support/2919/change-size-index-dimension-vector-space-index-defines-change?show=2937#a2937Wed, 31 Mar 2021 13:53:06 +0000Answered: Discrepancy in correlation functions calculated from ED and DMRG for free fermions
http://itensor.org/support/2935/discrepancy-correlation-functions-calculated-free-fermions?show=2936#a2936
<p>Hi, so I see in your code that you are not including any Jordan-Wigner “F” string operators in your MPS correlation function calculations. This is necessary when computing pairs of operators such as C^dagger and C which have an odd fermion parity. (As a side comment, we are nearly done with a new feature that will remove this requirement, using a technique that makes tensor indices anticommutative, but it’s technical and still in the debugging phase.)</p>
<p>For some resources on how to do this and why, here is a sample code for the C++ version showing how to compute fermion correlators properly for the case of spinless fermions:<br>
<a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv3&page=formulas/spinless_correlator_mps">http://itensor.org/docs.cgi?vers=cppv3&page=formulas/spinless_correlator_mps</a></p>
<p>For a discussion about Jordan-Wigner string and mappings to bosonic operators (all ITensors are bosonic in that sense), see this tutorial page: <a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv3&page=tutorials/fermions">http://itensor.org/docs.cgi?vers=cppv3&page=tutorials/fermions</a></p>
<p>Finally, the approach you are taking of making prod_aux where you combine many MPS tensors together looks like it will have an exponential cost, if I am understanding your code correctly there. This page has an explanation of the approach that is efficient for calculating MPS correlators: <a rel="nofollow" href="http://itensor.org/docs.cgi?vers=cppv3&page=tutorials/correlations">http://itensor.org/docs.cgi?vers=cppv3&page=tutorials/correlations</a> </p>
<p>We can discuss some more if you have questions -</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/2935/discrepancy-correlation-functions-calculated-free-fermions?show=2936#a2936Wed, 31 Mar 2021 13:52:35 +0000Is it normal that the Julia version gives different results on AMD cores from those on intel cores?
http://itensor.org/support/2929/normal-version-gives-different-results-cores-those-intel-cores
<p>Hi,</p>
<p>I noticed that ITensors.jl gives different results on AMD cores from those on intel cores. In some calculations, this small discrepancy may results in very different results in the large volume limit, that is, the RG flow goes to the wrong fixed point.</p>
<p>Sorry I didn't prepare the sample code for this question. I wonder if this is normal or not before doing that. Thanks.</p>
<p>Jin</p>
http://itensor.org/support/2929/normal-version-gives-different-results-cores-those-intel-coresTue, 23 Mar 2021 02:07:54 +0000Answered: Turning a randomITensor into a periodic MPS description
http://itensor.org/support/2882/turning-a-randomitensor-into-a-periodic-mps-description?show=2928#a2928
<p>(See answer above)</p>
http://itensor.org/support/2882/turning-a-randomitensor-into-a-periodic-mps-description?show=2928#a2928Mon, 22 Mar 2021 19:33:47 +0000Answered: Flip in the indices order of Hermitian conjugate of a two qubit quantum state.
http://itensor.org/support/2884/flip-indices-order-hermitian-conjugate-qubit-quantum-state?show=2927#a2927
<p>(See discussion above)</p>
http://itensor.org/support/2884/flip-indices-order-hermitian-conjugate-qubit-quantum-state?show=2927#a2927Mon, 22 Mar 2021 17:26:46 +0000Specific Questions about Constructing MPOs by hand in iDMRG
http://itensor.org/support/2926/specific-questions-about-constructing-mpos-by-hand-in-idmrg
<p>Hi Miles,</p>
<p>I have been recently trying doing some iDMRG simulations (C++v3). It is super nice of you to give sample codes in <a rel="nofollow" href="https://github.com/ITensor/iDMRG.">https://github.com/ITensor/iDMRG.</a> And for others who might be interested, here is a great brief introduction to the algorithm - <a rel="nofollow" href="http://itensor.org/docs.cgi?page=tutorials/iDMRG&vers=cppv2.">http://itensor.org/docs.cgi?page=tutorials/iDMRG&vers=cppv2.</a></p>
<p>But since I don't find any documentations about the implementation of the codes, it is a bit hard for me to modify based on that. And I think you might be I have some naive technical questions regarding how to construct a general Hamiltonian (to be specific, biquadratic Heisenberg model for my purpose).</p>
<p>$$H=\sum_{}\alpha s_i\cdot s_j+\beta(s_i\cdot s_j)^2$$</p>
<p>In the <a rel="nofollow" href="https://github.com/ITensor/iDMRG/blob/master/sample/Heisenberg.h">Heisenberg.h</a>, </p>
<p>Question 1<br>
How is the size for each QN block being decided? (3, 1, 1) in the following code.</p>
<pre><code> auto ts = format("Link,l=%d",l);
links.at(l) = Index(QN({"Sz", 0}),3,
QN({"Sz",-2}),1,
QN({"Sz",+2}),1,
Out,
ts);
</code></pre>
<p>Question 2</p>
<p>I guess the following codes are the ones that deal with the construction of Heisenberg MPO. But could you explain how these columns and rows correspond to the MPO of the Heisenberg MPO? And in general, how do you specify the row and column indices?</p>
<pre><code> W = ITensor(dag(sites_(n)),prime(sites_(n)),row,col);
W += sites_.op("Id",n) * setElt(row(1)) * setElt(col(1)); //ending state
W += sites_.op("Id",n) * setElt(row(2)) * setElt(col(2)); //starting state
W += sites_.op("Sz",n) * setElt(row(3)) * setElt(col(1));
W += sites_.op("Sz",n) * setElt(row(2)) * setElt(col(3)) * Jz_;
W += sites_.op("Sm",n) * setElt(row(4)) * setElt(col(1));
W += sites_.op("Sp",n) * setElt(row(2)) * setElt(col(4)) * J_/2;
W += sites_.op("Sp",n) * setElt(row(5)) * setElt(col(1));
W += sites_.op("Sm",n) * setElt(row(2)) * setElt(col(5)) * J_/2;
</code></pre>
<p>Thank you very much!</p>
<p>Best,<br>
Yi</p>
http://itensor.org/support/2926/specific-questions-about-constructing-mpos-by-hand-in-idmrgMon, 22 Mar 2021 17:04:29 +0000Answered: MPS for MixedSiteSet with different QN conservation on subsystems
http://itensor.org/support/2917/for-mixedsiteset-with-different-conservation-subsystems?show=2923#a2923
<p>For anyone interested, I solved the issue by now by adding "empty" quantum numbers in the file ITensor/itensor/mps/sites/boson.h<br>
Replacing one line <br>
s = Index(1+maxOcc,tags);<br>
with <br>
s = Index(QN(),1+maxOcc,tags); <br>
did the trick.</p>
http://itensor.org/support/2917/for-mixedsiteset-with-different-conservation-subsystems?show=2923#a2923Mon, 22 Mar 2021 09:24:08 +0000Answered: Valence bond - fast implementation (2)
http://itensor.org/support/2911/valence-bond-fast-implementation-2?show=2915#a2915
<p>(See discussion in above comments)</p>
http://itensor.org/support/2911/valence-bond-fast-implementation-2?show=2915#a2915Mon, 15 Mar 2021 18:37:04 +0000Error: Index::write: Index is default initialized
http://itensor.org/support/2902/error-index-write-index-is-default-initialized
<p>Hi,</p>
<p>I am not able to save a state using the WriteToFile function.<br>
The code returns the following error:<br>
<strong>Index::write: Index is default initialized</strong></p>
<p>It's not clear to me why it's happening. <br>
I have a bosonic system of size N with a certain cut-off to the Fock space.<br>
The state is the following:<br>
$$<br>
|\psi\rangle = |0 0 ...\rangle \otimes |\psi<em>0\rangle \otimes |00..0\rangle<br>
$$<br>
where @@|\psi</em>0\rangle@@ is a certain state. Since I am able to compute local quantites and perform a TEBD real time evolution I don't see any issue with the state itself (e.g. mismatch with indices). <br>
Could you help me?</p>
<p>Thank you in advance.<br>
Riccardo</p>
http://itensor.org/support/2902/error-index-write-index-is-default-initializedMon, 08 Mar 2021 17:28:28 +0000Answered: [Julia] Defining custom MPOs using op vs. op!
http://itensor.org/support/2897/julia-defining-custom-mpos-using-op-vs-op?show=2899#a2899
<p>Hi, so there may be a few things going on here causing the errors you are seeing.</p>
<p>First of all, we recommend overloading the functions called either <code>op!</code> or <code>op</code> which take an OpName"String" type argument. In your first code example, you are instead overloading a version of <code>op</code> which takes an AbstractString argument which is an older style we do not encourage users to adopt. So please use the newer style as you did with your later examples.</p>
<p>Also, I just looked at the Electron site code and I do not see it using the older-style <code>op</code> which takes an AbstractString anymore. You can see the latest code here:<br>
<a rel="nofollow" href="https://github.com/ITensor/ITensors.jl/blob/master/src/physics/site_types/electron.jl">https://github.com/ITensor/ITensors.jl/blob/master/src/physics/site_types/electron.jl</a></p>
<p>So perhaps you are looking at an older version of the Electron site code?</p>
<p>Finally, there is an up-to-date example of making a custom site type and custom operators with QNs here: <a rel="nofollow" href="http://itensor.org/docs.cgi?vers=julia&page=formulas/sitetype_qns">http://itensor.org/docs.cgi?vers=julia&page=formulas/sitetype_qns</a></p>
<p>Best,<br>
Miles</p>
http://itensor.org/support/2897/julia-defining-custom-mpos-using-op-vs-op?show=2899#a2899Sun, 07 Mar 2021 19:49:08 +0000Answered: Converting ITensors to matrices in Julia
http://itensor.org/support/2885/converting-itensors-to-matrices-in-julia?show=2887#a2887
<p>The short answer is that you can use the <code>Array</code> or <code>Matrix</code> function:</p>
<pre><code>i = Index(2, "i")
T = randomITensor(i', dag(i))
A = Array(A, i', i)
# Same thing, for an order-2 ITensor
M = Matrix(A, i', i)
</code></pre>
<p>where the indices are used to specify the memory ordering of the Array/Matrix. You can also use the lower case function <code>A = array(A)</code> which uses the current index ordering of the ITensor for the memory ordering of the Array, and makes the Array a view of the ITensor when possible. However, generally I would recommend working with ITensors when possible since it can help minimize mistakes with connecting the wrong indices together.</p>
<p>I'll also point out that we are planning on adding more functions to help with these conversions: <a rel="nofollow" href="https://github.com/ITensor/ITensors.jl/issues/374">https://github.com/ITensor/ITensors.jl/issues/374</a></p>
http://itensor.org/support/2885/converting-itensors-to-matrices-in-julia?show=2887#a2887Mon, 01 Mar 2021 14:31:46 +0000TDVP with time dependent term
http://itensor.org/support/2878/tdvp-with-time-dependent-term
<p>Hi all,<br>
I was trying to use the one center TDVP algorithm to study a system with a time-dependent term that is not part of the Hamiltonian. The overall system evolution is described by <br>
$$\dot y = H y + f(t)$$<br>
where y is the state, H the Hamiltonian, and f(t) is a time dependent vector. How should I modify the original TDVP code to treat this case?</p>
<p>Thanks,<br>
Raffaele</p>
http://itensor.org/support/2878/tdvp-with-time-dependent-termSun, 21 Feb 2021 09:12:32 +0000Answered: Applying local MPOs in Julia
http://itensor.org/support/2869/applying-local-mpos-in-julia?show=2870#a2870
<p>It looks like both approaches work fine. However, in the first approach, you are modifying <code>psi</code>, and you are using the modified version of <code>psi</code> in the second approach. To avoid this, you need to make a copy of the state before modifying it, for example:</p>
<pre><code>using ITensors
N = 6
bond_dim=24
sites = siteinds("S=1/2",N)
psi0 = randomMPS(sites, bond_dim);
psi1 = randomMPS(sites, bond_dim);
j = 3
psi = copy(psi0)
s = siteind(psi,j)
newpsi= 2*op(s,"Sx") * psi[j]
noprime!(newpsi)
psi[j]= newpsi
println("First value is ", inner(psi1, psi))
sample = AutoMPO()
sample += 2,"Sx", j;
Operator= MPO(sample,sites);
println("Second value is ", inner(psi1, Operator, psi0))
</code></pre>
<p>which outputs for me:</p>
<pre><code>First value is -0.14996338790894725
Second value is -0.14996338790894728
</code></pre>
<p>In the original post, in the second approach you are effectively applying the operator <code>2 Sz</code> twice to the original MPS <code>psi</code>.</p>
<p>As I'm sure you know, it is best to use the first approach since it doesn't scale with the number of sites, whereas the second approach uses an MPO that scales with the number of sites.</p>
<p>-Matt</p>
http://itensor.org/support/2869/applying-local-mpos-in-julia?show=2870#a2870Mon, 15 Feb 2021 15:19:50 +0000Answered: Making Initial Product States in 2D
http://itensor.org/support/2848/making-initial-product-states-in-2d?show=2849#a2849
<p>Hi Yi,<br>
So if I understand the code correctly, the problem (not the error but the conceptual problem) is coming from the lines:</p>
<pre><code>psi0.ref(n + m) = ITensor(s1);
psi0.ref(n + m + Ny) = ITensor(s2);
</code></pre>
<p>It seems you are planning to split the two-site singlet tensor "wf" into two pieces and then assign these two pieces, which share a common bond index, to two MPS tensors which are not neighbors of each other, in the sense of the 1D MPS ordering.</p>
<p>In short, the resulting setting of psi0 will not be a valid MPS. The tensors will not have an MPS structure.</p>
<p>I hope that's clear, but a good way to see it is to draw the tensor diagram for your MPS psi0 (putting the tensors along a 1D line, since the DMRG code doesn't know anything about 2D) and then you will see that the common bond between sitees n+m and n+m+Ny is a "long bond" that is connecting across many 1D sites, which is not the form an MPS has by definition.</p>
<p>Ok please let me know if that helps & we can discuss more.</p>
<p>Finally, we had previously discussed an idea of moving the dimers around using swap operators. The reason for the swaps is precisely because the dimers cannot be initially created in the way above: they would have to be placed along the MPS path initially then moved with nearest-neighbor moves. </p>
<p>Also what did you think about the idea of just using a Hamiltonian whose ground state is exactly the desired dimer state? That idea would be the simplest one to try first, assuming it works.</p>
<p>Miles</p>
http://itensor.org/support/2848/making-initial-product-states-in-2d?show=2849#a2849Wed, 10 Feb 2021 14:39:14 +0000Is there a method that gives the quantum number flux of a particular element in an ITensor
http://itensor.org/support/2844/there-method-gives-quantum-number-particular-element-itensor
<p>From this answer</p>
<p><a rel="nofollow" href="http://itensor.org/support/2799/are-there-methods-for-returning-value-for-mps-or-flux-for-mpo">http://itensor.org/support/2799/are-there-methods-for-returning-value-for-mps-or-flux-for-mpo</a></p>
<p>I realized that one can use the "flux" function to get the quantum number flux of an ITensor. However I wonder if there is a method to get the quantum number flux <em>for a particular element</em> in an ITensor?</p>
http://itensor.org/support/2844/there-method-gives-quantum-number-particular-element-itensorSun, 07 Feb 2021 16:11:38 +0000A partial fix of arnoldi
http://itensor.org/support/2843/a-partial-fix-of-arnoldi
<p>Hi Matthew,</p>
<p>The <a rel="nofollow" href="https://github.com/ITensor/ITensor/issues/360">issue#360</a> in <code>arnoldi</code> function is because of an extra multiplication of <code>A</code> in <a rel="nofollow" href="https://github.com/ITensor/ITensor/blob/fb83fde4a07f2122cf56f9a79f8e8ec01c7cad18/itensor/iterativesolvers.h#L809">the deflation</a>.</p>
<p>The current (incorrect) <code>arnoldi</code> calculates instead the first eigenvalues of <code>A</code> and <code>A-A^2</code>. That's why in <a rel="nofollow" href="https://github.com/ITensor/ITensor/issues/360">issue#360</a> the two eigenvectors are identical and the eigenvalues <br>
<code>lambda0 = (0.598975,0)
lambda1 = (0.240204,0)</code><br>
satisfy <code>lambda1 = lambda0 - lambda0^2</code>.</p>
<p>A minor pull request has been submitted <a rel="nofollow" href="https://github.com/ITensor/ITensor/pull/382">here</a>.</p>
<p>However, even after this fix the <code>arnoldi</code> function can only deal with Hermitian operator. Because the current deflation process cannot project to the correct subspace if the previously calculated eigenvectors are not orthogonal.</p>
<p>Ce</p>
http://itensor.org/support/2843/a-partial-fix-of-arnoldiSun, 07 Feb 2021 03:13:35 +0000initialize an ITensor from allocated memory
http://itensor.org/support/2842/initialize-an-itensor-from-allocated-memory
<p>Hi, </p>
<p>Is there any way to create an ITensor "in place" from some already allocated memory?</p>
<p>For example</p>
<pre><code>const int nx = 10;
const int ny = 10;
double* arr = new double[nx * ny] ;
Index i(nx);
Index j(ny);
ITensor A(i, j); //the storage is not yet initialized.
</code></pre>
<p>Currently I only know how to copy this allocated memory to the data vector of A as following</p>
<pre><code>vector_no_init<double>& dvec = (*((ITWrap<Dense<double>>*) & (*A.store()))).d.store;
dvec.assign(arr, arr + nx*ny);
</code></pre>
<p>What I'd like to do is to "steal" the allocated memory from <code>arr</code> and use that as the internal data vector of <code>A</code>. Although <code>memcpy</code> is in general very fast, sometimes we still want to avoid this overhead in case it is a huge <code>for</code> loop.</p>
<p>There's <a rel="nofollow" href="https://stackoverflow.com/questions/21917529/is-it-possible-to-initialize-stdvector-over-already-allocated-memory">some instruction</a> on how to steal the memory by overloading the allocator. But the data vector's allocator has already been overloaded as in the definition of <a rel="nofollow" href="https://github.com/ITensor/ITensor/blob/fb83fde4a07f2122cf56f9a79f8e8ec01c7cad18/itensor/util/vector_no_init.h#L24">vector no init</a>. </p>
<p>Do you have any idea how to combine the two overloaded versions of allocator, s.t. it can work as described above?</p>
<p>Ce</p>
http://itensor.org/support/2842/initialize-an-itensor-from-allocated-memorySun, 07 Feb 2021 02:51:04 +0000Answered: Canonical MPS representation given an initial state in Julia
http://itensor.org/support/2820/canonical-mps-representation-given-an-initial-state-julia?show=2836#a2836
<p>Is this what you are looking for?</p>
<pre><code>using ITensors
N = 4
s = siteinds("S=1/2", N)
A = randomITensor(s...)
psi = MPS(A, s; cutoff = 1e-10)
@show maxlinkdim(psi)
@show isapprox(A, prod(psi))
</code></pre>
<p>Notice that <code>prod</code> is a general Julia function for multiplying a collection together, so in the case of an MPS it contracts all of the tensors together into a single ITensor to reproduce the (approximation) of the original state. You can also set a maximum dimension with the keyword argument <code>maxdim</code>.</p>
<p>-Matt</p>
http://itensor.org/support/2820/canonical-mps-representation-given-an-initial-state-julia?show=2836#a2836Fri, 05 Feb 2021 18:10:00 +0000Answered: Matrix element of (tensor products of) Pauli operators in Julia
http://itensor.org/support/2824/matrix-element-tensor-products-of-pauli-operators-in-julia?show=2825#a2825
<p>Hi Arnab, yes this is a task that MPS (and ITensor) is perfectly suited for.</p>
<p>The simplest way to do this is to:<br>
1. choose a target string i1, i2, i3, that you want to compute (i.e. fix the i’s)<br>
2. apply the X^i_n operators to the MPS psi. Since these are single-site operators they can be applied very quickly and efficiently (even in parallel if you want to go there) by just multiplying each MPS by X on its physical index. In ITensor, you obtain the X operator for that site, use the * operator to contract it with the MPS, then call <code>noprime</code> to set the site’s prime level back to 0. Of course for sites where you act with the identity, you can just skip over such sites.<br>
3. finally take the resulting MPS, calling it Xpsi, say, then call <code>inner(phi,Xpsi)</code> to obtain the overlap of the modified psi with phi. </p>
<p>Then you can repeat this for other i-strings. </p>
<p>Finally, if you are planning to obtain a large number, or all amplitudes this way, there should be a way to organize them where say you reuse substrings, i.e. overlap by hand the modified psi tensors with phi tensors and then attach the next ones in both combinations and so on. It would take a bit of thought to see how advantage there would be in doing this (because ultimately you’d still have to make exponentially many such “substring partial overlap” tensors anyway). </p>
<p>Let me know if any of those steps aren’t clear. </p>
<p>Oh also we have a new framework precisely for making it easier to apply various operators to MPS, but it’s not totally well documented yet. Here is a sample code file showing it off:</p>
<p><a rel="nofollow" href="https://github.com/ITensor/ITensors.jl/blob/master/examples/gate_evolution/quantum_simulator.jl">https://github.com/ITensor/ITensors.jl/blob/master/examples/gate_evolution/quantum_simulator.jl</a></p>
<p>But it’s overkill just for your case of single-site operators which you can definitely do with the usual ITensor interface.</p>
<p>Best,<br>
Miles</p>
http://itensor.org/support/2824/matrix-element-tensor-products-of-pauli-operators-in-julia?show=2825#a2825Thu, 04 Feb 2021 23:06:49 +0000[Julia] Largest truncation error in DMRG output
http://itensor.org/support/2818/julia-largest-truncation-error-in-dmrg-output
<p>Hi,</p>
<p>I've been using the julia version of ITensor lately, and I noticed that calling DMRG by default does not print any information regarding the maximum truncation error for each sweep, unlike the C++ version. I've searched the documentation but could not find anything related to the truncation error. Is there some way to turn this feature on? Or is it just not implemented yet?</p>
<p>Best,</p>
<p>Rafael</p>
http://itensor.org/support/2818/julia-largest-truncation-error-in-dmrg-outputTue, 02 Feb 2021 23:59:38 +0000Answered: [Julia] QN Block Sparse ITensor gives wrong results for multiplying the delta tensor
http://itensor.org/support/2814/block-sparse-itensor-wrong-results-multiplying-delta-tensor?show=2816#a2816
<p>This was indeed a bug in the low level contraction code for contracting block sparse tensors. I've fixed it here: <a rel="nofollow" href="https://github.com/ITensor/NDTensors.jl/pull/64">https://github.com/ITensor/NDTensors.jl/pull/64</a> . The fix will be available in the next ITensors release (v0.1.38), it should be available later today.</p>
http://itensor.org/support/2814/block-sparse-itensor-wrong-results-multiplying-delta-tensor?show=2816#a2816Tue, 02 Feb 2021 17:54:56 +0000Answered: Computational cost of ITensor permute method
http://itensor.org/support/2810/computational-cost-of-itensor-permute-method?show=2811#a2811
<p>Hi Chia-Min,<br>
Good question. It really does permute all of the data, so the cost is proportional to the number of tensor elements.</p>
<p>The concept of permuting can be a little bit confusing in the case of ITensors, where the index order should not matter to the user. The way to think about it is that the permute function is a "lower-level" operation which is really permuting the way an ITensor is stored in memory. The usefulness of it is in case a different layout would make a later operation more efficient, or if you want to use a more traditional notation to access tensor elements such as T(1,2,3). </p>
<p>Otherwise, for normal types of operations involving ITensors such as adding them or contracting them with other ITensors, there is never any need to call the permute function.</p>
<p>Hope that helps! </p>
<p>Miles</p>
http://itensor.org/support/2810/computational-cost-of-itensor-permute-method?show=2811#a2811Thu, 21 Jan 2021 21:23:19 +0000Answered: M1 processor compatibility
http://itensor.org/support/2796/m1-processor-compatibility?show=2807#a2807
<p>Hi Jun,<br>
Thanks for the interesting question. So I just tried the C++ version of ITensor on a Macbook Air with the M1 processor, and it was a smooth experience. I just cloned ITensor from Github, and then used the options.mk.sample file provided as the template for options.mk. The only change I needed to make was to use clang as the C++ compiler, rather than g++. Otherwise I got an error about the -fconcepts flag not being recognized. I did not try to install MKL and build ITensor against that; it would be an interesting thing to try and important to compare the speed to Apple's default "vecLib" framework (default BLAS provided by MacOS).</p>
<p>The performance was very good. The speed I got running the exthubbard sample code was comparable to a workstation at our office that has a 24-core, 3.4 GHz Xeon chip, whereas from what I have read, the M1 has 8 3.2 GHz cores. It was more than two times faster than my Intel Macbook Pro which has a 2.9 GHz chip!</p>
<p>I also installed Julia and the Julia version of ITensor, ITensors.jl, without any issue. That surprised me because I had read that Julia was not yet working for the M1, so perhaps it is using the Rosetta compatibility layer? Also I was able to install the MKL Julia package which we have found significantly speeds up ITensors.jl on Intel chips. It would be interesting to compare Julia with and without MKL on the M1 chip.</p>
<p>Best regards,<br>
Miles</p>
http://itensor.org/support/2796/m1-processor-compatibility?show=2807#a2807Mon, 18 Jan 2021 02:19:07 +0000Answered: Are there methods for returning QN value for an MPS or QN flux for an MPO?
http://itensor.org/support/2799/are-there-methods-for-returning-value-for-mps-or-flux-for-mpo?show=2801#a2801
<p>Yes, if you call <code>flux(psi)</code> where psi is an MPS or <code>flux(H)</code> where H is an MPO it will tell you the total flux of that MPS or MPO.</p>
<p>Best,<br>
Miles</p>
http://itensor.org/support/2799/are-there-methods-for-returning-value-for-mps-or-flux-for-mpo?show=2801#a2801Fri, 15 Jan 2021 18:53:33 +0000Answered: [julia] DMRGObserver not working
http://itensor.org/support/2779/julia-dmrgobserver-not-working?show=2793#a2793
<p>Hi Sherry, so that documentation was a little bit hard to understand, because it makes it appear as if those arguments are named arguments. They are (or were - see below) not named arguments but just default arguments. However, that constructor turned out to have another bug, so would not have worked anyway even if called correctly.</p>
<p>I used that situation as an opportunity to improve the interface, and now it should work as you'd expect, i.e. </p>
<p>DMRGObserver(; energy_tol = 1E-4, minsweeps = 2)</p>
<p>say. Note that this is true right now only for the master branch of ITensors.jl and isn't in the latest numbered version yet. But we will tag a new version soon and the change will be included in 0.1.35.</p>
<p>Miles</p>
http://itensor.org/support/2779/julia-dmrgobserver-not-working?show=2793#a2793Wed, 13 Jan 2021 21:46:26 +0000Answered: [julia] Initial state for DMRG
http://itensor.org/support/2780/julia-initial-state-for-dmrg?show=2791#a2791
<p>Please see the discussion above. The key take-away of the discussion is that the same array of site indices used to originally make an MPS must be used to make a compatible MPO or other MPS. This array of site indices can be conveniently obtained from an existing MPS <code>psi</code> by calling:</p>
<pre><code>sites = siteinds(psi)
</code></pre>
http://itensor.org/support/2780/julia-initial-state-for-dmrg?show=2791#a2791Wed, 13 Jan 2021 05:40:17 +0000Answered: convergence problem for small lattice
http://itensor.org/support/2766/convergence-problem-for-small-lattice?show=2775#a2775
<p>(Please see discussion above.)</p>
http://itensor.org/support/2766/convergence-problem-for-small-lattice?show=2775#a2775Sat, 09 Jan 2021 22:35:28 +0000Answered: leftlim and rightlim initialization present in randomizeMPS! but not productMPS
http://itensor.org/support/2771/rightlim-initialization-present-randomizemps-productmps?show=2772#a2772
<p>Hi Sujay,<br>
Happy to discuss more, but most of your question can probably be answered by addressing the true purpose of leftlim and rightlim. They do not represent the boundaries of the region currently optimized (though in an optimization context they might correspond to these regions). What they actually represent are the orthogonality properties of the MPS, or at least as much that we can guarantee in the code in an automated way. (What I mean by that last part is that the MPS might be orthogonal over an even larger region than indicated by leftlim and rightlim but at a minimum it is guaranteed to be orthogonal up to leftlim and rightlim.)</p>
<p>You probably already know what I mean by parts of the MPS being orthogonal, but to be clear the meaning of leftlim is that the MPS tensors 1:leftlim are all left-orthogonal (square to an identity when contracted over both their left index and site index) and the MPS tensors rightlim:N are all right-orthogonal. Again other MPS tensors might be right or left orthogonal besides the ones in (1:leftlim) and (rightlim:N) but we only guarantee the ones in those ranges in terms of our algorithms.</p>
<p>The specific case of the productMPS function is one where we could, and probably should, strengthen this guarantee. I gather that right now leftlim and rightlim just remain at their most conservative settings of leftlim=0 and rightlim=N+1 i.e. not guaranteeing any orthogonality. Whereas productMPS is a special case where <em>all</em> of the MPS tensors are simulaneously both left and right orthogonal. So we could instead say set leftlim=0 and rightlim=2 for productMPS or some other setting.</p>
<p>The randomMPS function doesn't specifically "shift" leftlim and rightlim: rather it sets them because it constructs the MPS out of a quantum circuit that ensures the property that all MPS tensors from 2:N are right-orthogonal. The MPS tensor at site 1 is the "orthogonality center" of this MPS gauge (so called right-orthogonal gauge). </p>
<p>What does shift the leftlim and rightlim values are functions like <code>replacebond!</code> as you mention, which is used internally by DMRG and other algorithms (or you can use it directly). In a sense, this is its main purpose i.e. to update an MPS locally while correctly shifting leftlim and rightlim, as well as selecting among various algorithms for you based on truncation and accuracy settings. Doing this correctly "by hand" could be error prone so we introduced this function to help.</p>
<p>Finally, what is the real purpose of even having leftlim and rightlim? It is for two reasons: correctness and efficiency. There is a correctness aspect where truncating an MPS locally without including the orthogonality center can lead to an uncontrolled / unknown error. Another reason is efficiency: having a known leftlim and rightlim means that for many purposes the left- and right-orthogonal tensors can be omitted from certain algorithmic steps which cuts down on computation by quite a lot without sacrificing correctness or accuracy.</p>
<p>Hope that helps - this is giving me some ideas of things we should put into the docs -</p>
<p>Miles</p>
http://itensor.org/support/2771/rightlim-initialization-present-randomizemps-productmps?show=2772#a2772Sat, 09 Jan 2021 18:08:23 +0000