Skip to content

Commit

Permalink
Merge remote-tracking branch 'ITensor/v3' into v3
Browse files Browse the repository at this point in the history
  • Loading branch information
emstoudenmire committed Oct 17, 2020
2 parents 15d7739 + b6f9034 commit e0c2bca
Show file tree
Hide file tree
Showing 8 changed files with 246 additions and 84 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ sample/hubbard_2d
sample/hubbard_2d-g
sample/trg
sample/trg-g
sample/ctmrg
sample/ctmrg-g
this_dir.mk
options.mk
.exrc
Expand Down
14 changes: 10 additions & 4 deletions sample/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ LIBGFLAGS=-L'$(ITENSOR_LIBDIR)' $(ITENSOR_LIBGFLAGS)

#Targets -----------------

build: dmrg dmrg_table dmrgj1j2 exthubbard trg mixedspin hubbard_2d
build: dmrg dmrg_table dmrgj1j2 exthubbard trg ctmrg mixedspin hubbard_2d

debug: dmrg-g dmrg_table-g dmrgj1j2-g exthubbard-g trg-g mixedspin-g hubbard_2d-g
debug: dmrg-g dmrg_table-g dmrgj1j2-g exthubbard-g trg-g ctmrg-g mixedspin-g hubbard_2d-g

all: dmrg dmrg_table dmrgj1j2 exthubbard trg mixedspin hubbard_2d
all: dmrg dmrg_table dmrgj1j2 exthubbard trg ctmrg mixedspin hubbard_2d

dmrg: dmrg.o $(ITENSOR_LIBS) $(TENSOR_HEADERS)
$(CCCOM) $(CCFLAGS) dmrg.o -o dmrg $(LIBFLAGS)
Expand Down Expand Up @@ -61,6 +61,12 @@ trg: trg.o $(ITENSOR_LIBS) $(TENSOR_HEADERS)
trg-g: mkdebugdir .debug_objs/trg.o $(ITENSOR_GLIBS) $(TENSOR_HEADERS)
$(CCCOM) $(CCGFLAGS) .debug_objs/trg.o -o trg-g $(LIBGFLAGS)

ctmrg: ctmrg.o $(ITENSOR_LIBS) $(TENSOR_HEADERS)
$(CCCOM) $(CCFLAGS) ctmrg.o -o ctmrg $(LIBFLAGS)

ctmrg-g: mkdebugdir .debug_objs/trg.o $(ITENSOR_GLIBS) $(TENSOR_HEADERS)
$(CCCOM) $(CCGFLAGS) .debug_objs/ctmrg.o -o ctmrg-g $(LIBGFLAGS)

hubbard_2d: hubbard_2d.o $(ITENSOR_LIBS) $(TENSOR_HEADERS)
$(CCCOM) $(CCFLAGS) hubbard_2d.o -o hubbard_2d $(LIBFLAGS)

Expand All @@ -73,4 +79,4 @@ mkdebugdir:
clean:
@rm -fr *.o .debug_objs dmrg dmrg-g \
dmrg_table dmrg_table-g dmrgj1j2 dmrgj1j2-g exthubbard exthubbard-g \
mixedspin mixedspin-g trg trg-g hubbard_2d hubbard_2d-g
mixedspin mixedspin-g trg trg-g ctmrg ctmrg-g hubbard_2d hubbard_2d-g
4 changes: 4 additions & 0 deletions sample/README
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ mixedspin - demo code showing how to make and use
trg - tensor renormalization group (TRG) algorithm
for computing properties of large 2D classical
stat mech systems

ctmrg - corner transfer matrix renormalization group (CTMRG) algorithm
for computing properties of large 2D classical
stat mech systems
60 changes: 60 additions & 0 deletions sample/ctmrg.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include "src/ctmrg.h"
#include "src/ising.h"
#include "itensor/util/print_macro.h"

int
main()
{
Real betac = 0.5 * log(sqrt(2) + 1.0);
Real beta = 1.1 * betac;
int maxdim = 20;
int nsteps = 20;

auto dim0 = 2;

// Define an initial Index making up
// the Ising partition function
auto s = Index(dim0, "Site");

// Define the indices of the scale-0
// Boltzmann weight tensor "A"
auto sh = addTags(s, "horiz");
auto sv = addTags(s, "vert");

auto T = ising(sh, sv, beta);

auto l = Index(1, "Link");
auto lh = addTags(l, "horiz");
auto lv = addTags(l, "vert");
auto Clu0 = ITensor(lv, lh);
Clu0.set(1, 1, 1.0);
auto Al0 = ITensor(lv, prime(lv), sh);
Al0.set(lv = 1, prime(lv) = 1, sh = 1, 1.0);

auto [Clu, Al] = ctmrg(T, Clu0, Al0, maxdim, nsteps);

lv = commonIndex(Clu, Al);
lh = uniqueIndex(Clu, Al);

auto Au = replaceInds(Al, {lv, prime(lv), sh},
{lh, prime(lh), sv});

auto ACl = Al * Clu * dag(prime(Clu));

auto ACTl = prime(ACl * dag(prime(Au)) * T * Au, -1);
auto kappa = elt(ACTl * dag(ACl));

auto Tsz = ising(sh, sv, beta, true);
auto ACTszl = prime(ACl * dag(prime(Au)) * Tsz * Au, -1);
auto m = elt(ACTszl * dag(ACl)) / kappa;

printfln("beta = %.12f", beta);
printfln("beta/betac = %.12f", beta / betac);
println("maxdim = ", maxdim);
println("niters = ", nsteps);
printfln("kappa = %.12f", kappa);
printfln("m = %.12f", m);

return 0;
}

60 changes: 60 additions & 0 deletions sample/src/ctmrg.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include "itensor/all.h"

using namespace itensor;

std::tuple<ITensor, ITensor>
ctmrg(ITensor T,
ITensor Clu,
ITensor Al,
int maxdim,
int nsteps,
Real cutoff = 0.0)
{
auto sh = commonIndex(T, Al);
auto sv = uniqueIndex(T, {Al, prime(Al)}, "0");
auto lv = commonIndex(Clu, Al);
auto lh = uniqueIndex(Clu, Al);
auto Au = replaceInds(Al, {lv, prime(lv), sh},
{lh, prime(lh), sv});
ITensor Uv;
for(auto i : range1(nsteps))
{
// Get the grown corner transfer matrix (CTM)
auto Clu_new = Al * Clu * Au * T;

Clu_new.noPrime();
Clu_new.replaceInds({lh, sh}, {prime(lv), prime(sv)});

// Diagonalize the grown CTM
std::tie(Uv, Clu) = diagPosSemiDef(Clu_new,
{"MaxDim = ", maxdim,
"Tags = ", tags(lv),
"Cutoff = ", cutoff});

lv = commonIndex(Clu, Uv);
lh = setTags(lv, tags(lh));

Clu = toDense(Clu);
Clu.replaceInds({prime(lv)}, {lh});

// The renormalized CTM is the diagonal matrix of eigenvalues
// Normalize the CTM
auto Cl = Clu * prime(dag(Clu), lh);
auto normC = pow(elt(Cl * dag(Cl)), 0.25);
Clu /= normC;

// Calculate the renormalized half row transfer matrix (HRTM)
Uv.noPrime();
Al = Al * Uv * T * dag(prime(Uv));
Al = replaceInds(Al, {prime(sh)}, {sh});

// Normalize the HRTM
auto ACl = Al * Clu * prime(dag(Clu));
auto normA = sqrt(elt(ACl * dag(ACl)));
Al /= normA;
Au = replaceInds(Al, {lv, prime(lv), sh},
{lh, prime(lh), sv});
}
return std::tuple<ITensor, ITensor>({Clu, Al});
}

82 changes: 62 additions & 20 deletions sample/src/ising.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,68 @@
using namespace itensor;

ITensor
ising(Index const& l, Index const& r,
Index const& u, Index const& d,
Real beta)
ising(Index const& sh,
Index const& sv,
Real beta,
bool sz = false)
{
int dim0 = 2;
auto A = ITensor(l, r, u, d);
auto T = 1/beta;

// Fill the A tensor with correct Boltzmann weights:
auto Sig = [](int s) { return 1.-2.*(s-1); };
for(auto sl : range1(dim0))
for(auto sd : range1(dim0))
for(auto sr : range1(dim0))
for(auto su : range1(dim0))
{
auto E = Sig(sl)*Sig(sd)+Sig(sd)*Sig(sr)
+Sig(sr)*Sig(su)+Sig(su)*Sig(sl);
auto P = exp(-E/T);
A.set(l(sl),r(sr),u(su),d(sd),P);
}
return A;
auto d = dim(sh);
auto shp = prime(sh);
auto svp = prime(sv);
auto T = ITensor(sh, shp, sv, svp);
for(auto i : range1(d)){ T.set(i, i, i, i, 1.0); }
if(sz) { T.set(1, 1, 1, 1, -1.0); }
auto th = sim(sh);
auto thp = sim(shp);
auto tv = sim(sv);
auto tvp = sim(svp);
auto Tp = T * delta(sh, th) *
delta(shp, thp) *
delta(sv, tv) *
delta(svp, tvp);
// Analytic square root of the bond matrix:
// [exp( beta) exp(-beta)
// exp(-beta) exp( beta)]
auto lambda_p = sqrt(exp(beta) + exp(-beta));
auto lambda_m = sqrt(exp(beta) - exp(-beta));
auto x_p = 0.5 * (lambda_p + lambda_m);
auto x_m = 0.5 * (lambda_p - lambda_m);
auto Xh = ITensor(th, sh);
Xh.set(1, 1, x_p);
Xh.set(2, 1, x_m);
Xh.set(1, 2, x_m);
Xh.set(2, 2, x_p);
auto Xhp = replaceInds(Xh, {th, sh}, {thp, shp});
auto Xv = replaceInds(Xh, {th, sh}, {tv, sv });
auto Xvp = replaceInds(Xh, {th, sh}, {tvp, svp});
return Tp * Xhp * Xvp * Xh * Xv;
}

//
// Dual partition function
//

//ITensor
//ising(Index const& sh, Index const& sv,
// Real beta)
// {
// int dim0 = 2;
// auto T = ITensor(sh, prime(sh), sv, prime(sv));
//
// // Fill the T tensor with correct Boltzmann weights:
// auto Sig = [](int s) { return 1. - 2. * (s - 1); };
// for(auto ssh : range1(dim0))
// for(auto ssvp : range1(dim0))
// for(auto sshp : range1(dim0))
// for(auto ssv : range1(dim0))
// {
// auto E = Sig(ssh) * Sig(ssvp) +
// Sig(ssvp) * Sig(sshp) +
// Sig(sshp) * Sig(ssv) +
// Sig(ssv) * Sig(ssh);
// auto P = exp(-beta * E);
// T.set(sh = ssh, prime(sh) = sshp, sv = ssv, prime(sv) = ssvp, P);
// }
// return T;
// }

98 changes: 44 additions & 54 deletions sample/src/trg.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,73 +4,63 @@ using namespace itensor;

std::tuple<ITensor, Real>
trg(ITensor const& A0,
Index l, Index r,
Index u, Index d,
int maxdim, int topscale)
int maxdim, int topscale,
Real cutoff = 0.0)
{
auto A = addTags(A0, "scale=0");
l.addTags("scale=0");
r.addTags("scale=0");
u.addTags("scale=0");
d.addTags("scale=0");
auto A = A0;
auto is = findInds(A, "0");
auto sh = is(1);
auto sv = is(2);

// Keep track of partition function per site, z = Z^(1/N)
Real z = 1.0;

for(auto scale : range1(topscale))
{
//printfln("\n---------- Scale %d -> %d ----------",scale-1,scale);
{
//printfln("\n---------- Scale %d -> %d ----------",scale-1,scale);

// Get the upper-left and lower-right tensors
auto [Fl, Fr] = factor(A, {r, d}, {l, u},
{"MaxDim = ", maxdim,
"Tags = ", "left,scale=" + str(scale),
"SVDMethod = ", "gesdd",
"ShowEigs = ", false});
// Get the upper-left and lower-right tensors
auto [Fh, Fhp] = factor(A, {prime(sh), prime(sv)}, {sh, sv},
{"MaxDim = ", maxdim,
"Tags = ", "horiz",
"SVDMethod = ", "gesdd",
"Cutoff = ", cutoff,
"ShowEigs = ", false});

// Grab the new left Index
auto l_new = commonIndex(Fl, Fr);
// Grab the new left Index
auto sh_new = commonIndex(Fh, Fhp);
Fhp *= delta(sh_new, prime(sh_new));

// Get the upper-right and lower-left tensors
auto [Fu, Fd] = factor(A, {l, d}, {u, r},
{"MaxDim = ", maxdim,
"Tags = ", "up,scale=" + str(scale),
"SVDMethod = ", "gesdd",
"ShowEigs = ", false});
// Get the upper-right and lower-left tensors
auto [Fv, Fvp] = factor(A, {sh, prime(sv)}, {prime(sh), sv},
{"MaxDim = ", maxdim,
"Tags = ", "vert",
"SVDMethod = ", "gesdd",
"Cutoff = ", cutoff,
"ShowEigs = ", false});

// Grab the new up Index
auto u_new = commonIndex(Fu, Fd);
// Grab the new up Index
auto sv_new = commonIndex(Fv, Fvp);
Fvp *= delta(sv_new, prime(sv_new));

// Make the new index of Fl distinct
// from the new index of Fr by changing
// the tag from "left" to "right"
auto r_new = replaceTags(l_new, "left", "right");
Fr *= delta(l_new, r_new);
A = (Fh * delta(prime(sh), sh)) *
(Fv * delta(prime(sv), sv)) *
(Fhp * delta(sh, prime(sh))) *
(Fvp * delta(sv, prime(sv)));

// Update the indices
sh = sh_new;
sv = sv_new;

// Make the new index of Fd distinct
// from the new index of Fu by changing the tag
// from "up" to "down"
auto d_new = replaceTags(u_new, "up", "down");
Fd *= delta(u_new, d_new);
// Normalize the current tensor and keep track of
// the total normalization
Real TrA = elt(A * delta(sh, prime(sh)) * delta(sv, prime(sv)));
A /= TrA;
z *= pow(TrA, 1.0 / pow(2, scale));

Fl *= delta(r, l);
Fu *= delta(d, u);
Fr *= delta(l, r);
Fd *= delta(u, d);
A = Fl * Fu * Fr * Fd;

// Update the indices
l = l_new;
r = r_new;
u = u_new;
d = d_new;

// Normalize the current tensor and keep track of
// the total normalization
Real TrA = elt(A * delta(l, r) * delta(u, d));
A /= TrA;
z *= pow(TrA, 1.0 / pow(2, 1 + scale));
}
// If using the dual Ising partition function
//z *= pow(TrA, 1.0 / pow(2, 1 + scale));
}

//printfln("log(Z)/N = %.12f",log(z));

Expand Down
10 changes: 4 additions & 6 deletions sample/trg.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ main()

// Define the indices of the scale-0
// Boltzmann weight tensor "A"
auto l = addTags(s, "left");
auto r = addTags(s, "right");
auto u = addTags(s, "up");
auto d = addTags(s, "down");
auto sh = addTags(s, "horiz");
auto sv = addTags(s, "vert");

auto A0 = ising(l, r, u, d, beta);
auto [A, z] = trg(A0, l, r, u, d, maxdim, topscale);
auto A0 = ising(sh, sv, beta);
auto [A, z] = trg(A0, maxdim, topscale);
(void)A;

printfln("beta = %.12f", beta);
Expand Down

0 comments on commit e0c2bca

Please sign in to comment.