1 #ifndef _GLUCAT_INDEX_SET_IMP_H 2 #define _GLUCAT_INDEX_SET_IMP_H 45 template<const index_t LO, const index_t HI>
50 {
return "index_set"; }
53 template<const index_t LO, const index_t HI>
59 template<const index_t LO, const index_t HI>
66 template<const index_t LO, const index_t HI>
71 throw error_t(
"index_set(val,frm): cannot create: value gives an index set outside of frame");
74 const index_t skip = min_index > 0 ? 1 : 0;
76 *
this = folded_set.
unfold(frm);
80 template<const index_t LO, const index_t HI>
84 if (!prechecked && (range.first < LO || range.second > HI))
85 throw error_t(
"index_set(range): cannot create: range is too large");
86 const index_t begin_bit = (range.first < 0)
89 const index_t end_bit = (range.second < 0)
92 unsigned long mask = ( (end_bit == _GLUCAT_BITS_PER_ULONG)
94 : (1UL << end_bit)-1UL)
95 & ~((1UL << begin_bit)-1UL);
100 template<const index_t LO, const index_t HI>
104 std::istringstream ss(str);
107 throw error_t(
"index_set_t(str): could not parse string");
111 throw error_t(
"index_set_t(str): could not parse entire string");
115 template<const index_t LO, const index_t HI>
122 return *pthis ==
static_cast<bitset_t>(rhs);
126 template<const index_t LO, const index_t HI>
133 return *pthis !=
static_cast<bitset_t>(rhs);
137 template<const index_t LO, const index_t HI>
142 {
return bitset_t::operator~(); }
145 template<const index_t LO, const index_t HI>
152 *pthis ^=
static_cast<bitset_t>(rhs);
157 template<const index_t LO, const index_t HI>
166 return static_cast<bitset_t
>(lhs) ^ static_cast<bitset_t>(rhs);
170 template<const index_t LO, const index_t HI>
177 *pthis &=
static_cast<bitset_t>(rhs);
182 template<const index_t LO, const index_t HI>
191 return static_cast<bitset_t
>(lhs) & static_cast<bitset_t>(rhs);
195 template<const index_t LO, const index_t HI>
202 *pthis |=
static_cast<bitset_t>(rhs);
207 template<const index_t LO, const index_t HI>
216 return static_cast<bitset_t
>(lhs) | static_cast<bitset_t>(rhs);
220 template<const index_t LO, const index_t HI>
228 template<const index_t LO, const index_t HI>
233 {
return this->
test(idx); }
236 template<const index_t LO, const index_t HI>
244 ? bool(bitset_t::to_ulong() & (1UL << (idx - LO)))
246 ?
bool(bitset_t::to_ulong() & (1UL << (idx - LO - 1)))
251 template<const index_t LO, const index_t HI>
262 template<const index_t LO, const index_t HI>
269 bitset_t::set(idx-LO-1);
271 bitset_t::set(idx-LO);
276 template<const index_t LO, const index_t HI>
283 bitset_t::set(idx-LO-1, val);
285 bitset_t::set(idx-LO, val);
290 template<const index_t LO, const index_t HI>
301 template<const index_t LO, const index_t HI>
308 bitset_t::reset(idx-LO-1);
310 bitset_t::reset(idx-LO);
315 template<const index_t LO, const index_t HI>
326 template<const index_t LO, const index_t HI>
333 bitset_t::flip(idx-LO-1);
335 bitset_t::flip(idx-LO);
340 template<const index_t LO, const index_t HI>
346 unsigned long val = bitset_t::to_ulong();
360 template<const index_t LO, const index_t HI>
368 return neg_part.
count();
372 template<const index_t LO, const index_t HI>
380 return pos_part.
count();
383 #if (_GLUCAT_BITS_PER_ULONG == 64) 384 template<const index_t LO, const index_t HI>
392 unsigned long val = bitset_t::to_ulong();
397 val -= val & (val-1);
404 if (val & 0xffffffff00000000ul)
406 if (val & 0xffff0000ffff0000ul)
408 if (val & 0xff00ff00ff00ff00ul)
411 if (val & 0xf0f0f0f0f0f0f0f0ul)
413 if (val & 0xccccccccccccccccul)
415 if (val & 0xaaaaaaaaaaaaaaaaul)
418 return idx + ((idx < -LO) ? LO : LO+1);
421 #elif (_GLUCAT_BITS_PER_ULONG == 32) 422 template<const index_t LO, const index_t HI>
430 unsigned long val = bitset_t::to_ulong();
435 val -= val & (val-1);
441 if (val & 0xffff0000ul)
443 if (val & 0xff00ff00ul)
446 if (val & 0xf0f0f0f0ul)
448 if (val & 0xccccccccul)
450 if (val & 0xaaaaaaaaul)
453 return idx + ((idx < -LO) ? LO : LO+1);
457 template<const index_t LO, const index_t HI>
479 #if (_GLUCAT_BITS_PER_ULONG == 64) 480 template<const index_t LO, const index_t HI>
488 unsigned long val = bitset_t::to_ulong();
497 if (val & 0xffffffff00000000ul)
498 { val >>= 32; idx += 32; }
499 if (val & 0x00000000ffff0000ul)
500 { val >>= 16; idx += 16; }
501 if (val & 0x000000000000ff00ul)
502 { val >>= 8; idx += 8; }
504 if (val & 0x00000000000000f0ul)
505 { val >>= 4; idx += 4; }
506 if (val & 0x000000000000000cul)
507 { val >>= 2; idx += 2; }
508 if (val & 0x0000000000000002ul)
510 return idx + ((idx < -LO) ? LO : LO+1);
513 #elif (_GLUCAT_BITS_PER_ULONG == 32) 514 template<const index_t LO, const index_t HI>
522 unsigned long val = bitset_t::to_ulong();
531 if (val & 0xffff0000ul)
532 { val >>= 16; idx += 16; }
533 if (val & 0x0000ff00ul)
534 { val >>= 8; idx += 8; }
536 if (val & 0x000000f0ul)
537 { val >>= 4; idx += 4; }
538 if (val & 0x0000000cul)
539 { val >>= 2; idx += 2; }
540 if (val & 0x00000002ul)
542 return idx + ((idx < -LO) ? LO : LO+1);
546 template<const index_t LO, const index_t HI>
570 template<const index_t LO, const index_t HI>
584 template<const index_t LO, const index_t HI>
589 {
return bitset_t::to_ulong() < rhs.bitset_t::to_ulong(); }
593 template<const index_t LO, const index_t HI>
601 return (this_grade < rhs_grade)
603 : (this_grade > rhs_grade)
609 template<const index_t LO, const index_t HI>
611 operator<< (std::ostream& os, const index_set<LO,HI>&
ist)
616 (i <= HI) && !(
ist[i]);
631 template<const index_t LO, const index_t HI>
640 bool parse_index_list =
true;
641 bool expect_closing_brace =
false;
642 bool expect_index =
false;
647 parse_index_list =
false;
650 expect_closing_brace = (c == int(
'{'));
651 if (expect_closing_brace)
657 if (s.good() && (c == int(
'}')))
659 expect_closing_brace =
false;
663 parse_index_list =
false;
667 if (s.good() && parse_index_list)
674 if ((i < LO) || (i > HI))
676 s.clear(std::istream::failbit);
682 expect_index =
false;
694 if (expect_closing_brace && (c ==
int(
'}')))
698 expect_closing_brace =
false;
711 s.clear(std::istream::failbit);
717 if (expect_index || expect_closing_brace)
718 s.clear(std::istream::failbit);
728 template<const index_t LO, const index_t HI>
736 return (min_index < 0 && max_index > 0)
737 ? max_index - min_index == this->
count()
738 : (min_index == 1 || max_index == -1) &&
739 (max_index - min_index == this->
count() - 1);
743 template<const index_t LO, const index_t HI>
749 {
return this->
fold(*
this,
true); }
752 template<const index_t LO, const index_t HI>
758 if (!prechecked && ((*
this | frm) != frm))
759 throw error_t(
"fold(frm): cannot fold from outside of frame");
765 for (unfold_idx = -1;
766 unfold_idx >= frm_min;
768 if (frm.
test(unfold_idx))
771 if (this->
test(unfold_idx))
772 result.
set(fold_idx);
777 unfold_idx <= frm_max;
779 if (frm.
test(unfold_idx))
782 if (this->
test(unfold_idx))
783 result.
set(fold_idx);
790 template<const index_t LO, const index_t HI>
797 "unfold(frm): cannot unfold into a smaller frame";
803 for (unfold_idx = -1;
804 unfold_idx >= frm_min;
806 if (frm.
test(unfold_idx))
807 if (this->
test(fold_idx--))
808 result.
set(unfold_idx);
809 if (!prechecked && ((fold_idx+1) > this->
min()))
813 unfold_idx <= frm_max;
815 if (frm.
test(unfold_idx))
816 if (this->
test(fold_idx++))
817 result.
set(unfold_idx);
818 if (!prechecked && ((fold_idx-1) < this->
max()))
824 template<const index_t LO, const index_t HI>
836 const index_t skip = min_index > 0 ? 1 : 0;
837 return folded_set.bitset_t::to_ulong() >> (min_index-LO-skip);
847 #if (_GLUCAT_BITS_PER_ULONG >= 64) 864 #if (_GLUCAT_BITS_PER_ULONG >= 64) 876 template<const index_t LO, const index_t HI>
884 const unsigned long uthis = this->bitset_t::to_ulong();
885 const unsigned long urhs = rhs.bitset_t::to_ulong();
887 unsigned long negative = 0;
898 const unsigned long q =
inverse_gray((uthis & urhs) >> -LO);
910 negative ^= h & (uthis >> j);
916 negative ^= h & (uthis >> j);
920 return 1 - int((negative & 1) << 1);
924 template<const index_t LO, const index_t HI>
930 int result = 1 - int((this->
count_neg() % 2) << 1);
931 switch (this->
count() % 4)
944 template<const index_t LO, const index_t HI>
950 static const unsigned long lo_mask = (1UL << -LO) - 1UL;
951 const unsigned long uthis = bitset_t::to_ulong();
952 const unsigned long neg_part = uthis & lo_mask;
953 const unsigned long pos_part = uthis >> -LO;
954 return size_t(neg_part ^ pos_part);
961 {
return (j < 0) ? -1 : 1; }
964 template<const index_t LO, const index_t HI>
968 {
return std::min(ist.
min(), 0); }
971 template<const index_t LO, const index_t HI>
975 {
return std::max(ist.
max(), 0); }
980 template<const index_t LO, const index_t HI>
989 template<const index_t LO, const index_t HI>
1003 template<const index_t LO, const index_t HI>
1017 template<const index_t LO, const index_t HI>
1025 template<const index_t LO, const index_t HI>
1028 operator bool ()
const 1032 template<const index_t LO, const index_t HI>
1042 #endif // _GLUCAT_INDEX_SET_IMP_H reference & flip()
for b[i].flip();
friend int compare(const index_set_t &lhs, const index_set_t &rhs)
bool operator==(const index_set_t rhs) const
Equality.
index_t count_pos() const
Number of positive indices included in set.
const index_set_t fold() const
Fold this index set within itself as a frame.
const index_set_t unfold(const index_set_t frm, const bool prechecked=false) const
Unfold this index set within the given frame.
error< index_set > error_t
index_t max() const
Maximum member.
int sign_of_square() const
Sign of geometric square of a Clifford basis element.
set_value_t value_of_fold(const index_set_t frm) const
The set value of the fold of this index set within the given frame.
index_t count() const
Cardinality: Number of indices included in set.
bool lex_less_than(const index_set_t rhs) const
Lexicographic ordering of two sets: *this < rhs.
static const std::string classname()
index_set_t & operator^=(const index_set_t rhs)
Symmetric set difference: exclusive or.
friend const index_set_t operator^(const index_set_t &lhs, const index_set_t &rhs)
bool operator<(const index_set_t rhs) const
Less than operator used for comparisons, map, etc.
reference & operator=(const bool x)
for b[i] = x;
index_t min() const
Minimum member.
bool is_contiguous() const
Determine if the index set is contiguous, ie. has no gaps.
index_set_t operator~() const
Set complement: not.
int sign_of_mult(const index_set_t ist) const
Sign of geometric product of two Clifford basis elements.
bool operator~() const
Flips a bit.
friend const index_set_t operator&(const index_set_t &lhs, const index_set_t &rhs)
index_t min_neg(const index_set< LO, HI > &ist)
Minimum negative index, or 0 if none.
reference()
Private default constructor is left undefined.
bool operator[](const index_t idx) const
Subscripting: Test idx for membership: test value of bit idx.
index_set_t & operator|=(const index_set_t rhs)
Set union: or.
std::pair< index_t, index_t > index_pair_t
friend const index_set_t operator|(const index_set_t &lhs, const index_set_t &rhs)
index_set_t & flip()
Set complement, except 0: flip all bits, except 0.
bool operator!=(const index_set_t rhs) const
Inequality.
std::bitset< HI-LO > bitset_t
index_set_t & set()
Include all indices except 0: set all bits except 0.
index_set()
Default constructor creates an empty set.
Index set class based on std::bitset<> in Gnu standard C++ library.
Index set member reference.
size_t hash_fn() const
Hash function.
index_t max_pos(const index_set< LO, HI > &ist)
Maximum positive index, or 0 if none.
index_set_t & reset()
Make set empty: Set all bits to 0.
int index_t
Size of index_t should be enough to represent LO, HI.
unsigned long set_value_t
Size of set_value_t should be enough to contain index_set<LO,HI>
static unsigned long inverse_reversed_gray(unsigned long x)
Inverse reversed Gray code.
index_set_t & operator&=(const index_set_t rhs)
Set intersection: and.
std::istream & operator>>(std::istream &s, framed_multi< Scalar_T, LO, HI > &val)
Read multivector from input.
static unsigned long inverse_gray(unsigned long x)
Inverse Gray code.
index_t count_neg() const
Number of negative indices included in set.
bool test(const index_t idx) const
Test idx for membership: test value of bit idx.