7#include <unordered_set>
8#include <unordered_map>
11#include <boost/rational.hpp>
34template<
typename Kind,
typename Scalar=
double>
40 static constexpr std::size_t
Nq=1;
61 inline static std::string
name() {
return "SU2"; }
62 inline static constexpr std::array<KIND,Nq>
kind() {
return {Kind::name}; }
63 inline static constexpr std::array<int,Nq>
mod() {
return {
MOD_N}; }
68 inline static constexpr std::array<qType,1>
lowest_qs() {
return std::array<qType,1> {{
qarray<1>(std::array<int,1>{{2}}) }}; }
87 static std::vector<qType>
reduceSilent(
const std::vector<qType>& ql,
const qType& qr);
93 static std::vector<qType>
reduceSilent(
const std::vector<qType>& ql,
const std::vector<qType>& qr,
bool UNIQUE=
false);
95 static vector<tuple<qarray<1>,size_t,
qarray<1>,size_t,
qarray<1> > >
tensorProd (
const std::vector<qType>& ql,
const std::vector<qType>& qr );
115 int q1_z,
int q2_z,
int q3_z);
117 int q1_z,
int q2_z,
int q3_z);
159 template<std::
size_t M>
160 static bool compare (
const std::array<qType,M>& q1,
const std::array<qType,M>& q2 );
167 template<std::
size_t M>
168 static bool validate(
const std::array<qType,M>& qs );
170 static bool triangle(
const std::array<qType,3>& qs );
171 static bool pair(
const std::array<qType,2>& qs );
174template<
typename Kind,
typename Scalar>
178 std::vector<qType> vout;
179 int qmin = std::abs(ql[0]-qr[0]) +1;
180 int qmax = std::abs(ql[0]+qr[0]) -1;
181 for (
int i=qmin; i<=qmax; i+=2 ) { vout.push_back({i}); }
185template<
typename Kind,
typename Scalar>
189 auto qtmp = reduceSilent(ql,qm);
190 return reduceSilent(qtmp,qr);
193template<
typename Kind,
typename Scalar>
197 std::vector<typename SU2<Kind,Scalar>::qType> vout;
198 for (std::size_t q=0; q<ql.size(); q++)
200 int qmin = std::abs(ql[q][0]-qr[0]) +1;
201 int qmax = std::abs(ql[q][0]+qr[0]) -1;
202 for (
int i=qmin; i<=qmax; i+=2 ) { vout.push_back({i}); }
207template<
typename Kind,
typename Scalar>
209reduceSilent(
const std::vector<qType>& ql,
const std::vector<qType>& qr,
bool UNIQUE )
213 std::unordered_set<qType> uniqueControl;
214 std::vector<qType> vout;
215 for (std::size_t q1=0; q1<ql.size(); q1++)
216 for (std::size_t q2=0; q2<qr.size(); q2++)
218 int qmin = std::abs(ql[q1][0]-qr[q2][0]) +1;
219 int qmax = std::abs(ql[q1][0]+qr[q2][0]) -1;
220 for (
int i=qmin; i<=qmax; i+=2 )
222 if(
auto it = uniqueControl.find({i}) == uniqueControl.end() ) {uniqueControl.insert({i}); vout.push_back({i});}
229 std::vector<qType> vout;
230 for (std::size_t q1=0; q1<ql.size(); q1++)
231 for (std::size_t q2=0; q2<qr.size(); q2++)
233 int qmin = std::abs(ql[q1][0]-qr[q2][0]) +1;
234 int qmax = std::abs(ql[q1][0]+qr[q2][0]) -1;
235 for (
int i=qmin; i<=qmax; i+=2 ) { vout.push_back({i}); }
241template<
typename Kind,
typename Scalar>
243tensorProd (
const std::vector<qType>& ql,
const std::vector<qType>& qr )
263 for (std::size_t q1=0; q1<ql.size(); q1++)
264 for (std::size_t q2=0; q2<qr.size(); q2++)
266 int qmin = std::abs(ql[q1][0]-qr[q2][0]) + 1;
267 int qmax = std::abs(ql[q1][0]+qr[q2][0]) - 1;
268 for (
int i=qmin; i<=qmax; i+=2)
270 out.push_back(make_tuple(ql[q1], q1, qr[q2], q2,
qarray<1>{i}));
276template<
typename Kind,
typename Scalar>
280 Scalar out = Scalar(1.);
284template<
typename Kind,
typename Scalar>
288 Scalar out =
static_cast<Scalar
>(q1[0]);
292template<
typename Kind,
typename Scalar>
296 Scalar out =
static_cast<Scalar
>(q1[0]) /
static_cast<Scalar
>(q2[0]);
300template<
typename Kind,
typename Scalar>
304 Scalar out = std::sqrt(
static_cast<Scalar
>(q1[0]) /
static_cast<Scalar
>(q2[0]));
308template<
typename Kind,
typename Scalar>
312 Scalar out = phase<Scalar>((q1[0]-q2[0]+q3[0]-1) / 2) *
313 std::sqrt(
static_cast<Scalar
>(q1[0])) / std::sqrt(
static_cast<Scalar
>(q2[0]));
317template<
typename Kind,
typename Scalar>
321 Scalar out = phase<Scalar>((q1[0]-q2[0]-q3[0]-1) / 2) *
322 std::sqrt(
static_cast<Scalar
>(q1[0])) / std::sqrt(
static_cast<Scalar
>(q2[0]));
326template<
typename Kind,
typename Scalar>
330 Scalar out = phase<Scalar>((q1[0]+q2[0]-q3[0]-3) /2);
334template<
typename Kind,
typename Scalar>
338 Scalar out = phase<Scalar>((q3[0]+q1[0]-q2[0]-1) / 2) *
339 std::sqrt(
static_cast<Scalar
>(q1[0])) / std::sqrt(
static_cast<Scalar
>(q2[0]));
343template<
typename Kind,
typename Scalar>
347 Scalar out = phase<Scalar>((q1[0]-q2[0]-q3[0]-3) / 2) *
348 std::sqrt(
static_cast<Scalar
>(q1[0])) / std::sqrt(
static_cast<Scalar
>(q2[0]));
353template<
typename Kind,
typename Scalar>
356 int q1_z,
int q2_z,
int q3_z)
363template<
typename Kind,
typename Scalar>
366 int q1_z,
int q2_z,
int q3_z)
372 q1_z , q2_z , -q3_z) *
373 phase<Scalar>((q1[0]-q2[0]+q3_z)/2) * sqrt(q3[0]);
378template<
typename Kind,
typename Scalar>
388template<
typename Kind,
typename Scalar>
393 Scalar out =
coupling_6j(q1[0],q2[0],q3[0],q4[0],q5[0],q6[0])*
394 std::sqrt(
static_cast<Scalar
>(q3[0]*q6[0]))
395 *phase<Scalar>((q1[0]+q2[0]+q4[0]+q5[0]-4)/2);
399template<
typename Kind,
typename Scalar>
404 Scalar out =
coupling_6j(q1[0],q2[0],q3[0],q4[0],q5[0],q6[0])*
405 std::sqrt(
static_cast<Scalar
>(q2[0]*q3[0]))
406 *phase<Scalar>((q1[0]+q5[0]+q6[0]-3)/2);
410template<
typename Kind,
typename Scalar>
415 Scalar out =
coupling_6j(q1[0],q2[0],q3[0],q4[0],q5[0],q6[0])*
416 std::sqrt(
static_cast<Scalar
>(q3[0]*q6[0]))*
417 phase<Scalar>((q1[0]+q5[0]+q6[0]-3)/2);
421template<
typename Kind,
typename Scalar>
426 Scalar out =
coupling_6j(q1[0],q2[0],q3[0],q4[0],q5[0],q6[0])*
427 std::sqrt(
static_cast<Scalar
>(q3[0]*q6[0]))*
428 phase<Scalar>((q1[0]+q2[0]+q4[0]+q5[0]-4)/2);
432template<
typename Kind,
typename Scalar>
437 Scalar out =
coupling_6j(q1[0],q2[0],q3[0],q4[0],q5[0],q6[0])*
438 std::sqrt(
static_cast<Scalar
>(q3[0]*q6[0]))
439 *phase<Scalar>((q1[0]+q2[0]+q4[0]+q5[0]-4)/2);
443template<
typename Kind,
typename Scalar>
455template<
typename Kind,
typename Scalar>
464 std::sqrt(
static_cast<Scalar
>(q7[0]*q8[0]*q3[0]*q6[0]));
468template<
typename Kind,
typename Scalar>
477 std::sqrt(
static_cast<Scalar
>(q7[0]*q8[0]*q3[0]*q6[0]));
481template<
typename Kind,
typename Scalar>
490 std::sqrt(
static_cast<Scalar
>(q7[0]*q8[0]*q3[0]*q6[0]));
494template<
typename Kind,
typename Scalar>
503 std::sqrt(
static_cast<Scalar
>(q7[0]*q8[0]*q3[0]*q6[0])) *
504 static_cast<Scalar
>(q9[0]) /
static_cast<Scalar
>(q7[0]);
508template<
typename Kind,
typename Scalar>
517 std::sqrt(
static_cast<Scalar
>(q7[0]*q8[0]*q3[0]*q6[0]));
521template<
typename Kind,
typename Scalar>
530 std::sqrt(
static_cast<Scalar
>(q7[0]*q8[0]*q3[0]*q6[0]));
534template<
typename Kind,
typename Scalar>
535template<std::
size_t M>
539 for (std::size_t m=0; m<
M; m++)
541 if (q1[m][0] > q2[m][0]) {
return false; }
542 else if (q1[m][0] < q2[m][0]) {
return true; }
547template<
typename Kind,
typename Scalar>
552 if (qs[2][0]-1 >= abs(qs[0][0]-qs[1][0]) and qs[2][0]-1 <= qs[0][0]+qs[1][0]-2) {
return true;}
556template<
typename Kind,
typename Scalar>
561 if (qs[0] == qs[1]) {
return true;}
565template<
typename Kind,
typename Scalar>
566template<std::
size_t M>
570 if constexpr(
M == 1 ) {
return true; }
573 else { cout <<
"This should not be printed out!" << endl;
return true; }
double coupling_9j(const int q1, const int q2, const int q3, const int q4, const int q5, const int q6, const int q7, const int q8, const int q9)
double coupling_3j(const int q1, const int q2, const int q3, const int q1_z, const int q2_z, const int q3_z)
double coupling_6j(const int q1, const int q2, const int q3, const int q4, const int q5, const int q6)
static constexpr int MOD_N
static vector< tuple< qarray< 1 >, size_t, qarray< 1 >, size_t, qarray< 1 > > > tensorProd(const std::vector< qType > &ql, const std::vector< qType > &qr)
static Scalar coeff_leftSweep2(const qType &q1, const qType &q2, const qType &q3)
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)
static bool compare(const std::array< qType, M > &q1, const std::array< qType, M > &q2)
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)
static Scalar coeff_adjoint(const qType &q1, const qType &q2, const qType &q3)
static Scalar coeff_CGC(const qType &q1, const qType &q2, const qType &q3, int q1_z, int q2_z, int q3_z)
static constexpr std::array< qType, 1 > lowest_qs()
static bool triangle(const std::array< qType, 3 > &qs)
static constexpr bool HAS_CGC
static Scalar coeff_leftSweep(const qType &q1, const qType &q2)
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)
static int degeneracy(const qType &q)
static constexpr bool ABELIAN
static constexpr size_t lowest_qs_size
static constexpr bool IS_TRIVIAL
static constexpr qType qvacuum()
static qType flip(const qType &q)
static bool pair(const std::array< qType, 2 > &qs)
static Scalar coeff_6j(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6)
static Scalar coeff_dot(const qType &q1)
static bool validate(const std::array< qType, M > &qs)
static constexpr bool IS_SPIN_SU2()
static constexpr std::array< int, Nq > mod()
static int spinorFactor()
static Scalar coeff_Apair(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6)
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)
static Scalar coeff_prod(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6)
static constexpr bool NO_CHARGE_SYM()
static constexpr bool NON_ABELIAN
static Scalar coeff_swapPhase(const qType &q1, const qType &q2, const qType &q3)
static constexpr bool NO_SPIN_SYM()
static constexpr bool IS_CHARGE_SU2()
static Scalar coeff_MPOprod6(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6)
static constexpr bool IS_MODULAR
static std::vector< qType > reduceSilent(const qType &ql, const qType &qr)
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)
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)
static constexpr bool IS_SPIN_U1()
static std::string name()
static Scalar coeff_leftSweep3(const qType &q1, const qType &q2, const qType &q3)
static constexpr std::array< KIND, Nq > kind()
static constexpr std::size_t Nq
static Scalar coeff_splitAA(const qType &q1, const qType &q2, const qType &q3)
static Scalar coeff_3j(const qType &q1, const qType &q2, const qType &q3, int q1_z, int q2_z, int q3_z)
static Scalar coeff_twoSiteGate(const qType &q1, const qType &q2, const qType &q3, const qType &q4, const qType &q5, const qType &q6)
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)
static Scalar coeff_unity()
static Scalar coeff_rightOrtho(const qType &q1, const qType &q2)