Revision a7c7ec38ef00eff0b80337577d4c9c17fe6b6904 authored by Miles Stoudenmire on 22 May 2014, 21:20:26 UTC, committed by Miles Stoudenmire on 23 May 2014, 17:42:01 UTC
1 parent 6ec25ad
hambuilder.h
//
// Distributed under the ITensor Library License, Version 1.1.
// (See accompanying LICENSE file.)
//
#ifndef __ITENSOR_HAMBUILDER_H
#define __ITENSOR_HAMBUILDER_H
#include "mpo.h"
//
//
// HamBuilder
//
// Class for creating product-operator MPOs,
// usually to be combined into a more complex
// MPO such as a Hamiltonian.
//
class HamBuilder
{
public:
HamBuilder(const Model& mod);
int
N() const { return N_; }
//Sets res to an identity MPO
template <class Tensor>
void
getMPO(MPOt<Tensor>& res, Real fac=1) const;
//Sets the j1'th operator of res to op1
//and the rest to the identity
template <class Tensor>
void
getMPO(int j1, const Tensor& op1,
MPOt<Tensor>& res, Real fac=1) const;
//Sets the j1'th operator of res to op1,
//the j2'th operator of res to op2,
//and the rest to the identity
template <class Tensor>
void
getMPO(int j1, const Tensor& op1,
int j2, const Tensor& op2,
MPOt<Tensor>& res, Real fac=1) const;
// etc.
template <class Tensor>
void
getMPO(int j1, const Tensor& op1,
int j2, const Tensor& op2,
int j3, const Tensor& op3,
MPOt<Tensor>& res, Real fac=1) const;
template <class Tensor>
void
getMPO(int j1, const Tensor& op1,
int j2, const Tensor& op2,
int j3, const Tensor& op3,
int j4, const Tensor& op4,
MPOt<Tensor>& res, Real fac=1) const;
private:
/////////////////
//
// Data Members
const Model& mod_;
const int N_;
//
/////////////////
void
putLinks(MPOt<ITensor>& res) const;
void
putLinks(MPOt<IQTensor>& res) const;
template <class Tensor>
void
initialize(MPOt<Tensor>& res) const;
static int
hamNumber()
{
static int num_ = 0;
++num_;
return num_;
}
};
inline HamBuilder::
HamBuilder(const Model& mod)
:
mod_(mod),
N_(mod.N())
{ }
template <class Tensor>
void HamBuilder::
getMPO(MPOt<Tensor>& res, Real fac) const
{
initialize(res);
putLinks(res);
res.Anc(1) *= fac;
}
template <class Tensor>
void HamBuilder::
getMPO(int j1, const Tensor& op1,
MPOt<Tensor>& res, Real fac) const
{
initialize(res);
#ifdef DEBUG
if(!hasindex(op1,mod_.si(j1)))
{
Print(j1);
Print(op1.indices());
Error("Tensor does not have correct Site index");
}
#endif
res.Anc(j1) = op1;
res.Anc(j1) *= fac;
putLinks(res);
}
template <class Tensor>
void HamBuilder::
getMPO(int j1, const Tensor& op1,
int j2, const Tensor& op2,
MPOt<Tensor>& res, Real fac) const
{
initialize(res);
#ifdef DEBUG
if(!hasindex(op1,mod_.si(j1)))
{
Print(j1);
Print(op1.indices());
Error("Tensor does not have correct Site index");
}
if(!hasindex(op2,mod_.si(j2)))
{
Print(j2);
Print(op2.indices());
Error("Tensor does not have correct Site index");
}
#endif
res.Anc(j1) = op1;
res.Anc(j2) = op2;
res.Anc(j1) *= fac;
putLinks(res);
}
template <class Tensor>
void HamBuilder::
getMPO(int j1, const Tensor& op1,
int j2, const Tensor& op2,
int j3, const Tensor& op3,
MPOt<Tensor>& res, Real fac) const
{
initialize(res);
#ifdef DEBUG
if(!hasindex(op1,mod_.si(j1)))
{
Print(j1);
Print(op1.indices());
Error("Tensor does not have correct Site index");
}
if(!hasindex(op2,mod_.si(j2)))
{
Print(j2);
Print(op2.indices());
Error("Tensor does not have correct Site index");
}
if(!hasindex(op3,mod_.si(j3)))
{
Print(j3);
Print(op3.indices());
Error("Tensor does not have correct Site index");
}
#endif
res.Anc(j1) = op1;
res.Anc(j2) = op2;
res.Anc(j3) = op3;
res.Anc(j1) *= fac;
putLinks(res);
}
template <class Tensor>
void HamBuilder::
getMPO(int j1, const Tensor& op1,
int j2, const Tensor& op2,
int j3, const Tensor& op3,
int j4, const Tensor& op4,
MPOt<Tensor>& res, Real fac) const
{
initialize(res);
#ifdef DEBUG
if(!hasindex(op1,mod_.si(j1)))
{
Print(j1);
Print(op1.indices());
Error("Tensor does not have correct Site index");
}
if(!hasindex(op2,mod_.si(j2)))
{
Print(j2);
Print(op2.indices());
Error("Tensor does not have correct Site index");
}
if(!hasindex(op3,mod_.si(j3)))
{
Print(j3);
Print(op3.indices());
Error("Tensor does not have correct Site index");
}
if(!hasindex(op4,mod_.si(j4)))
{
Print(j4);
Print(op4.indices());
Error("Tensor does not have correct Site index");
}
#endif
res.Anc(j1) = op1;
res.Anc(j2) = op2;
res.Anc(j3) = op3;
res.Anc(j4) = op4;
res.Anc(j1) *= fac;
putLinks(res);
}
template <class Tensor>
void HamBuilder::
initialize(MPOt<Tensor>& res) const
{
res = MPOt<Tensor>(mod_);
for(int j = 1; j <= N_; ++j)
res.Anc(j) = mod_.op("Id",j);
}
void inline HamBuilder::
putLinks(MPOt<ITensor>& res) const
{
int ver = hamNumber();
std::vector<Index> links(N_);
for(int i = 1; i < N_; ++i)
{
boost::format nm = boost::format("h%d-%d") % ver % i;
links.at(i) = Index(nm.str());
}
res.Anc(1) *= links.at(1)(1);
for(int i = 1; i < N_; ++i)
{
res.Anc(i) *= links.at(i-1)(1);
res.Anc(i) *= links.at(i)(1);
}
res.Anc(N_) *= links.at(N_-1)(1);
}
void inline HamBuilder::
putLinks(MPOt<IQTensor>& res) const
{
QN q;
int ver = hamNumber();
std::vector<IQIndex> links(N_);
for(int i = 1; i < N_; ++i)
{
boost::format nm = boost::format("h%d-%d") % ver % i,
Nm = boost::format("H%d-%d") % ver % i;
q += div(res.A(i));
links.at(i) = IQIndex(Nm.str(),
Index(nm.str()),q);
}
res.Anc(1) *= links.at(1)(1);
for(int i = 2; i < N_; ++i)
{
res.Anc(i) *= conj(links.at(i-1)(1));
res.Anc(i) *= links.at(i)(1);
}
res.Anc(N_) *= conj(links.at(N_-1)(1));
}
#endif
Computing file changes ...