35 #include <alps/numeric/real.hpp>
40 namespace ts_reshape {
42 template<
class Matrix,
class SymmGroup>
53 typedef std::size_t size_t;
54 typedef typename SymmGroup::charge charge;
60 boost::lambda::bind(
static_cast<charge(*)(charge, charge)
>(
SymmGroup::fuse),
61 -boost::lambda::_1, boost::lambda::_2));
65 for (
size_t block = 0; block < m1.
n_blocks(); ++block)
67 for (
size_t s1 = 0; s1 < physical_i_left.
size(); ++s1)
68 for (
size_t s2 = 0; s2 < physical_i_right.size(); ++s2)
71 -physical_i_left[s1].first));
72 if(l == left_i.
size())
continue;
74 physical_i_right[s2].first));
75 if(r == right_i.
size())
continue;
78 charge s_charge =
SymmGroup::fuse(physical_i_left[s1].first, physical_i_right[s2].first);
84 charge out_r_charge = right_i[r].first;
89 if (! m2.
has_block(out_l_charge, out_r_charge) )
90 m2.
insert_block(
new Matrix(out_left.
size(s_charge, left_i[l].first), right_i[r].second, 0),
91 out_l_charge, out_r_charge);
95 in_left(physical_i_left[s1].first, left_i[l].first), in_right(physical_i_right[s2].first, right_i[r].first),
96 out_left(s_charge, left_i[l].first), phys_pb(physical_i_left[s1].first, physical_i_right[s2].first),
97 physical_i_left[s1].second, physical_i_right[s2].second, left_i[l].second, right_i[r].second );
114 template<
class Matrix,
class SymmGroup>
125 typedef std::size_t size_t;
126 typedef typename SymmGroup::charge charge;
133 boost::lambda::bind(
static_cast<charge(*)(charge, charge)
>(
SymmGroup::fuse),
134 -boost::lambda::_1, boost::lambda::_2));
137 for (
size_t block = 0; block < m1.
n_blocks(); ++block)
140 if(r == right_i.
size())
continue;
142 for (
size_t s1 = 0; s1 < physical_i_left.
size(); ++s1)
143 for (
size_t s2 = 0; s2 < physical_i_right.size(); ++s2)
145 charge s_charge =
SymmGroup::fuse(physical_i_left[s1].first, physical_i_right[s2].first);
149 if(l == left_i.
size())
continue;
152 charge out_l_charge =
SymmGroup::fuse(physical_i_left[s1].first, left_i[l].first);
153 charge out_r_charge =
SymmGroup::fuse(-physical_i_right[s2].first, right_i[r].first);
159 if (! m2.
has_block(out_l_charge, out_r_charge) )
160 m2.
insert_block(
new Matrix(out_left.
size(physical_i_left[s1].first, left_i[l].first),
161 out_right.
size(-physical_i_right[s2].first, right_i[r].first), 0),
162 out_l_charge, out_r_charge);
166 in_left(s_charge, left_i[l].first), phys_pb(physical_i_left[s1].first, physical_i_right[s2].first),
167 out_left(physical_i_left[s1].first, left_i[l].first), out_right(physical_i_right[s2].first, right_i[r].first),
168 physical_i_left[s1].second, physical_i_right[s2].second, left_i[l].second, right_i[r].second );
175 template<
class Matrix,
class SymmGroup>
186 typedef std::size_t size_t;
187 typedef typename SymmGroup::charge charge;
192 boost::lambda::bind(
static_cast<charge(*)(charge, charge)
>(
SymmGroup::fuse),
193 -boost::lambda::_1, boost::lambda::_2));
196 boost::lambda::bind(
static_cast<charge(*)(charge, charge)
>(
SymmGroup::fuse),
197 -boost::lambda::_1, boost::lambda::_2));
200 for (
size_t block = 0; block < m1.
n_blocks(); ++block)
203 if(l == left_i.
size())
continue;
205 for (
size_t s1 = 0; s1 < physical_i_left.
size(); ++s1)
206 for (
size_t s2 = 0; s2 < physical_i_right.size(); ++s2)
208 charge s_charge =
SymmGroup::fuse(physical_i_left[s1].first, physical_i_right[s2].first);
211 if(r == right_i.
size())
continue;
214 charge out_l_charge =
SymmGroup::fuse(physical_i_left[s1].first, left_i[l].first);
215 charge out_r_charge =
SymmGroup::fuse(-physical_i_right[s2].first, right_i[r].first);
221 if (! m2.
has_block(out_l_charge, out_r_charge) )
222 m2.
insert_block(
new Matrix(out_left.
size(physical_i_left[s1].first, left_i[l].first),
223 out_right.
size(-physical_i_right[s2].first, right_i[r].first), 0),
224 out_l_charge, out_r_charge);
226 size_t in_right_offset = in_right (s_charge , right_i[r].first);
227 size_t out_right_offset = out_right (physical_i_right[s2].first, right_i[r].first);
228 size_t out_left_offset = out_left (physical_i_left[s1].first, left_i[l].first);
229 size_t in_phys_offset = phys_pb (physical_i_left[s1].first, physical_i_right[s2].first);
232 Matrix
const & in_block = m1[block];
233 Matrix & out_block = m2(out_l_charge, out_r_charge);
235 for (
size_t ss1 = 0; ss1 < physical_i_left[s1].second; ++ss1)
236 for (
size_t ss2 = 0; ss2 < physical_i_right[s2].second; ++ss2)
238 size_t ss_out = in_phys_offset + ss1*physical_i_right[s2].second + ss2;
239 for (
size_t rr = 0; rr < right_i[r].second; ++rr)
240 for (
size_t ll = 0; ll < left_i[l].second; ++ll)
241 out_block(out_left_offset + ss1*left_i[l].second + ll, out_right_offset + ss2*right_i[r].second + rr) = in_block(ll, in_right_offset + ss_out*right_i[r].second + rr);
259 template<
class Matrix,
class SymmGroup>
270 typedef std::size_t size_t;
271 typedef typename SymmGroup::charge charge;
277 boost::lambda::bind(
static_cast<charge(*)(charge, charge)
>(
SymmGroup::fuse),
278 -boost::lambda::_1, boost::lambda::_2));
280 boost::lambda::bind(
static_cast<charge(*)(charge, charge)
>(
SymmGroup::fuse),
281 -boost::lambda::_1, boost::lambda::_2));
283 for (
size_t block = 0; block < m1.
n_blocks(); ++block)
285 for (
size_t s1 = 0; s1 < physical_i_left.
size(); ++s1)
288 -physical_i_left[s1].first));
289 if(l == left_i.
size())
continue;
291 for (
size_t s2 = 0; s2 < physical_i_right.size(); ++s2)
294 physical_i_right[s2].first));
295 if(r == right_i.
size())
continue;
298 charge s_charge =
SymmGroup::fuse(physical_i_left[s1].first, physical_i_right[s2].first);
303 charge out_l_charge = left_i[l].first;
308 if (! m2.
has_block(out_l_charge, out_r_charge) )
309 m2.
insert_block(
new Matrix(left_i[l].second, out_right.
size(-s_charge, right_i[r].first), 0),
310 out_l_charge, out_r_charge);
312 size_t in_left_offset = in_left(physical_i_left[s1].first, left_i[l].first);
313 size_t in_right_offset = in_right(physical_i_right[s2].first, right_i[r].first);
314 size_t out_right_offset = out_right(s_charge, right_i[r].first);
315 size_t out_phys_offset = phys_pb(physical_i_left[s1].first, physical_i_right[s2].first);
318 Matrix
const & in_block = m1[block];
319 Matrix & out_block = m2(out_l_charge, out_r_charge);
321 for (
size_t ss1 = 0; ss1 < physical_i_left[s1].second; ++ss1)
322 for (
size_t ss2 = 0; ss2 < physical_i_right[s2].second; ++ss2)
324 size_t ss_out = out_phys_offset + ss1*physical_i_right[s2].second + ss2;
325 for (
size_t rr = 0; rr < right_i[r].second; ++rr)
326 for (
size_t ll = 0; ll < left_i[l].second; ++ll)
327 out_block(ll, out_right_offset + ss_out*right_i[r].second + rr) = in_block(in_left_offset + ss1*left_i[l].second+ll, in_right_offset + ss2*right_i[r].second+rr);
size_type n_blocks() const
void reshape_l2b(alps::numeric::matrix< T, A > &out, const alps::numeric::matrix< T, A > &in, size_t in_left_offset, size_t in_phys_offset, size_t out_left_offset, size_t out_right_offset, size_t sdim1, size_t sdim2, size_t ldim, size_t rdim)
size_t size(charge pc) const
size_type insert_block(Matrix const &, charge, charge)
void reshape_both_to_right(Index< SymmGroup > const &physical_i_left, Index< SymmGroup > const &physical_i_right, Index< SymmGroup > const &left_i, Index< SymmGroup > const &right_i, block_matrix< Matrix, SymmGroup > const &m1, block_matrix< Matrix, SymmGroup > &m2)
declaration of the TwoSiteTensor class
declaration of the MPSTensor class
bool has_block(charge r, charge c) const
Index< SymmGroup > const & right_basis() const
void reshape_b2l(alps::numeric::matrix< T, A > &out, const alps::numeric::matrix< T, A > &in, size_t in_left_offset, size_t in_right_offset, size_t out_left_offset, size_t out_phys_offset, size_t sdim1, size_t sdim2, size_t ldim, size_t rdim)
std::size_t position(charge c) const
void reshape_both_to_left(Index< SymmGroup > const &physical_i_left, Index< SymmGroup > const &physical_i_right, Index< SymmGroup > const &left_i, Index< SymmGroup > const &right_i, block_matrix< Matrix, SymmGroup > const &m1, block_matrix< Matrix, SymmGroup > &m2)
algorithms for block_matrix (gemm, svd, etc.)
void reshape_right_to_both(Index< SymmGroup > const &physical_i_left, Index< SymmGroup > const &physical_i_right, Index< SymmGroup > const &left_i, Index< SymmGroup > const &right_i, block_matrix< Matrix, SymmGroup > const &m1, block_matrix< Matrix, SymmGroup > &m2)
functions to reshape the representation of data in MPSTensor
Index< SymmGroup > const & left_basis() const
void reshape_left_to_both(Index< SymmGroup > const &physical_i_left, Index< SymmGroup > const &physical_i_right, Index< SymmGroup > const &left_i, Index< SymmGroup > const &right_i, block_matrix< Matrix, SymmGroup > const &m1, block_matrix< Matrix, SymmGroup > &m2)
T fuse(const A &ind, T d)
Fuse indices n[i] into one p = n[i] d^i.