VMPS++
Loading...
Searching...
No Matches
DmrgExternal.h
Go to the documentation of this file.
1#ifndef STRAWBERRY_DMRGEXTERNALQ
2#define STRAWBERRY_DMRGEXTERNALQ
3
5#include <sstream>
6#include <array>
7#include <boost/functional/hash.hpp>
8#include <boost/rational.hpp>
10
11typedef boost::rational<int> frac;
12
13#include "symmetry/qarray.h"
14// #include "DmrgTypedefs.h"
15
17#ifndef POSMOD_FUNCTION
18#define POSMOD_FUNCTION
19template<int N>
20inline int posmod (int x)
21{
22 return (x%N+N)%N;
23}
24
25inline int posmod (int x, int N)
26{
27 return (x%N+N)%N;
28}
29#endif
30
32std::string print_frac_nice (frac r)
33{
34 std::stringstream ss;
35 if (r.denominator()==1) {ss << r.numerator();}
36 else {ss << r;}
37 return ss.str();
38}
39
40namespace std
41{
43 template<size_t N>
44 struct hash<std::array<int,N> >
45 {
46 inline size_t operator()(const std::array<int,N> &a) const
47 {
48 size_t seed = 0;
49 for (size_t i=0; i<N; ++i)
50 {
51 boost::hash_combine(seed, a[i]);
52 }
53 return seed;
54 }
55 };
56}
57
58namespace std
59{
61template<size_t Nq, size_t Nlegs>
62struct hash<std::array<qarray<Nq>,Nlegs> >
63{
64 inline size_t operator()(const std::array<qarray<Nq>,Nlegs> &ix) const
65 {
66 size_t seed = 0;
67 for (size_t leg=0; leg<Nlegs; ++leg)
68 for (size_t q=0; q<Nq; ++q)
69 {
70 boost::hash_combine(seed, ix[leg][q]);
71 }
72 return seed;
73 }
74};
75
77template<size_t Nq>
78struct hash<std::tuple<size_t,size_t,size_t,qarray<Nq>,qarray<Nq> > >
79{
80 inline size_t operator()(const std::tuple<size_t,size_t,size_t,qarray<Nq>,qarray<Nq> > &ix) const
81 {
82 size_t seed = 0;
83 boost::hash_combine(seed, get<0>(ix));
84 boost::hash_combine(seed, get<1>(ix));
85 boost::hash_combine(seed, get<2>(ix));
86 for (size_t q=0; q<Nq; ++q) { boost::hash_combine(seed, get<3>(ix)[q]); }
87 for (size_t q=0; q<Nq; ++q) { boost::hash_combine(seed, get<4>(ix)[q]); }
88 return seed;
89 }
90};
91
93template<size_t Nq>
94struct hash<std::pair<qarray<Nq>,size_t> >
95{
96 inline size_t operator()(const std::pair<qarray<Nq>,size_t> &ix) const
97 {
98 size_t seed = 0;
99 for (size_t q=0; q<Nq; ++q) { boost::hash_combine(seed, get<0>(ix)[q]); }
100 boost::hash_combine(seed, get<1>(ix));
101 return seed;
102 }
103};
104
109template<>
110struct hash<std::array<size_t,2> >
111{
112 inline size_t operator()(const std::array<size_t,2> &a) const
113 {
114 size_t seed = 0;
115 boost::hash_combine(seed, a[0]);
116 boost::hash_combine(seed, a[1]);
117 return seed;
118 }
119};
120
125template<size_t Nq>
126struct hash<qarray<Nq> >
127{
128 inline size_t operator()(const qarray<Nq> &ix) const
129 {
130 size_t seed = 0;
131 for (size_t q=0; q<Nq; ++q)
132 {
133 boost::hash_combine(seed, ix[q]);
134 }
135 return seed;
136 }
137};
138}
139
141template<typename MatrixTypeA, typename MatrixTypeB>
142size_t mult_cost (const MatrixTypeA &A, const MatrixTypeB &B)
143{
144 return A.rows()*A.cols()*B.cols();
145}
146
148template<typename MatrixTypeA, typename MatrixTypeB, typename MatrixTypeC>
149std::vector<size_t> mult_cost (const MatrixTypeA &A, const MatrixTypeB &B, const MatrixTypeC &C)
150{
151 std::vector<size_t> out(2);
152 // (AB)C
153 out[0] = mult_cost(A,B) + A.rows()*C.rows()*C.cols();
154
155 // A(BC)
156 out[1] = mult_cost(B,C) + A.rows()*A.cols()*C.cols();
157
158 return out;
159}
160
162template<typename MatrixTypeA, typename MatrixTypeB, typename MatrixTypeC, typename MatrixTypeD>
163std::vector<size_t> mult_cost (const MatrixTypeA &A, const MatrixTypeB &B, const MatrixTypeC &C, const MatrixTypeD &D)
164{
165 std::vector<size_t> out(5);
166 // (AB)(CD)
167 out[0] = mult_cost(A,B) + mult_cost(C,D) + A.rows()*B.cols()*C.cols();
168
169 // ((AB)C)D
170 out[1] = mult_cost(A,B) + A.rows()*C.rows()*C.cols() + A.rows()*D.rows()*D.cols();
171
172 // (A(BC))D
173 out[2] = mult_cost(B,C) + A.rows()*A.cols()*C.cols() + A.rows()*D.rows()*D.cols();
174
175 // A((BC)D)
176 out[3] = mult_cost(B,C) + B.rows()*D.rows()*D.cols() + A.rows()*A.cols()*D.cols();
177
178 // A(B(CD))
179 out[4] = mult_cost(C,D) + B.rows()*B.cols()*D.cols() + A.rows()*A.cols()*D.cols();
180 return out;
181}
182
183template<typename MatrixType>
184inline void print_size (const MatrixType &M, string label)
185{
186 std::cout << label << ": " << M.rows() << "x" << M.cols() << std::endl;
187}
188
190template<typename MatrixTypeA, typename MatrixTypeB, typename MatrixTypeC, typename MatrixTypeR, typename Scalar>
191void optimal_multiply (Scalar alpha, const MatrixTypeA &A, const MatrixTypeB &B, const MatrixTypeC &C, MatrixTypeR &result, bool DEBUG=false)
192{
193 if (DEBUG)
194 {
195 print_size(A,"A");
196 print_size(B,"B");
197 print_size(C,"C");
198 std::cout << endl;
199 }
200
201 std::vector<size_t> cost(2);
202 cost = mult_cost(A,B,C);
203 size_t opt_mult = min_element(cost.begin(),cost.end())- cost.begin();
204
205 if (opt_mult == 0)
206 {
207 MatrixTypeR Mtmp = A * B;
208 result.noalias() = alpha * Mtmp * C;
209 }
210 else if (opt_mult == 1)
211 {
212 MatrixTypeR Mtmp = B * C;
213 result.noalias() = alpha * A * Mtmp;
214 }
215}
216
218template<typename MatrixTypeA, typename MatrixTypeB, typename MatrixTypeC, typename MatrixTypeD, typename MatrixTypeR, typename Scalar>
219void optimal_multiply (Scalar alpha, const MatrixTypeA &A, const MatrixTypeB &B, const MatrixTypeC &C, const MatrixTypeD &D, MatrixTypeR &result,
220 bool DEBUG=false)
221{
222 if (DEBUG)
223 {
224 print_size(A,"A");
225 print_size(B,"B");
226 print_size(C,"C");
227 print_size(D,"D");
228 std::cout << endl;
229 }
230
231 std::vector<size_t> cost(5);
232 cost = mult_cost(A,B,C,D);
233 size_t opt_mult = min_element(cost.begin(),cost.end())- cost.begin();
234
235 if (opt_mult == 0)
236 {
237 MatrixTypeR Mtmp1 = A * B;
238 MatrixTypeR Mtmp2 = C * D;
239 result = alpha * Mtmp1 * Mtmp2;
240 }
241 else if (opt_mult == 1)
242 {
243 MatrixTypeR Mtmp = A * B;
244 Mtmp = Mtmp * C;
245 result = alpha * Mtmp * D;
246 }
247 else if (opt_mult == 2)
248 {
249 MatrixTypeR Mtmp = B * C;
250 Mtmp = A * Mtmp;
251 result = alpha * Mtmp * D;
252 }
253 else if (opt_mult == 3)
254 {
255 MatrixTypeR Mtmp = B * C;
256 Mtmp = Mtmp * D;
257 result = alpha * A * Mtmp;
258 }
259 else if (opt_mult == 4)
260 {
261 MatrixTypeR Mtmp = C * D;
262 Mtmp = B * Mtmp;
263 result = alpha * A * Mtmp;
264 }
265}
266
268inline double stagger (int i)
269{
270 return pow(-1.,i);
271}
272
274template<typename Scalar>
275Scalar localSumTrivial (int i)
276{
277 return 1.;
278}
279
283double calc_S_from_SSp1 (double x)
284{
285 return -0.5+sqrt(0.25+x);
286}
287
288int closest_int (double x, int min, int max)
289{
290 ArrayXd v(abs(max-min)+1);
291
292 for (int i=0; i<v.rows(); ++i)
293 {
294 v(i) = double(min+i);
295 }
296
297 v -= x;
298 v = v.cwiseAbs();
299 int res;
300 v.minCoeff(&res);
301 return res;
302}
303
304// template<typename Symmetry>
305// void transform_base (vector<vector<qarray<Symmetry::Nq> > > &qloc, qarray<Symmetry::Nq> Qtot, bool PRINT = false)
306// {
307// if (Qtot != Symmetry::qvacuum())
308// {
309// for (size_t l=0; l<qloc.size(); ++l)
310// for (size_t i=0; i<qloc[l].size(); ++i)
311// for (size_t q=0; q<Symmetry::Nq; ++q)
312// {
313// if (Symmetry::kind()[q] != Sym::KIND::S and Symmetry::kind()[q] != Sym::KIND::T) //Do not transform the base for non Abelian symmetries
314// {
315// qloc[l][i][q] = qloc[l][i][q] * static_cast<int>(qloc.size()) - Qtot[q];
316// }
317// }
318
319// if (PRINT)
320// {
321// lout << "transformed base:" << endl;
322// for (size_t l=0; l<qloc.size(); ++l)
323// {
324// lout << "l=" << l << endl;
325// for (size_t i=0; i<qloc[l].size(); ++i)
326// {
327// cout << "qloc: " << qloc[l][i] << endl;
328// }
329// }
330// }
331// }
332// };
333
334#endif
boost::rational< int > frac
Definition: DmrgExternal.h:11
double calc_S_from_SSp1(double x)
Definition: DmrgExternal.h:283
double stagger(int i)
Definition: DmrgExternal.h:268
size_t mult_cost(const MatrixTypeA &A, const MatrixTypeB &B)
Definition: DmrgExternal.h:142
std::string print_frac_nice(frac r)
Definition: DmrgExternal.h:32
Scalar localSumTrivial(int i)
Definition: DmrgExternal.h:275
void print_size(const MatrixType &M, string label)
Definition: DmrgExternal.h:184
void optimal_multiply(Scalar alpha, const MatrixTypeA &A, const MatrixTypeB &B, const MatrixTypeC &C, MatrixTypeR &result, bool DEBUG=false)
Definition: DmrgExternal.h:191
int closest_int(double x, int min, int max)
Definition: DmrgExternal.h:288
int posmod(int x)
Definition: DmrgExternal.h:20
@ B
Definition: DmrgTypedefs.h:130
@ A
Definition: DmrgTypedefs.h:130
STL namespace.
Definition: qarray.h:26
size_t operator()(const qarray< Nq > &ix) const
Definition: DmrgExternal.h:128
size_t operator()(const std::array< int, N > &a) const
Definition: DmrgExternal.h:46
size_t operator()(const std::array< qarray< Nq >, Nlegs > &ix) const
Definition: DmrgExternal.h:64
size_t operator()(const std::array< size_t, 2 > &a) const
Definition: DmrgExternal.h:112
size_t operator()(const std::pair< qarray< Nq >, size_t > &ix) const
Definition: DmrgExternal.h:96
size_t operator()(const std::tuple< size_t, size_t, size_t, qarray< Nq >, qarray< Nq > > &ix) const
Definition: DmrgExternal.h:80