VMPS++
Loading...
Searching...
No Matches
S1xS2.h
Go to the documentation of this file.
1#ifndef S1xS2_H_
2#define S1xS2_H_
3
5#include <utility>
6#include <unordered_map>
7#include <unordered_set>
8#include <iostream>
10
11#include "DmrgTypedefs.h"
12#include "DmrgExternal.h"
13
14#include "qarray.h"
15
16#include "JoinArray.h" //from TOOLS
17
18//include "symmetry/kind_dummies.h"
19//include "symmetry/qarray.h"
20//include "symmetry/U0.h"
21//include "symmetry/U1.h"
22//include "symmetry/SU2.h"
23
24namespace Sym{
25
33template<typename S1_, typename S2_>
34class S1xS2
35{
36public:
37
38 typedef typename S1_::Scalar_ Scalar;
39 typedef typename S1_::Scalar_ Scalar_;
40 // Confusing... But works! (Roman)
41
42 typedef S1_ S1;
43 typedef S2_ S2;
44
45 S1xS2() {};
46
47 static std::string name() { return S1_::name()+"⊗"+S2_::name(); }
48
49 static constexpr std::size_t Nq=S1_::Nq+S2_::Nq;
50
51 static constexpr bool HAS_CGC = false;
52 static constexpr bool NON_ABELIAN = S1_::NON_ABELIAN or S2_::NON_ABELIAN;
53 static constexpr bool ABELIAN = S1_::ABELIAN and S2_::ABELIAN;
54 static constexpr bool IS_TRIVIAL = S1_::IS_TRIVIAL and S2_::IS_TRIVIAL;
55 static constexpr bool IS_MODULAR = S1_::IS_MODULAR and S2_::IS_MODULAR;
56 static constexpr int MOD_N = S1_::MOD_N * S2_::MOD_N;
57
58 static constexpr bool IS_CHARGE_SU2() { return S1_::IS_CHARGE_SU2() or S2_::IS_CHARGE_SU2(); }
59 static constexpr bool IS_SPIN_SU2() { return S1_::IS_SPIN_SU2() or S2_::IS_SPIN_SU2(); }
60
61 static constexpr bool IS_SPIN_U1() { return S1_::IS_SPIN_U1() or S2_::IS_SPIN_U1(); }
62
63 static constexpr bool NO_SPIN_SYM() { return S1_::NO_SPIN_SYM() and S2_::NO_SPIN_SYM(); }
64 static constexpr bool NO_CHARGE_SYM() { return S1_::NO_CHARGE_SYM() and S2_::NO_CHARGE_SYM(); }
65
67
68 inline static constexpr std::array<KIND,Nq> kind() { return thirdparty::join(S1_::kind(),S2_::kind()); }
69 inline static constexpr std::array<int,Nq> mod() { return thirdparty::join(S1_::mod(),S2_::mod()); }
70
71 inline static constexpr qType qvacuum() { return join(S1_::qvacuum(),S2_::qvacuum()); }
72
73 inline static constexpr size_t lowest_qs_size = S1_::lowest_qs_size*S2_::lowest_qs_size; // for compatibility with g++-8
74 inline static constexpr std::array<qType,lowest_qs_size> lowest_qs() // S1_::lowest_qs().size()*S2_::lowest_qs().size()
75 {
76 std::array<qType,lowest_qs_size> out; // S1_::lowest_qs().size()*S2_::lowest_qs().size()
77 size_t index = 0;
78 for (const auto &q1 : S1_::lowest_qs())
79 for (const auto &q2 : S2_::lowest_qs())
80 {
81 out[index] = join(q1,q2);
82 index++;
83 }
84 return out;
85 }
86
87 inline static qType flip( const qType& q ) { auto [ql,qr] = disjoin<S1_::Nq,S2_::Nq>(q); return join(S1_::flip(ql),S2_::flip(qr)); }
88 inline static int degeneracy( const qType& q ) { auto [ql,qr] = disjoin<S1_::Nq,S2_::Nq>(q); return S1_::degeneracy(ql)*S2_::degeneracy(qr); }
89
90 inline static int spinorFactor() { return S1_::spinorFactor() * S2_::spinorFactor(); }
92
95 static std::vector<qType> reduceSilent(const qType& ql, const qType& qr);
100 static std::vector<qType> reduceSilent( const qType& ql, const qType& qm, const qType& qr);
106 static std::vector<qType> reduceSilent( const std::vector<qType>& ql, const qType& qr);
112 static std::vector<qType> reduceSilent( const std::vector<qType>& ql, const std::vector<qType>& qr, bool UNIQUE=false);
113
114 static vector<tuple<qarray<Nq>,size_t,qarray<Nq>,size_t,qarray<Nq> > > tensorProd ( const std::vector<qType>& ql, const std::vector<qType>& qr );
116
118
121 inline static Scalar coeff_unity();
122 inline static Scalar coeff_dot(const qType& q1);
123 inline static Scalar coeff_rightOrtho(const qType& q1, const qType& q2);
124 inline static Scalar coeff_leftSweep(const qType& q1, const qType& q2);
125
126 inline static Scalar coeff_swapPhase(const qType& q1, const qType& q2, const qType& q3);
127 inline static Scalar coeff_adjoint(const qType& q1, const qType& q2, const qType& q3);
128 inline static Scalar coeff_splitAA(const qType& q1, const qType& q2, const qType& q3);
129 inline static Scalar coeff_leftSweep2(const qType& q1, const qType& q2, const qType& q3);
130 inline static Scalar coeff_leftSweep3(const qType& q1, const qType& q2, const qType& q3);
131
132 static Scalar coeff_3j(const qType& q1, const qType& q2, const qType& q3,
133 int q1_z, int q2_z, int q3_z) {return 1.;}
134 static Scalar coeff_CGC(const qType& q1, const qType& q2, const qType& q3,
135 int q1_z, int q2_z, int q3_z) {return 1.;}
136
137 inline static Scalar coeff_6j(const qType& q1, const qType& q2, const qType& q3,
138 const qType& q4, const qType& q5, const qType& q6);
139 inline static Scalar coeff_Apair(const qType& q1, const qType& q2, const qType& q3,
140 const qType& q4, const qType& q5, const qType& q6);
141 static Scalar coeff_splitAA(const qType& q1, const qType& q2, const qType& q3,
142 const qType& q4, const qType& q5, const qType& q6);
143 inline static Scalar coeff_prod(const qType& q1, const qType& q2, const qType& q3,
144 const qType& q4, const qType& q5, const qType& q6);
145 inline static Scalar coeff_MPOprod6(const qType& q1, const qType& q2, const qType& q3,
146 const qType& q4, const qType& q5, const qType& q6);
147 static Scalar coeff_twoSiteGate(const qType& q1, const qType& q2, const qType& q3,
148 const qType& q4, const qType& q5, const qType& q6);
149
150 inline static Scalar coeff_9j(const qType& q1, const qType& q2, const qType& q3,
151 const qType& q4, const qType& q5, const qType& q6,
152 const qType& q7, const qType& q8, const qType& q9);
153 inline static Scalar coeff_tensorProd(const qType& q1, const qType& q2, const qType& q3,
154 const qType& q4, const qType& q5, const qType& q6,
155 const qType& q7, const qType& q8, const qType& q9);
156 inline static Scalar coeff_MPOprod9(const qType& q1, const qType& q2, const qType& q3,
157 const qType& q4, const qType& q5, const qType& q6,
158 const qType& q7, const qType& q8, const qType& q9);
159 inline static Scalar coeff_buildL(const qType& q1, const qType& q2, const qType& q3,
160 const qType& q4, const qType& q5, const qType& q6,
161 const qType& q7, const qType& q8, const qType& q9);
162 inline static Scalar coeff_buildR(const qType& q1, const qType& q2, const qType& q3,
163 const qType& q4, const qType& q5, const qType& q6,
164 const qType& q7, const qType& q8, const qType& q9);
165 inline static Scalar coeff_HPsi(const qType& q1, const qType& q2, const qType& q3,
166 const qType& q4, const qType& q5, const qType& q6,
167 const qType& q7, const qType& q8, const qType& q9);
168 inline static Scalar coeff_AW(const qType& q1, const qType& q2, const qType& q3,
169 const qType& q4, const qType& q5, const qType& q6,
170 const qType& q7, const qType& q8, const qType& q9);
172
177 template<std::size_t M>
178 static bool compare ( const std::array<qType,M>& q1, const std::array<qType,M>& q2 );
179
185 template<std::size_t M>
186 static bool validate( const std::array<qType,M>& qs );
187
188 static bool triangle( const std::array<qType,3>& qs );
189 static bool pair( const std::array<qType,2>& qs );
190
191};
192
193template<typename S1_, typename S2_>
194std::vector<typename S1xS2<S1_,S2_>::qType> S1xS2<S1_,S2_>::
195reduceSilent( const qType& ql, const qType& qr )
196{
197 auto [ql1,ql2] = disjoin<S1_::Nq,S2_::Nq>(ql);
198 auto [qr1,qr2] = disjoin<S1_::Nq,S2_::Nq>(qr);
199 std::vector<typename S1_::qType> firstSym = S1_::reduceSilent(ql1,qr1);
200 std::vector<typename S2_::qType> secondSym = S2_::reduceSilent(ql2,qr2);
201
202 std::vector<qType> vout;
203 for(const auto& q1:firstSym)
204 for(const auto& q2:secondSym)
205 {
206 vout.push_back(join(q1,q2));
207 }
208 return vout;
209}
210
211template<typename S1_, typename S2_>
212std::vector<typename S1xS2<S1_,S2_>::qType> S1xS2<S1_,S2_>::
213reduceSilent( const qType& ql, const qType& qm, const qType& qr )
214{
215 return reduceSilent(reduceSilent(ql,qm),qr);
216}
217
218template<typename S1_, typename S2_>
219std::vector<typename S1xS2<S1_,S2_>::qType> S1xS2<S1_,S2_>::
220reduceSilent( const std::vector<qType>& ql, const qType& qr )
221{
222 std::vector<qType> vout;
223
224 for (std::size_t q=0; q<ql.size(); q++)
225 {
226 auto [ql1,ql2] = disjoin<S1_::Nq,S2_::Nq>(ql[q]);
227 auto [qr1,qr2] = disjoin<S1_::Nq,S2_::Nq>(qr);
228
229 std::vector<typename S1_::qType> firstSym = S1_::reduceSilent(ql1,qr1);
230 std::vector<typename S2_::qType> secondSym = S2_::reduceSilent(ql2,qr2);
231
232 for(const auto& q1:firstSym)
233 for(const auto& q2:secondSym)
234 {
235 vout.push_back(join(q1,q2));
236 }
237 }
238
239 return vout;
240}
241
242template<typename S1_, typename S2_>
243std::vector<typename S1xS2<S1_,S2_>::qType> S1xS2<S1_,S2_>::
244reduceSilent( const std::vector<qType>& ql, const std::vector<qType>& qr, bool UNIQUE )
245{
246 std::vector<qType> vout;
247 std::unordered_set<qType> uniqueControl;
248
249 for (std::size_t q=0; q<ql.size(); q++)
250 for (std::size_t p=0; p<qr.size(); p++)
251 {
252 auto [ql1,ql2] = disjoin<S1_::Nq,S2_::Nq>(ql[q]);
253 auto [qr1,qr2] = disjoin<S1_::Nq,S2_::Nq>(qr[p]);
254 std::vector<typename S1_::qType> firstSym = S1_::reduceSilent(ql1,qr1);
255 std::vector<typename S2_::qType> secondSym = S2_::reduceSilent(ql2,qr2);
256
257 for(const auto& q1:firstSym)
258 for(const auto& q2:secondSym)
259 {
260 if (UNIQUE)
261 {
262 if( auto it = uniqueControl.find(join(q1,q2)) == uniqueControl.end() )
263 {
264 uniqueControl.insert(join(q1,q2));
265 vout.push_back(join(q1,q2));
266 }
267 }
268 else
269 {
270 vout.push_back(join(q1,q2));
271 }
272 }
273 }
274 return vout;
275}
276
277template<typename S1_, typename S2_>
278vector<tuple<qarray<S1xS2<S1_,S2_>::Nq>,size_t,qarray<S1xS2<S1_,S2_>::Nq>,size_t,qarray<S1xS2<S1_,S2_>::Nq> > > S1xS2<S1_,S2_>::
279tensorProd ( const std::vector<qType>& ql, const std::vector<qType>& qr )
280{
281 vector<tuple<qarray<Nq>,size_t,qarray<Nq>,size_t,qarray<Nq> > > out;
282 for (std::size_t q=0; q<ql.size(); q++)
283 for (std::size_t p=0; p<qr.size(); p++)
284 {
285 auto [ql1,ql2] = disjoin<S1_::Nq,S2_::Nq>(ql[q]);
286 auto [qr1,qr2] = disjoin<S1_::Nq,S2_::Nq>(qr[p]);
287 std::vector<typename S1_::qType> firstSym = S1_::reduceSilent(ql1,qr1);
288 std::vector<typename S2_::qType> secondSym = S2_::reduceSilent(ql2,qr2);
289
290
291 for(const auto& q1:firstSym)
292 for(const auto& q2:secondSym)
293 {
294 out.push_back(make_tuple(ql[q], q, qr[p], p, join(q1,q2)));
295 }
296 }
297 return out;
298}
299
300template<typename S1_, typename S2_>
301typename S1_::Scalar_ S1xS2<S1_,S2_>::
303{
304 Scalar out = Scalar(1.);
305 return out;
306}
307
308template<typename S1_, typename S2_>
309typename S1_::Scalar_ S1xS2<S1_,S2_>::
310coeff_dot(const qType& q1)
311{
312 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
313 Scalar out = S1_::coeff_dot(q1l)*S2_::coeff_dot(q1r);
314 return out;
315}
316
317template<typename S1_, typename S2_>
318typename S1_::Scalar_ S1xS2<S1_,S2_>::
319coeff_rightOrtho(const qType& q1, const qType& q2)
320{
321 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
322 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
323 Scalar out = S1_::coeff_rightOrtho(q1l,q2l)*S2_::coeff_rightOrtho(q1r,q2r);
324 return out;
325}
326
327template<typename S1_, typename S2_>
328typename S1_::Scalar_ S1xS2<S1_,S2_>::
329coeff_leftSweep(const qType& q1, const qType& q2)
330{
331 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
332 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
333 Scalar out = S1_::coeff_leftSweep(q1l,q2l)*S2_::coeff_leftSweep(q1r,q2r);
334 return out;
335}
336
337template<typename S1_, typename S2_>
338typename S1_::Scalar_ S1xS2<S1_,S2_>::
339coeff_swapPhase(const qType& q1, const qType& q2, const qType& q3)
340{
341 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
342 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
343 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
344 Scalar out = S1_::coeff_swapPhase(q1l,q2l,q3l)*S2_::coeff_swapPhase(q1r,q2r,q3r);
345 return out;
346}
347
348template<typename S1_, typename S2_>
349typename S1_::Scalar_ S1xS2<S1_,S2_>::
350coeff_adjoint(const qType& q1, const qType& q2, const qType& q3)
351{
352 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
353 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
354 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
355 Scalar out = S1_::coeff_adjoint(q1l,q2l,q3l)*S2_::coeff_adjoint(q1r,q2r,q3r);
356 return out;
357}
358
359template<typename S1_, typename S2_>
360typename S1_::Scalar_ S1xS2<S1_,S2_>::
361coeff_splitAA(const qType& q1, const qType& q2, const qType& q3)
362{
363 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
364 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
365 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
366 Scalar out = S1_::coeff_splitAA(q1l,q2l,q3l)*S2_::coeff_splitAA(q1r,q2r,q3r);
367 return out;
368}
369
370template<typename S1_, typename S2_>
371typename S1_::Scalar_ S1xS2<S1_,S2_>::
372coeff_leftSweep2(const qType& q1, const qType& q2, const qType& q3)
373{
374 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
375 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
376 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
377 Scalar out = S1_::coeff_leftSweep2(q1l,q2l,q3l)*S2_::coeff_leftSweep2(q1r,q2r,q3r);
378 return out;
379}
380
381template<typename S1_, typename S2_>
382typename S1_::Scalar_ S1xS2<S1_,S2_>::
383coeff_leftSweep3(const qType& q1, const qType& q2, const qType& q3)
384{
385 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
386 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
387 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
388 Scalar out = S1_::coeff_leftSweep3(q1l,q2l,q3l)*S2_::coeff_leftSweep3(q1r,q2r,q3r);
389 return out;
390}
391// template<typename S1_, typename S2_>
392// typename S1_::Scalar S1xS2<S1_,S2_>::
393// coeff_3j(const qType& q1, const qType& q2, const qType& q3,
394// int q1_z, int q2_z, int q3_z)
395// {
396// Scalar out = S1_::coeff_3j({q1[0]}, {q2[0]}, {q3[0]}, q1_z, q2_z, q3_z) * S2_::coeff_3j({q1[1]}, {q2[1]}, {q3[1]}, q1_z, q2_z, q3_z);
397// return out;
398// }
399
400// template<typename S1_, typename S2_>
401// typename S1_::Scalar S1xS2<S1_,S2_>::
402// coeff_CGC(const qType& q1, const qType& q2, const qType& q3,
403// int q1_z, int q2_z, int q3_z)
404// {
405// Scalar out = S1_::coeff_CGC({q1[0]}, {q2[0]}, {q3[0]}, q1_z, q2_z, q3_z) * S2_::coeff_CGC({q1[1]}, {q2[1]}, {q3[1]}, q1_z, q2_z, q3_z);
406// return out;
407// }
408
409template<typename S1_, typename S2_>
410typename S1_::Scalar_ S1xS2<S1_,S2_>::
411coeff_6j(const qType& q1, const qType& q2, const qType& q3,
412 const qType& q4, const qType& q5, const qType& q6)
413{
414 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
415 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
416 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
417 auto [q4l,q4r] = disjoin<S1_::Nq,S2_::Nq>(q4);
418 auto [q5l,q5r] = disjoin<S1_::Nq,S2_::Nq>(q5);
419 auto [q6l,q6r] = disjoin<S1_::Nq,S2_::Nq>(q6);
420
421 Scalar out=S1_::coeff_6j(q1l,q2l,q3l,
422 q4l,q5l,q6l)*
423 S2_::coeff_6j(q1r,q2r,q3r,
424 q4r,q5r,q6r);
425 return out;
426}
427
428template<typename S1_, typename S2_>
429typename S1_::Scalar_ S1xS2<S1_,S2_>::
430coeff_Apair(const qType& q1, const qType& q2, const qType& q3,
431 const qType& q4, const qType& q5, const qType& q6)
432{
433 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
434 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
435 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
436 auto [q4l,q4r] = disjoin<S1_::Nq,S2_::Nq>(q4);
437 auto [q5l,q5r] = disjoin<S1_::Nq,S2_::Nq>(q5);
438 auto [q6l,q6r] = disjoin<S1_::Nq,S2_::Nq>(q6);
439
440 Scalar out=S1_::coeff_Apair(q1l,q2l,q3l,
441 q4l,q5l,q6l)*
442 S2_::coeff_Apair(q1r,q2r,q3r,
443 q4r,q5r,q6r);
444 return out;
445}
446
447template<typename S1_, typename S2_>
448typename S1_::Scalar_ S1xS2<S1_,S2_>::
449coeff_splitAA(const qType& q1, const qType& q2, const qType& q3,
450 const qType& q4, const qType& q5, const qType& q6)
451{
452 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
453 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
454 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
455 auto [q4l,q4r] = disjoin<S1_::Nq,S2_::Nq>(q4);
456 auto [q5l,q5r] = disjoin<S1_::Nq,S2_::Nq>(q5);
457 auto [q6l,q6r] = disjoin<S1_::Nq,S2_::Nq>(q6);
458
459 Scalar out=S1_::coeff_splitAA(q1l,q2l,q3l,
460 q4l,q5l,q6l)*
461 S2_::coeff_splitAA(q1r,q2r,q3r,
462 q4r,q5r,q6r);
463 return out;
464}
465
466template<typename S1_, typename S2_>
467typename S1_::Scalar_ S1xS2<S1_,S2_>::
468coeff_prod(const qType& q1, const qType& q2, const qType& q3,
469 const qType& q4, const qType& q5, const qType& q6)
470{
471 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
472 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
473 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
474 auto [q4l,q4r] = disjoin<S1_::Nq,S2_::Nq>(q4);
475 auto [q5l,q5r] = disjoin<S1_::Nq,S2_::Nq>(q5);
476 auto [q6l,q6r] = disjoin<S1_::Nq,S2_::Nq>(q6);
477
478 Scalar out=S1_::coeff_prod(q1l,q2l,q3l,
479 q4l,q5l,q6l)*
480 S2_::coeff_prod(q1r,q2r,q3r,
481 q4r,q5r,q6r);
482 return out;
483}
484
485template<typename S1_, typename S2_>
486typename S1_::Scalar_ S1xS2<S1_,S2_>::
487coeff_MPOprod6(const qType& q1, const qType& q2, const qType& q3,
488 const qType& q4, const qType& q5, const qType& q6)
489{
490 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
491 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
492 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
493 auto [q4l,q4r] = disjoin<S1_::Nq,S2_::Nq>(q4);
494 auto [q5l,q5r] = disjoin<S1_::Nq,S2_::Nq>(q5);
495 auto [q6l,q6r] = disjoin<S1_::Nq,S2_::Nq>(q6);
496
497 Scalar out=S1_::coeff_MPOprod6(q1l,q2l,q3l,
498 q4l,q5l,q6l)*
499 S2_::coeff_MPOprod6(q1r,q2r,q3r,
500 q4r,q5r,q6r);
501 return out;
502}
503
504template<typename S1_, typename S2_>
505typename S1_::Scalar_ S1xS2<S1_,S2_>::
506coeff_twoSiteGate(const qType& q1, const qType& q2, const qType& q3,
507 const qType& q4, const qType& q5, const qType& q6)
508{
509 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
510 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
511 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
512 auto [q4l,q4r] = disjoin<S1_::Nq,S2_::Nq>(q4);
513 auto [q5l,q5r] = disjoin<S1_::Nq,S2_::Nq>(q5);
514 auto [q6l,q6r] = disjoin<S1_::Nq,S2_::Nq>(q6);
515
516 Scalar out=S1_::coeff_twoSiteGate(q1l,q2l,q3l,
517 q4l,q5l,q6l)*
518 S2_::coeff_twoSiteGate(q1r,q2r,q3r,
519 q4r,q5r,q6r);
520 return out;
521}
522
523template<typename S1_, typename S2_>
524typename S1_::Scalar_ S1xS2<S1_,S2_>::
525coeff_9j(const qType& q1, const qType& q2, const qType& q3,
526 const qType& q4, const qType& q5, const qType& q6,
527 const qType& q7, const qType& q8, const qType& q9)
528{
529 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
530 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
531 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
532 auto [q4l,q4r] = disjoin<S1_::Nq,S2_::Nq>(q4);
533 auto [q5l,q5r] = disjoin<S1_::Nq,S2_::Nq>(q5);
534 auto [q6l,q6r] = disjoin<S1_::Nq,S2_::Nq>(q6);
535 auto [q7l,q7r] = disjoin<S1_::Nq,S2_::Nq>(q7);
536 auto [q8l,q8r] = disjoin<S1_::Nq,S2_::Nq>(q8);
537 auto [q9l,q9r] = disjoin<S1_::Nq,S2_::Nq>(q9);
538
539 Scalar out=S1_::coeff_9j(q1l,q2l,q3l,
540 q4l,q5l,q6l,
541 q7l,q8l,q9l)*
542 S2_::coeff_9j(q1r,q2r,q3r,
543 q4r,q5r,q6r,
544 q7r,q8r,q9r);
545 return out;
546}
547
548template<typename S1_, typename S2_>
549typename S1_::Scalar_ S1xS2<S1_,S2_>::
550coeff_tensorProd(const qType& q1, const qType& q2, const qType& q3,
551 const qType& q4, const qType& q5, const qType& q6,
552 const qType& q7, const qType& q8, const qType& q9)
553{
554 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
555 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
556 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
557 auto [q4l,q4r] = disjoin<S1_::Nq,S2_::Nq>(q4);
558 auto [q5l,q5r] = disjoin<S1_::Nq,S2_::Nq>(q5);
559 auto [q6l,q6r] = disjoin<S1_::Nq,S2_::Nq>(q6);
560 auto [q7l,q7r] = disjoin<S1_::Nq,S2_::Nq>(q7);
561 auto [q8l,q8r] = disjoin<S1_::Nq,S2_::Nq>(q8);
562 auto [q9l,q9r] = disjoin<S1_::Nq,S2_::Nq>(q9);
563
564 Scalar out=S1_::coeff_tensorProd(q1l,q2l,q3l,
565 q4l,q5l,q6l,
566 q7l,q8l,q9l)*
567 S2_::coeff_tensorProd(q1r,q2r,q3r,
568 q4r,q5r,q6r,
569 q7r,q8r,q9r);
570 return out;
571}
572
573template<typename S1_, typename S2_>
574typename S1_::Scalar_ S1xS2<S1_,S2_>::
575coeff_MPOprod9(const qType& q1, const qType& q2, const qType& q3,
576 const qType& q4, const qType& q5, const qType& q6,
577 const qType& q7, const qType& q8, const qType& q9)
578{
579 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
580 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
581 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
582 auto [q4l,q4r] = disjoin<S1_::Nq,S2_::Nq>(q4);
583 auto [q5l,q5r] = disjoin<S1_::Nq,S2_::Nq>(q5);
584 auto [q6l,q6r] = disjoin<S1_::Nq,S2_::Nq>(q6);
585 auto [q7l,q7r] = disjoin<S1_::Nq,S2_::Nq>(q7);
586 auto [q8l,q8r] = disjoin<S1_::Nq,S2_::Nq>(q8);
587 auto [q9l,q9r] = disjoin<S1_::Nq,S2_::Nq>(q9);
588
589 Scalar out=S1_::coeff_MPOprod9(q1l,q2l,q3l,
590 q4l,q5l,q6l,
591 q7l,q8l,q9l)*
592 S2_::coeff_MPOprod9(q1r,q2r,q3r,
593 q4r,q5r,q6r,
594 q7r,q8r,q9r);
595 return out;
596}
597
598template<typename S1_, typename S2_>
599typename S1_::Scalar_ S1xS2<S1_,S2_>::
600coeff_buildL(const qType& q1, const qType& q2, const qType& q3,
601 const qType& q4, const qType& q5, const qType& q6,
602 const qType& q7, const qType& q8, const qType& q9)
603{
604 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
605 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
606 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
607 auto [q4l,q4r] = disjoin<S1_::Nq,S2_::Nq>(q4);
608 auto [q5l,q5r] = disjoin<S1_::Nq,S2_::Nq>(q5);
609 auto [q6l,q6r] = disjoin<S1_::Nq,S2_::Nq>(q6);
610 auto [q7l,q7r] = disjoin<S1_::Nq,S2_::Nq>(q7);
611 auto [q8l,q8r] = disjoin<S1_::Nq,S2_::Nq>(q8);
612 auto [q9l,q9r] = disjoin<S1_::Nq,S2_::Nq>(q9);
613
614 Scalar out=S1_::coeff_buildL(q1l,q2l,q3l,
615 q4l,q5l,q6l,
616 q7l,q8l,q9l)*
617 S2_::coeff_buildL(q1r,q2r,q3r,
618 q4r,q5r,q6r,
619 q7r,q8r,q9r);
620 return out;
621}
622
623template<typename S1_, typename S2_>
624typename S1_::Scalar_ S1xS2<S1_,S2_>::
625coeff_buildR(const qType& q1, const qType& q2, const qType& q3,
626 const qType& q4, const qType& q5, const qType& q6,
627 const qType& q7, const qType& q8, const qType& q9)
628{
629 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
630 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
631 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
632 auto [q4l,q4r] = disjoin<S1_::Nq,S2_::Nq>(q4);
633 auto [q5l,q5r] = disjoin<S1_::Nq,S2_::Nq>(q5);
634 auto [q6l,q6r] = disjoin<S1_::Nq,S2_::Nq>(q6);
635 auto [q7l,q7r] = disjoin<S1_::Nq,S2_::Nq>(q7);
636 auto [q8l,q8r] = disjoin<S1_::Nq,S2_::Nq>(q8);
637 auto [q9l,q9r] = disjoin<S1_::Nq,S2_::Nq>(q9);
638
639 Scalar out=S1_::coeff_buildR(q1l,q2l,q3l,
640 q4l,q5l,q6l,
641 q7l,q8l,q9l)*
642 S2_::coeff_buildR(q1r,q2r,q3r,
643 q4r,q5r,q6r,
644 q7r,q8r,q9r);
645 return out;
646}
647
648template<typename S1_, typename S2_>
649typename S1_::Scalar_ S1xS2<S1_,S2_>::
650coeff_HPsi(const qType& q1, const qType& q2, const qType& q3,
651 const qType& q4, const qType& q5, const qType& q6,
652 const qType& q7, const qType& q8, const qType& q9)
653{
654 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
655 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
656 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
657 auto [q4l,q4r] = disjoin<S1_::Nq,S2_::Nq>(q4);
658 auto [q5l,q5r] = disjoin<S1_::Nq,S2_::Nq>(q5);
659 auto [q6l,q6r] = disjoin<S1_::Nq,S2_::Nq>(q6);
660 auto [q7l,q7r] = disjoin<S1_::Nq,S2_::Nq>(q7);
661 auto [q8l,q8r] = disjoin<S1_::Nq,S2_::Nq>(q8);
662 auto [q9l,q9r] = disjoin<S1_::Nq,S2_::Nq>(q9);
663
664 Scalar out=S1_::coeff_HPsi(q1l,q2l,q3l,
665 q4l,q5l,q6l,
666 q7l,q8l,q9l)*
667 S2_::coeff_HPsi(q1r,q2r,q3r,
668 q4r,q5r,q6r,
669 q7r,q8r,q9r);
670 return out;
671}
672
673template<typename S1_, typename S2_>
674typename S1_::Scalar_ S1xS2<S1_,S2_>::
675coeff_AW(const qType& q1, const qType& q2, const qType& q3,
676 const qType& q4, const qType& q5, const qType& q6,
677 const qType& q7, const qType& q8, const qType& q9)
678{
679 auto [q1l,q1r] = disjoin<S1_::Nq,S2_::Nq>(q1);
680 auto [q2l,q2r] = disjoin<S1_::Nq,S2_::Nq>(q2);
681 auto [q3l,q3r] = disjoin<S1_::Nq,S2_::Nq>(q3);
682 auto [q4l,q4r] = disjoin<S1_::Nq,S2_::Nq>(q4);
683 auto [q5l,q5r] = disjoin<S1_::Nq,S2_::Nq>(q5);
684 auto [q6l,q6r] = disjoin<S1_::Nq,S2_::Nq>(q6);
685 auto [q7l,q7r] = disjoin<S1_::Nq,S2_::Nq>(q7);
686 auto [q8l,q8r] = disjoin<S1_::Nq,S2_::Nq>(q8);
687 auto [q9l,q9r] = disjoin<S1_::Nq,S2_::Nq>(q9);
688
689 Scalar out=S1_::coeff_AW(q1l,q2l,q3l,
690 q4l,q5l,q6l,
691 q7l,q8l,q9l)*
692 S2_::coeff_AW(q1r,q2r,q3r,
693 q4r,q5r,q6r,
694 q7r,q8r,q9r);
695 return out;
696}
697
698template<typename S1_, typename S2_>
699template<std::size_t M>
701compare ( const std::array<S1xS2<S1_,S2_>::qType,M>& q1, const std::array<S1xS2<S1_,S2_>::qType,M>& q2 )
702{
703 for (std::size_t m=0; m<M; m++)
704 {
705 if (q1[m] > q2[m]) { return false; }
706 else if (q1[m] < q2[m]) {return true; }
707 }
708 return false;
709
710 // std::array<typename S1_::qType,M> q1l;
711 // std::array<typename S1_::qType,M> q2l;
712 // std::array<typename S2_::qType,M> q1r;
713 // std::array<typename S2_::qType,M> q2r;
714
715 // for (std::size_t m=0; m<M; m++)
716 // {
717 // auto [q1ll,q1rr] = disjoin<S1_::Nq,S2_::Nq>(q1[m]);
718 // auto [q2ll,q2rr] = disjoin<S1_::Nq,S2_::Nq>(q2[m]);
719 // q1l[m] = q1ll;
720 // q2l[m] = q2ll;
721 // q1r[m] = q1rr;
722 // q2r[m] = q2rr;
723 // }
724 // bool b1 = S1_::compare(q1l,q2l);
725 // if (b1) {return b1;}
726 // return S2_::compare(q1r,q2r);
727}
728
729template<typename S1_, typename S2_>
731triangle ( const std::array<S1xS2<S1_,S2_>::qType,3>& qs )
732{
733 qarray3<S1_::Nq> q_frstSym;
734 qarray3<S2_::Nq> q_secdSym;
735
736 for (size_t q=0; q<3; q++)
737 {
738 auto [q1,q2] = disjoin<S1_::Nq,S2_::Nq>(qs[q]);
739 q_frstSym[q] = q1;
740 q_secdSym[q] = q2;
741 }
742 return (S1_::triangle(q_frstSym) and S2_::triangle(q_secdSym));
743}
744
745template<typename S1_, typename S2_>
747pair ( const std::array<S1xS2<S1_,S2_>::qType,2>& qs )
748{
749 qarray2<S1_::Nq> q_frstSym;
750 qarray2<S2_::Nq> q_secdSym;
751
752 for (size_t q=0; q<2; q++)
753 {
754 auto [q1,q2] = disjoin<S1_::Nq,S2_::Nq>(qs[q]);
755 q_frstSym[q] = q1;
756 q_secdSym[q] = q2;
757 }
758 return (S1_::pair(q_frstSym) and S2_::pair(q_secdSym));
759}
760
761template<typename S1_, typename S2_>
762template<std::size_t M>
764validate ( const std::array<S1xS2<S1_,S2_>::qType,M>& qs )
765{
766 if constexpr( M == 1 ) { return true; }
767 else if constexpr( M == 2 ) { return S1xS2<S1_,S2_>::pair(qs); }
768 else if constexpr( M==3 ) { return S1xS2<S1_,S2_>::triangle(qs); }
769 else { cout << "This should not be printed out!" << endl; return true; }
770}
771
772} //end namespace Sym
773
774#endif //end S1xS2_H_
static vector< tuple< qarray< Nq >, size_t, qarray< Nq >, size_t, qarray< Nq > > > tensorProd(const std::vector< qType > &ql, const std::vector< qType > &qr)
Definition: S1xS2.h:279
static constexpr std::array< KIND, Nq > kind()
Definition: S1xS2.h:68
static bool compare(const std::array< qType, M > &q1, const std::array< qType, M > &q2)
static Scalar coeff_buildR(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6, const qType &q7, const qType &q8, const qType &q9)
Definition: S1xS2.h:625
static constexpr int MOD_N
Definition: S1xS2.h:56
static Scalar coeff_twoSiteGate(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6)
Definition: S1xS2.h:506
static constexpr bool ABELIAN
Definition: S1xS2.h:53
static constexpr std::size_t Nq
Definition: S1xS2.h:49
S1_::Scalar_ Scalar_
Definition: S1xS2.h:39
static Scalar coeff_adjoint(const qType &q1, const qType &q2, const qType &q3)
Definition: S1xS2.h:350
static constexpr std::array< int, Nq > mod()
Definition: S1xS2.h:69
static constexpr std::array< qType, lowest_qs_size > lowest_qs()
Definition: S1xS2.h:74
static Scalar coeff_prod(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6)
Definition: S1xS2.h:468
static constexpr bool IS_SPIN_U1()
Definition: S1xS2.h:61
static bool triangle(const std::array< qType, 3 > &qs)
Definition: S1xS2.h:731
static Scalar coeff_Apair(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6)
Definition: S1xS2.h:430
S2_ S2
Definition: S1xS2.h:43
static qType flip(const qType &q)
Definition: S1xS2.h:87
static Scalar coeff_9j(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6, const qType &q7, const qType &q8, const qType &q9)
Definition: S1xS2.h:525
S1xS2()
Definition: S1xS2.h:45
static Scalar coeff_leftSweep2(const qType &q1, const qType &q2, const qType &q3)
Definition: S1xS2.h:372
static Scalar coeff_tensorProd(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6, const qType &q7, const qType &q8, const qType &q9)
Definition: S1xS2.h:550
static constexpr bool NON_ABELIAN
Definition: S1xS2.h:52
static Scalar coeff_unity()
Definition: S1xS2.h:302
static constexpr bool IS_MODULAR
Definition: S1xS2.h:55
qarray< Nq > qType
Definition: S1xS2.h:66
static bool validate(const std::array< qType, M > &qs)
static Scalar coeff_MPOprod6(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6)
Definition: S1xS2.h:487
static Scalar coeff_MPOprod9(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6, const qType &q7, const qType &q8, const qType &q9)
Definition: S1xS2.h:575
static int degeneracy(const qType &q)
Definition: S1xS2.h:88
static constexpr bool HAS_CGC
Definition: S1xS2.h:51
static Scalar coeff_AW(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6, const qType &q7, const qType &q8, const qType &q9)
Definition: S1xS2.h:675
static constexpr bool IS_CHARGE_SU2()
Definition: S1xS2.h:58
static Scalar coeff_buildL(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6, const qType &q7, const qType &q8, const qType &q9)
Definition: S1xS2.h:600
static Scalar coeff_leftSweep3(const qType &q1, const qType &q2, const qType &q3)
Definition: S1xS2.h:383
static Scalar coeff_rightOrtho(const qType &q1, const qType &q2)
Definition: S1xS2.h:319
static int spinorFactor()
Definition: S1xS2.h:90
static bool pair(const std::array< qType, 2 > &qs)
Definition: S1xS2.h:747
static std::vector< qType > reduceSilent(const qType &ql, const qType &qr)
Definition: S1xS2.h:195
static Scalar coeff_CGC(const qType &q1, const qType &q2, const qType &q3, int q1_z, int q2_z, int q3_z)
Definition: S1xS2.h:134
static Scalar coeff_dot(const qType &q1)
Definition: S1xS2.h:310
static constexpr bool IS_TRIVIAL
Definition: S1xS2.h:54
static Scalar coeff_HPsi(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6, const qType &q7, const qType &q8, const qType &q9)
Definition: S1xS2.h:650
static constexpr bool NO_CHARGE_SYM()
Definition: S1xS2.h:64
static Scalar coeff_splitAA(const qType &q1, const qType &q2, const qType &q3)
Definition: S1xS2.h:361
static constexpr bool NO_SPIN_SYM()
Definition: S1xS2.h:63
S1_::Scalar_ Scalar
Definition: S1xS2.h:38
static constexpr size_t lowest_qs_size
Definition: S1xS2.h:73
static constexpr qType qvacuum()
Definition: S1xS2.h:71
static Scalar coeff_leftSweep(const qType &q1, const qType &q2)
Definition: S1xS2.h:329
static Scalar coeff_swapPhase(const qType &q1, const qType &q2, const qType &q3)
Definition: S1xS2.h:339
static Scalar coeff_3j(const qType &q1, const qType &q2, const qType &q3, int q1_z, int q2_z, int q3_z)
Definition: S1xS2.h:132
static constexpr bool IS_SPIN_SU2()
Definition: S1xS2.h:59
static std::string name()
Definition: S1xS2.h:47
S1_ S1
Definition: S1xS2.h:42
static Scalar coeff_6j(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6)
Definition: S1xS2.h:411
std::array< qarray< Nq >, 2 > qarray2
Definition: qarray.h:51
std::array< qarray< Nq >, 3 > qarray3
Definition: qarray.h:52
constexpr qarray< Nq1+Nq2 > join(qarray< Nq1 > rhs, qarray< Nq2 > lhs)
Definition: qarray.h:95
Definition: qarray.h:26