33 namespace ComparePTLeaf {
36 template<
typename PTType,
bool IsConst = false>
59 up_node(_up), m_val(_val) {};
66 virtual void remove();
71 class PTLeaf :
public PTNode<T> {
82 PTNode<T>(_up, _val), next_leaf(nullptr), prev_leaf_addr(nullptr), m_key(_key) {};
134 namespace ComparePTLeaf {
137 template <
typename T>
139 return (A.key().sum() >= B.key().sum()) && (A.key() >= B.key());
141 template <
typename T>
149 template <
typename T>
151 if(A.key().size() < 9 || B.key().size() < 9)
154 if(A.key().sum() > B.key().sum())
156 if(A.key().sum() < B.key().sum())
160 sub1A(A.key().sub_array(0, A.key().size() - 7)),
161 sub2A(A.key().sub_array(A.key().size() - 6, A.key().size() - 4)),
162 sub3A(A.key().sub_array(A.key().size() - 3, A.key().size() - 1)),
163 sub1B(B.key().sub_array(0, B.key().size() - 7)),
164 sub2B(B.key().sub_array(B.key().size() - 6, B.key().size() - 4)),
165 sub3B(B.key().sub_array(B.key().size() - 3, B.key().size() - 1));
166 if(sub1A.sum() > sub1B.sum())
168 if(sub1A.sum() < sub1B.sum())
170 if(sub1A.max() > sub1B.max())
172 if(sub1A.max() < sub1B.max())
174 if(sub2A.sum() > sub2B.sum())
176 if(sub2A.sum() < sub2B.sum())
178 if(sub3A.sum() > sub3B.
sum())
180 if(sub3A.sum() < sub3B.
sum())
185 return std::abs(A.val()) > std::abs(B.val());
187 template <
typename T>
197 class PolyTrie :
public PTNode<T> {
273 const_iterator
end()
const {
291 template<
typename CompareType>
296 template<
typename PTType,
bool IsConst>
307 PTIterator(leaf_type *_leaf_ptr = 0) : m_curr_leaf_ptr(_leaf_ptr) {};
310 template<
bool IsConst2>
312 return m_curr_leaf_ptr == _it.m_curr_leaf_ptr;
315 template<
bool IsConst2>
317 return !((*this) == _it);
322 m_curr_leaf_ptr = m_curr_leaf_ptr->next();
337 return m_curr_leaf_ptr->val_ref();
343 return m_curr_leaf_ptr->key();
354 template<
typename PTType,
bool IsConst>
356 m_curr_leaf_ptr(_it.leaf_ptr()) {}
365 return at(i) ? at(i) : at(i) =
new PTNode<T>(
this);
372 if(ind.
size() == 0 && home_trie.depth() == 0 &&
this ==
static_cast<PTNode<T> *
>(&home_trie)) {
373 if(!home_trie.begin_ptr())
374 home_trie.list_leaf(
new PTLeaf<T>(
this, ind, 0));
375 return home_trie.begin_ptr();
378 while(size() <= ind.
back()) {
383 if(!at(ind.
back())) {
385 home_trie.list_leaf(
static_cast<PTLeaf<T>*
>(at(ind.
back())));
388 return at(ind.
back());
401 bool remove_up(
true), not_removed(
true);
403 for(
Index i = 0; i < up_node->size() && (remove_up || not_removed); i++) {
404 if((up_node->at(i)) ==
this) {
405 up_node->at(i) =
nullptr;
408 remove_up = remove_up && !(up_node->at(i));
424 for(
Index i = 0; i < size(); i++) {
435 swap(prev_leaf_addr, other->prev_leaf_addr);
436 *prev_leaf_addr =
this;
437 *(other->prev_leaf_addr) = other;
443 insert_at(prev->next_leaf);
452 prev_leaf_addr = &insertion_ptr;
455 next_leaf = insertion_ptr;
459 next_leaf->prev_leaf_addr = &next_leaf;
463 (*prev_leaf_addr) =
this;
472 assert(next && next->prev_leaf_addr &&
"PTLeaf insertion failed because 'next' leaf address is not in List.");
478 prev_leaf_addr = next->prev_leaf_addr;
481 (*prev_leaf_addr) =
this;
484 next->prev_leaf_addr = &next_leaf;
493 *prev_leaf_addr = next_leaf;
499 prev_leaf_addr =
nullptr;
518 for(; it != it_end; ++it)
526 if(depth() == 0 && begin_ptr())
536 for(; it != it_end; ++it)
545 assert(ind.
size() == depth() &&
"In PolyTrie<T>::get(), ind.size() must match PolyTrie<T>::depth().");
546 if(ind.
size() == 0) {
548 return begin_ptr()->val();
554 if(ind[i] >= tnode->
size() || !(tnode->
at(ind[i]))) {
557 tnode = tnode->
at(ind[i]);
566 assert(ind.
size() == depth() &&
"In PolyTrie<T>::set(), ind.size() must match PolyTrie<T>::depth().");
573 for(
Index i = 0; i < ind.
size() - 1; i++) {
588 assert(ind.
size() == depth() &&
"In PolyTrie<T>::at(), ind.size() must match PolyTrie<T>::depth().");
591 for(
Index i = 0; i < ind.
size() - 1; i++) {
592 tnode = tnode->valid_node_at(ind[i]);
595 tnode = tnode->valid_leaf_at(*
this, ind);
604 assert(ind.
size() == depth() &&
"In PolyTrie<T>::operator(), ind.size() must match PolyTrie<T>::depth().");
607 for(
Index i = 0; i < ind.
size() - 1; i++) {
608 tnode = tnode->valid_node_at(ind[i]);
611 tnode = tnode->valid_leaf_at(*
this, ind);
620 assert(ind.
size() == depth() &&
"In PolyTrie<T>::get(), ind.size() must match PolyTrie<T>::depth().");
621 if(ind.
size() == 0) {
623 return begin_ptr()->val();
629 if(ind[i] >= tnode->
size() || !(tnode->
at(ind[i]))) {
632 tnode = tnode->
at(ind[i]);
643 new_leaf->insert_at(m_leaf_list);
652 current = current->remove_and_next();
671 for(
Index i = 0; i < size(); i++) {
673 at(i)->up_node = &other;
678 for(
Index i = 0; i < size(); i++) {
680 at(i)->up_node =
this;
686 m_leaf_list->prev_leaf_addr = &m_leaf_list;
687 if(other.m_leaf_list)
688 other.m_leaf_list->prev_leaf_addr = &(other.m_leaf_list);
695 assert(ind.
size() == depth() &&
"In PolyTrie<T>::remove(), ind.size() must match PolyTrie<T>::depth().");
698 if(ind[i] >= tnode->
size() || !(tnode->at(ind[i]))) {
701 tnode = tnode->at(ind[i]);
711 bool is_edited(
false);
713 for(; it != it_end; ++it) {
715 it.remove_and_next();
727 for(; it != it_end; ++it) {
729 out << it.key() <<
": " << *it <<
'\n';
743 for(; it != it_end; ++it)
754 for(; it != it_end; ++it) {
766 for(; it != it_end; ++it) {
778 return result += RHS;
785 return result -= RHS;
792 return ((*
this) - RHS).almost_zero(tol);
808 for(; it != it_end; ++it) {
817 template<
typename T>
template<
typename CompareType>
833 int merge_size(1), nmerges(2);
848 for(
int i = 0; i < merge_size; i++) {
850 if(!(b_ptr = b_ptr->next()))
break;
857 while(a_size > 0 || (b_size > 0 && b_ptr)) {
862 b_ptr = b_ptr->next();
865 else if(b_size == 0 || !b_ptr) {
868 a_ptr = a_ptr->next();
871 else if(
compare(*a_ptr, *b_ptr)) {
874 a_ptr = a_ptr->next();
880 b_ptr = b_ptr->next();
886 merge_elem->insert_after(tail);
889 merge_elem->insert_at(m_leaf_list);
void insert_after(PTLeaf< T > *prev)
typename std::conditional< IsConst, const T, T >::type ConstSwitch
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
PolyTrie & operator*=(const T &scale)
void list_leaf(PTLeaf< T > *new_leaf)
PTIterator< PolyTrie< T >, true > const_iterator
bool operator()(const PTLeaf< T > &A, const PTLeaf< T > &B) const
void insert_before(PTLeaf< T > *next)
CASM_TMP::ConstSwitch< IsConst, typename PTType::leaf_type > leaf_type
PTLeaf< T > * begin_ptr()
bool compare(const T &A, const T &B, double tol)
Floating point comparison with tol, return A < B.
void push_back(const PTNode< T > *&toPush)
PTLeaf< T > * remove_and_next()
const T & val_ref() const
T get(const Array< Index > &ind) const
get() provides constant access does not change trie structure
const Array< Index > & key() const
PTNode< T > * valid_node_at(Index i)
T & at(const Array< Index > &ind)
at() provides non-const access and changes trie if leaf does not exist at ind
bool operator==(const PTIterator< PTType, IsConst2 > &_it)
PTIterator(leaf_type *_leaf_ptr=0)
CASM_TMP::ConstSwitch< IsConst, typename PTType::value_type > & reference
bool prune_zeros(double tol=PTNode< T >::PT_TOL())
removes zero entries, if there are any, and returns true if entries were removed. ...
PTNode(PTNode< T > *_up, const T &_val=0)
PTLeaf< T > const * begin_ptr() const
PTIterator & remove_and_next()
void swap(ConfigDoF &A, ConfigDoF &B)
ComparePTLeaf::ByMonomialOrder CompareByMonomialOrder
static bool compare(const PTLeaf< T > &A, const PTLeaf< T > &B)
PTLeaf< T > ** prev_leaf_addr
void swap(PolyTrie< T > &other)
Efficient swap of this PolyTrie with another.
const Array< Index > & key()
void sort_leaves(const CompareType &compare)
PTIterator operator++(int)
void redefine(Index new_depth)
Clears all leaves and resets depth.
void remove()
Virtual from PTNode, you cannot remove a PolyTrie.
T & operator()(const Array< Index > &ind)
void swap_after_prev(PTLeaf< T > *other)
EigenIndex Index
For long integer indexing:
PTLeaf< T > * m_leaf_list
PolyTrie operator-(const PolyTrie< T > &RHS) const
PolyTrie & operator+=(const PolyTrie< T > &RHS)
Index num_nonzero() const
leaf_type * m_curr_leaf_ptr
leaf_type * leaf_ptr() const
PTNode< T > *& at(Index ind)
PTLeaf< T > const * next() const
PolyTrie operator+(const PolyTrie< T > &RHS) const
PolyTrie & operator-=(const PolyTrie< T > &RHS)
bool operator!=(const PTIterator< PTType, IsConst2 > &_it)
bool compare(const PolyTrie< T > &RHS, double tol=2 *PTNode< T >::PT_TOL()) const
PTNode< T > * valid_leaf_at(PolyTrie< T > &home_trie, const Array< Index > &ind)
bool operator()(const PTLeaf< T > &A, const PTLeaf< T > &B) const
CASM_TMP::ConstSwitch< IsConst, typename PTType::value_type > * pointer
void set(const Array< Index > &ind, const T &_val)
set() allows assignment that prunes the trie if _val is approximately 0;
bool almost_zero(double tol=2 *PTNode< T >::PT_TOL()) const
static bool compare(const PTLeaf< T > &A, const PTLeaf< T > &B)
const_iterator begin() const
void insert_at(PTLeaf< T > *&insertion_ptr)
List insertion methods.
void print_sparse(std::ostream &out) const
PTIterator< PolyTrie< T > > iterator
bool operator==(const PolyTrie< T > &RHS) const
Basic std::vector like container (deprecated)
bool almost_equal(const GenericCluster< CoordType > &LHS, const GenericCluster< CoordType > &RHS, double tol)
PTIterator & operator++()
const_iterator end() const
PTLeaf(PTNode< T > *_up, const Array< Index > &_key, const T &_val)