Cytnx v1.0.0
Loading...
Searching...
No Matches
Symmetry.hpp
Go to the documentation of this file.
1#ifndef CYTNX_SYMMETRY_H_
2#define CYTNX_SYMMETRY_H_
3
4#include <fstream>
5#include <ostream>
6#include <string>
7#include <variant>
8#include <vector>
9
10#include "cytnx_error.hpp"
11#include "Type.hpp"
12#include "utils/dynamic_arg_resolver.hpp"
13
14namespace cytnx {
30 enum SymmetryType : int { Void = -99, U = -1, Z = 0, fPar = -2, fNum = -3 };
31
38 enum fermionParity : bool { EVEN = false, ODD = true };
39
40 // helper class, has implicitly conversion to std::vector<int64>!
41 class Qs {
42 private:
43 std::vector<cytnx_int64> tmpQs;
44
45 public:
46 template <class... Ts>
47 Qs(const cytnx_int64 &e1, const Ts... elems) {
48 this->tmpQs = dynamic_arg_int64_resolver(e1, elems...);
49 }
50
51 Qs(const std::vector<cytnx_int64> &qin) { this->tmpQs = qin; }
52
53 // interprete as 2d vector directly implicitly convert!
54 explicit operator std::vector<cytnx_int64>() const { return this->tmpQs; };
55
56 std::pair<std::vector<cytnx_int64>, cytnx_uint64> operator>>(const cytnx_uint64 &dim) {
57 return std::make_pair(this->tmpQs, dim);
58 }
59 };
60
61 //=====================================
62 // Symmetry kinds (std::variant alternatives).
63 //
64 // Symmetry is a plain value type: the active kind lives inline in a
65 // std::variant and every public method of Symmetry dispatches with
66 // std::visit. The visit lambdas are the completeness contract: adding a new
67 // alternative to Symmetry::kind_variant that does not implement the full
68 // rule set below fails to compile.
69 //
70 // Each kind keeps the legacy `n` field with the value the previous
71 // intrusive-ptr implementation stored (U1: 1, Zn: n, fPar: -2, fNum: -1);
72 // it backs Symmetry::n() and the Save/Load binary format.
73
75 class U1Symmetry {
76 public:
77 // mutable: backs the legacy `int &n() const` accessor of Symmetry.
78 mutable int n;
79 static constexpr int stype_id = SymmetryType::U;
80
81 U1Symmetry() : n(1) {}
82
83 bool check_qnum(const cytnx_int64 &in_qnum) const;
84 bool check_qnums(const std::vector<cytnx_int64> &in_qnums) const;
85 void combine_rule_(std::vector<cytnx_int64> &out, const std::vector<cytnx_int64> &inL,
86 const std::vector<cytnx_int64> &inR) const;
87 void combine_rule_(cytnx_int64 &out, const cytnx_int64 &inL, const cytnx_int64 &inR,
88 const bool &is_reverse) const;
89 void reverse_rule_(cytnx_int64 &out, const cytnx_int64 &in) const;
90 fermionParity get_fermion_parity(const cytnx_int64 &in_qnum) const;
91 bool is_fermionic() const { return false; }
92 void print_info() const;
93 std::string stype_str() const { return "U1"; }
94 };
96
98 class ZnSymmetry {
99 public:
100 // mutable: backs the legacy `int &n() const` accessor of Symmetry.
101 mutable int n;
102 static constexpr int stype_id = SymmetryType::Z;
103
104 explicit ZnSymmetry(const int &n) : n(n) {
105 if (n <= 1) cytnx_error_msg(true, "%s", "[ERROR] ZnSymmetry can only have n > 1");
106 }
107
108 bool check_qnum(const cytnx_int64 &in_qnum) const;
109 bool check_qnums(const std::vector<cytnx_int64> &in_qnums) const;
110 void combine_rule_(std::vector<cytnx_int64> &out, const std::vector<cytnx_int64> &inL,
111 const std::vector<cytnx_int64> &inR) const;
112 void combine_rule_(cytnx_int64 &out, const cytnx_int64 &inL, const cytnx_int64 &inR,
113 const bool &is_reverse) const;
114 void reverse_rule_(cytnx_int64 &out, const cytnx_int64 &in) const;
115 fermionParity get_fermion_parity(const cytnx_int64 &in_qnum) const;
116 bool is_fermionic() const { return false; }
117 void print_info() const;
118 std::string stype_str() const { return "Z" + std::to_string(this->n); }
119 };
121
123 class FermionParitySymmetry {
124 public:
125 // mutable: backs the legacy `int &n() const` accessor of Symmetry.
126 mutable int n = -2;
127 static constexpr int stype_id = SymmetryType::fPar;
128
129 bool check_qnum(const cytnx_int64 &in_qnum) const;
130 bool check_qnums(const std::vector<cytnx_int64> &in_qnums) const;
131 void combine_rule_(std::vector<cytnx_int64> &out, const std::vector<cytnx_int64> &inL,
132 const std::vector<cytnx_int64> &inR) const;
133 void combine_rule_(cytnx_int64 &out, const cytnx_int64 &inL, const cytnx_int64 &inR,
134 const bool &is_reverse) const;
135 void reverse_rule_(cytnx_int64 &out, const cytnx_int64 &in) const;
136 fermionParity get_fermion_parity(const cytnx_int64 &in_qnum) const;
137 bool is_fermionic() const { return true; }
138 void print_info() const;
139 std::string stype_str() const { return "fP"; }
140 };
142
144 class FermionNumberSymmetry {
145 public:
146 // mutable: backs the legacy `int &n() const` accessor of Symmetry.
147 mutable int n = -1;
148 static constexpr int stype_id = SymmetryType::fNum;
149
150 bool check_qnum(const cytnx_int64 &in_qnum) const;
151 bool check_qnums(const std::vector<cytnx_int64> &in_qnums) const;
152 void combine_rule_(std::vector<cytnx_int64> &out, const std::vector<cytnx_int64> &inL,
153 const std::vector<cytnx_int64> &inR) const;
154 void combine_rule_(cytnx_int64 &out, const cytnx_int64 &inL, const cytnx_int64 &inR,
155 const bool &is_reverse) const;
156 void reverse_rule_(cytnx_int64 &out, const cytnx_int64 &in) const;
157 fermionParity get_fermion_parity(const cytnx_int64 &in_qnum) const;
158 bool is_fermionic() const { return true; }
159 void print_info() const;
160 std::string stype_str() const { return "f#"; }
161 };
163
164 //=====================================
165 // this is API
167 class Symmetry {
168 public:
169 //[Note] this is hidden from user.
171 using kind_variant =
172 std::variant<U1Symmetry, ZnSymmetry, FermionParitySymmetry, FermionNumberSymmetry>;
173
174 kind_variant _impl;
175
176 Symmetry(const int &stype = -1, const int &n = 0) {
177 this->Init(stype, n);
178 }; // default is U1Symmetry
179
180 void Init(const int &stype = -1, const int &n = 0) {
181 if (stype == SymmetryType::U) {
182 this->_impl = U1Symmetry();
183 } else if (stype == SymmetryType::Z) {
184 this->_impl = ZnSymmetry(n);
185 } else if (stype == SymmetryType::fPar) {
186 this->_impl = FermionParitySymmetry();
187 } else if (stype == SymmetryType::fNum) {
188 this->_impl = FermionNumberSymmetry();
189 } else {
190 cytnx_error_msg(true, "%s", "[ERROR] invalid symmetry type.");
191 }
192 }
193 Symmetry &operator=(const Symmetry &rhs) = default;
194 Symmetry(const Symmetry &rhs) = default;
196
197 //[genenrators]
226 static Symmetry U1() { return Symmetry(SymmetryType::U, 1); }
227
257 static Symmetry Zn(const int &n) { return Symmetry(SymmetryType::Z, n); }
258
279
300
315 Symmetry clone() const { return *this; }
316
323 int stype() const {
324 return std::visit([](const auto &kind) { return kind.stype_id; }, this->_impl);
325 }
326
336 int &n() const {
337 // [legacy API] `int &n() const` (a mutable reference from a const
338 // Symmetry) is preserved for compatibility with the intrusive-ptr era;
339 // accessor cleanup is tracked together with the #840-era API follow-ups.
340 // The kind structs declare `n` mutable, so returning it is well-defined
341 // even for genuinely const objects.
342 //
343 // Value-semantics note (the second observable change of the value-type
344 // refactor, alongside `is()` becoming address identity): the returned
345 // reference now points into *this* Symmetry's own variant, so writing
346 // through it no longer propagates to copies. Under the shared
347 // intrusive-ptr impl, `Symmetry b = a; a.n() = k;` also changed b;
348 // copies are now independent.
349 return std::visit([](const auto &kind) -> int & { return kind.n; }, this->_impl);
350 }
351
359 std::string stype_str() const {
360 return std::visit([](const auto &kind) { return kind.stype_str(); }, this->_impl);
361 }
362
369 bool check_qnum(const cytnx_int64 &qnum) const {
370 return std::visit([&](const auto &kind) { return kind.check_qnum(qnum); }, this->_impl);
371 }
372
380 bool check_qnums(const std::vector<cytnx_int64> &qnums) const {
381 return std::visit([&](const auto &kind) { return kind.check_qnums(qnums); }, this->_impl);
382 }
383
390 std::vector<cytnx_int64> combine_rule(const std::vector<cytnx_int64> &inL,
391 const std::vector<cytnx_int64> &inR) const {
392 std::vector<cytnx_int64> out;
393 this->combine_rule_(out, inL, inR);
394 return out;
395 }
396
404 void combine_rule_(std::vector<cytnx_int64> &out, const std::vector<cytnx_int64> &inL,
405 const std::vector<cytnx_int64> &inR) const {
406 std::visit([&](const auto &kind) { kind.combine_rule_(out, inL, inR); }, this->_impl);
407 }
408
415 cytnx_int64 combine_rule(const cytnx_int64 &inL, const cytnx_int64 &inR,
416 const bool &is_reverse = false) const {
417 cytnx_int64 out;
418 std::visit([&](const auto &kind) { kind.combine_rule_(out, inL, inR, is_reverse); },
419 this->_impl);
420 return out;
421 }
422
430 void combine_rule_(cytnx_int64 &out, const cytnx_int64 &inL, const cytnx_int64 &inR,
431 const bool &is_reverse = false) const {
432 std::visit([&](const auto &kind) { kind.combine_rule_(out, inL, inR, is_reverse); },
433 this->_impl);
434 }
435
444 void reverse_rule_(cytnx_int64 &out, const cytnx_int64 &in) const {
445 std::visit([&](const auto &kind) { kind.reverse_rule_(out, in); }, this->_impl);
446 }
447
456 cytnx_int64 reverse_rule(const cytnx_int64 &in) const {
457 cytnx_int64 out;
458 std::visit([&](const auto &kind) { kind.reverse_rule_(out, in); }, this->_impl);
459 return out;
460 }
461
468 fermionParity get_fermion_parity(const cytnx_int64 &in_qnum) const {
469 return std::visit([&](const auto &kind) { return kind.get_fermion_parity(in_qnum); },
470 this->_impl);
471 }
472
477 bool is_fermionic() const {
478 return std::visit([](const auto &kind) { return kind.is_fermionic(); }, this->_impl);
479 }
480
486 void Save(const std::string &fname) const;
487
491 void Save(const char *fname) const;
492
499 static Symmetry Load(const std::string &fname);
500
504 static Symmetry Load(const char *fname);
505
507 void _Save(std::fstream &f) const;
508 void _Load(std::fstream &f);
510
514 void print_info() const {
515 std::visit([](const auto &kind) { kind.print_info(); }, this->_impl);
516 }
517
521 bool operator==(const Symmetry &rhs) const;
522
526 bool operator!=(const Symmetry &rhs) const;
527 }; // Symmetry
528
530 std::ostream &operator<<(std::ostream &os, const Symmetry &in);
532
533}; // namespace cytnx
534#endif // CYTNX_SYMMETRY_H_
Definition Symmetry.hpp:41
Qs(const cytnx_int64 &e1, const Ts... elems)
Definition Symmetry.hpp:47
Qs(const std::vector< cytnx_int64 > &qin)
Definition Symmetry.hpp:51
std::pair< std::vector< cytnx_int64 >, cytnx_uint64 > operator>>(const cytnx_uint64 &dim)
Definition Symmetry.hpp:56
the symmetry object
Definition Symmetry.hpp:167
static Symmetry Zn(const int &n)
create a Zn discrete symmetry object with
Definition Symmetry.hpp:257
void combine_rule_(cytnx_int64 &out, const cytnx_int64 &inL, const cytnx_int64 &inR, const bool &is_reverse=false) const
apply combine rule of current symmetry to two quantum numbers, and store the combined quntun number i...
Definition Symmetry.hpp:430
std::string stype_str() const
return the symmetry type name of current Symmetry object in string form, see cytnx::SymmetryType::
Definition Symmetry.hpp:359
static Symmetry FermionParity()
create a fermionic parity symmetry object
Definition Symmetry.hpp:278
void Save(const char *fname) const
Same as Save(const std::string &fname) const;.
cytnx_int64 combine_rule(const cytnx_int64 &inL, const cytnx_int64 &inR, const bool &is_reverse=false) const
apply combine rule of current symmetry to two quantum numbers.
Definition Symmetry.hpp:415
Symmetry clone() const
return a clone instance of current Symmetry object.
Definition Symmetry.hpp:315
static Symmetry FermionNumber()
create a fermionic occupation number symmetry object
Definition Symmetry.hpp:299
void combine_rule_(std::vector< cytnx_int64 > &out, const std::vector< cytnx_int64 > &inL, const std::vector< cytnx_int64 > &inR) const
apply combine rule of current symmetry to two quantum number lists, and store it into parameter out.
Definition Symmetry.hpp:404
bool check_qnums(const std::vector< cytnx_int64 > &qnums) const
check all the quantum numbers \qnums are within the valid value range of current Symmetry.
Definition Symmetry.hpp:380
int stype() const
return the symmetry type-id of current Symmetry object, see cytnx::SymmetryType::
Definition Symmetry.hpp:323
std::vector< cytnx_int64 > combine_rule(const std::vector< cytnx_int64 > &inL, const std::vector< cytnx_int64 > &inR) const
apply combine rule of current symmetry to two quantum number lists.
Definition Symmetry.hpp:390
int & n() const
return the discrete n of current Symmetry object.
Definition Symmetry.hpp:336
bool operator==(const Symmetry &rhs) const
the equality operator of the Symmetry object.
bool is_fermionic() const
check if the Symmetry is fermionic or not
Definition Symmetry.hpp:477
void print_info() const
Print the information of current Symmetry object.
Definition Symmetry.hpp:514
static Symmetry U1()
create a U1 symmetry object
Definition Symmetry.hpp:226
cytnx_int64 reverse_rule(const cytnx_int64 &in) const
Apply reverse rule of current symmetry to a given quantum number and return the result.
Definition Symmetry.hpp:456
static Symmetry Load(const char *fname)
Same as static Symmetry Load(const std::string &fname);.
void reverse_rule_(cytnx_int64 &out, const cytnx_int64 &in) const
Apply reverse rule of current symmetry to a given quantum number and store in parameter out.
Definition Symmetry.hpp:444
bool operator!=(const Symmetry &rhs) const
the inequality operator of the Symmetry object.
bool check_qnum(const cytnx_int64 &qnum) const
check the quantum number qnum is within the valid value range of current Symmetry.
Definition Symmetry.hpp:369
void Save(const std::string &fname) const
Save the current Symmetry object to a file.
static Symmetry Load(const std::string &fname)
Load a Symmetry object from a file.
fermionParity get_fermion_parity(const cytnx_int64 &in_qnum) const
fermionic parity for a given quantum number
Definition Symmetry.hpp:468
#define cytnx_error_msg(is_true, format,...)
Definition cytnx_error.hpp:115
Definition Accessor.hpp:12
SymmetryType
Symmetry type.
Definition Symmetry.hpp:30
@ U
Definition Symmetry.hpp:30
@ fNum
Definition Symmetry.hpp:30
@ Z
Definition Symmetry.hpp:30
@ Void
Definition Symmetry.hpp:30
@ fPar
Definition Symmetry.hpp:30
fermionParity
fermionParity
Definition Symmetry.hpp:38
@ EVEN
Definition Symmetry.hpp:38
@ ODD
Definition Symmetry.hpp:38