carl  24.04
Computer ARithmetic Library
TermAdditionManager.h
Go to the documentation of this file.
1 /*
2  * File: TermAdditionManager.h
3  * Author: Florian Corzilius
4  *
5  * Created on October 30, 2014, 7:20 AM
6  */
7 
8 #pragma once
9 
10 #include <list>
11 #include <mutex>
12 #include <tuple>
13 #include <unordered_map>
14 #include <vector>
15 
16 #include <carl-common/config.h>
17 #include "Term.h"
20 
21 namespace carl
22 {
23 
24 template<typename Polynomial, typename Ordering>
26 public:
27  using IDType = unsigned;
28  using Coeff = typename Polynomial::CoeffType;
30  using TermPtr = TermType;
31  using TermIDs = std::vector<IDType>;
32  using Terms = std::vector<TermPtr>;
33  /* 0: Maps global IDs to local IDs.
34  * 1: Actual terms by local IDs.
35  * 2: Flag if this entry is currently used.
36  * 3: Constant part.
37  * 4: Next free local ID.
38  */
39  using Tuple = std::tuple<TermIDs,Terms,bool,Coeff,IDType>;
40  using TAMId = typename std::list<Tuple>::iterator;
41 private:
42  std::list<Tuple> mData;
44  mutable std::mutex mMutex;
45 
46  #ifdef THREAD_SAFE
47  #define TAM_LOCK_GUARD std::lock_guard<std::mutex> lock( mMutex );
48  #define TAM_LOCK mMutex.lock();
49  #define TAM_UNLOCK mMutex.unlock();
50  #else
51  #define TAM_LOCK_GUARD
52  #define TAM_LOCK
53  #define TAM_UNLOCK
54  #endif
55 
57  TAMId res = mData.emplace(mData.end());
58  std::get<4>(*res) = 1;
59  return res;
60  }
61 
62  bool compare(TAMId id, IDType t1, IDType t2) const {
63  Tuple& data = *id;
64  assert(std::get<2>(data));
65  Terms& t = std::get<1>(data);
66  return Ordering::less(t[t1], t[t2]);
67  }
68 public:
72  }
73 
74  #define SWAP_TERMS
75 
76  TAMId getId(std::size_t expectedSize = 0) {
78  assert(mNextId != mData.end());
79  while (std::get<2>(*mNextId)) {
80  mNextId++;
81  if (mNextId == mData.end()) {
82  mNextId = mData.emplace(mData.end());
83  std::get<4>(*mNextId) = 1;
84  }
85  }
86  Tuple& data = *mNextId;
87  Terms& terms = std::get<1>(data);
88  terms.clear();
89  terms.resize(expectedSize + 1);
90  #ifdef SWAP_TERMS
91  //memset(&terms[0], 0, sizeof(TermPtr)*terms.size());
92  #endif
93  std::size_t greatestIdPlusOne = MonomialPool::getInstance().largestID() + 1;
94  if( std::get<0>(data).size() < greatestIdPlusOne ) std::get<0>(data).resize(greatestIdPlusOne);
95  //memset(&std::get<0>(data)[0], 0, sizeof(IDType)*std::get<0>(data).size());
96  std::get<3>(data) = constant_zero<Coeff>::get();
97  std::get<4>(data) = 1;
98  std::get<2>(data) = true;
99  TAMId result = mNextId;
100  mNextId++;
101  if (mNextId == mData.end()) mNextId = mData.begin();
102  return result;
103  }
104 
105  template<bool SizeUnknown, bool NewMonomials = true>
106  void addTerm(TAMId id, const TermPtr& term) {
107  assert(!is_zero(term));
108  Tuple& data = *id;
109  assert(std::get<2>(data));
110  TermIDs& termIDs = std::get<0>(data);
111  Terms& terms = std::get<1>(data);
112  if (term.monomial()) {
113  std::size_t monId = term.monomial()->id();
114  if (NewMonomials && monId >= termIDs.size()) termIDs.resize(monId + 1);
115  IDType locId = termIDs[monId];
116  if (locId != 0) {
117  if (SizeUnknown && locId >= terms.size()) terms.resize(locId + 1);
118  assert(locId < terms.size());
119  TermPtr& t = terms[locId];
120  if (!carl::is_zero(t.coeff())) {
121  Coeff coeff = t.coeff() + term.coeff();
122  if (carl::is_zero(coeff)) {
123  termIDs[monId] = 0;
124  t = std::move(TermType());
125  } else {
126  t.coeff() = std::move(coeff);
127  }
128  } else
129  t = term;
130  } else {
131  IDType& nextID = std::get<4>(data);
132  if (SizeUnknown && nextID >= terms.size()) terms.resize(nextID + 1);
133  assert(nextID < terms.size());
134  assert(nextID < std::numeric_limits<IDType>::max());
135  termIDs[monId] = nextID;
136  terms[nextID] = term;
137  ++nextID;
138  }
139  } else {
140  std::get<3>(data) += term.coeff();
141  }
142  }
143 
145  Tuple& data = *id;
146  Terms& terms = std::get<1>(data);
147  std::size_t max = 0;
148  assert(terms.size() > 0);
149  for (std::size_t i = 1; i < terms.size(); i++) {
150  if (Ordering::less(terms[max], terms[i])) max = i;
151  }
152  assert(!terms[max].is_constant() || is_zero(terms[max]));
153  if (is_zero(terms[max])) return TermType(std::get<3>(data));
154  else return terms[max];
155  }
156 
157  void readTerms(TAMId id, Terms& terms) {
158  Tuple& data = *id;
159  assert(std::get<2>(data));
160  Terms& t = std::get<1>(data);
161  TermIDs& termIDs = std::get<0>(data);
162  #ifdef SWAP_TERMS
163  if (!is_zero(std::get<3>(data))) {
164  t[0] = std::move(TermType(std::move(std::get<3>(data)), nullptr));
165  }
166  for (auto i = t.begin(); i != t.end();) {
167  if (is_zero(*i)) {
168  //Avoid invalidating pointer for last element
169  if (i == --t.end()) {
170  t.pop_back();
171  break;
172  } else {
173  std::swap(*i, *t.rbegin());
174  t.pop_back();
175  }
176  } else {
177  if ((*i).monomial()) termIDs[(*i).monomial()->id()] = 0;
178  ++i;
179  }
180  }
181  std::swap(t, terms);
182  t.clear();
183  #else
184  terms.clear();
185  if (!is_zero(std::get<3>(data))) {
186  terms.push_back( std::make_shared<const TermType>(std::move(std::get<3>(data)), nullptr) );
187  }
188  auto i = t.begin();
189  ++i;
190  for (; i != t.end(); ++i)
191  {
192  if (*i)
193  {
194  termIDs[(*i)->monomial()->id()] = 0;
195  terms.push_back( *i );
196  *i = nullptr;
197  }
198  }
199  t.clear();
200  #endif
202  std::get<2>(data) = false;
203  }
204 
205  void dropTerms(TAMId id) {
206  Tuple& data = *id;
207  assert(std::get<2>(data));
208  Terms& t = std::get<1>(data);
209  TermIDs& termIDs = std::get<0>(data);
210  for (auto i = t.begin(); i != t.end(); i++) {
211  if ((*i).monomial()) termIDs[(*i).monomial()->id()] = 0;
212  }
214  std::get<2>(data) = false;
215  }
216 };
217 
218 }
#define TAM_LOCK_GUARD
carl is the main namespace for the library.
void swap(Variable &lhs, Variable &rhs)
Definition: Variables.h:202
bool is_constant(const ContextPolynomial< Coeff, Ordering, Policies > &p)
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
Definition: Interval.h:1453
static const T & get()
Definition: constants.h:42
std::size_t largestID() const
Definition: MonomialPool.h:154
Coefficient & coeff()
Get the coefficient.
Definition: Term.h:80
Monomial::Arg & monomial()
Get the monomial.
Definition: Term.h:91
std::tuple< TermIDs, Terms, bool, Coeff, IDType > Tuple
TAMId getId(std::size_t expectedSize=0)
void addTerm(TAMId id, const TermPtr &term)
std::vector< IDType > TermIDs
bool compare(TAMId id, IDType t1, IDType t2) const
std::vector< TermPtr > Terms
TermType getMaxTerm(TAMId id) const
typename std::list< Tuple >::iterator TAMId
void readTerms(TAMId id, Terms &terms)
typename Polynomial::CoeffType Coeff
static MonomialPool & getInstance()
Returns the single instance of this class by reference.
Definition: Singleton.h:45