COPASI API  4.16.103
CNormalLcm.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010 - 2013 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 // Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
7 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
8 // and The University of Manchester.
9 // All rights reserved.
10 
11 // Copyright (C) 2007 by Pedro Mendes, Virginia Tech Intellectual
12 // Properties, Inc. and EML Research, gGmbH.
13 // All rights reserved.
14 
15 #ifdef WIN32
16 # pragma warning (disable: 4786)
17 # pragma warning (disable: 4243)
18 // warning C4355: 'this' : used in base member initializer list
19 # pragma warning (disable: 4355)
20 #endif // WIN32
21 
22 #include <vector>
23 #include <set>
24 #include <cmath>
25 #include <sstream>
26 
27 #include "copasi.h"
28 
29 #include "CNormalSum.h"
30 #include "CNormalProduct.h"
31 #include "CNormalItemPower.h"
32 #include "CNormalLcm.h"
33 
34 /**
35  * Default constructor
36  */
38 {}
39 
40 /**
41  * Copy contructor
42  */
44 {
45  std::set <CNormalItemPower*, compareItemPowers >::const_iterator it;
46  std::set <CNormalItemPower*, compareItemPowers >::const_iterator itEnd = src.mItemPowers.end();
47 
48  for (it = src.mItemPowers.begin(); it != itEnd; ++it)
49  {
50  mItemPowers.insert(new CNormalItemPower(**it));
51  }
52 
53  std::vector<CNormalSum*>::const_iterator it2;
54  std::vector<CNormalSum*>::const_iterator it2End = src.mSums.end();
55 
56  for (it2 = src.mSums.begin(); it2 != it2End; ++it2)
57  {
58  mSums.push_back(new CNormalSum(**it2));
59  }
60 }
61 
62 /**
63  * Assignment operator
64  */
66 {
67  std::set<CNormalItemPower*, compareItemPowers >::const_iterator it;
68  std::set<CNormalItemPower*, compareItemPowers >::const_iterator itEnd = src.mItemPowers.end();
69 
70  for (it = src.mItemPowers.begin(); it != itEnd; ++it)
71  mItemPowers.insert(new CNormalItemPower(**it));
72 
73  std::vector<CNormalSum*>::const_iterator it2;
74  std::vector<CNormalSum*>::const_iterator it2End = src.mSums.end();
75 
76  for (it2 = src.mSums.begin(); it2 != it2End; ++it2)
77  mSums.push_back(new CNormalSum(**it2));
78 
79  return *this;
80 }
81 
82 /**
83  * Destructor
84  */
86 {
87  std::set<CNormalItemPower*, compareItemPowers >::const_iterator it;
88  std::set<CNormalItemPower*, compareItemPowers >::const_iterator itEnd = mItemPowers.end();
89 
90  for (it = mItemPowers.begin(); it != itEnd; ++it)
91  delete *it;
92 
93  std::vector<CNormalSum*>::const_iterator it2;
94  std::vector<CNormalSum*>::const_iterator it2End = mSums.end();
95 
96  for (it2 = mSums.begin(); it2 != it2End; ++it2)
97  delete *it2;
98 }
99 
100 /**
101  * Add an itempower to this lcm,
102  * ie. lcm := LeastCommonMultiple(lcm,itempower)
103  * @return true.
104  */
105 bool CNormalLcm::add(const CNormalItemPower& itemPower)
106 {
107  std::set <CNormalItemPower*, compareItemPowers >::iterator it;
108  std::set <CNormalItemPower*, compareItemPowers >::iterator itEnd = mItemPowers.end();
109 
110  for (it = mItemPowers.begin(); it != itEnd; ++it)
111  {
112  if ((*it)->getItem().areEqual(itemPower.getItem()))
113  {
114  (*it)->setExp((*it)->getExp() > itemPower.getExp() ? (*it)->getExp() : itemPower.getExp());
115  return true;
116  }
117  }
118 
119  CNormalItemPower* tmp = new CNormalItemPower(itemPower);
120  mItemPowers.insert(tmp);
121  return true;
122 }
123 
124 /**
125  * Add a fractionless sum to this lcm,
126  * ie. lcm := LeastCommonMultiple(lcm,sum)
127  * @return true.
128  */
129 bool CNormalLcm::add(const CNormalSum& sum)
130 {
131  switch (sum.getProducts().size())
132  {
133  case 0: //Sum must contain at least one product!
134  {
135  return false;
136  }
137 
138  case 1:
139  {
140  CNormalProduct* product = *sum.getProducts().begin();
141  std::set<CNormalItemPower*, compareItemPowers >::const_iterator it;
142  std::set<CNormalItemPower*, compareItemPowers >::const_iterator itEnd = product->getItemPowers().end();
143 
144  for (it = product->getItemPowers().begin(); it != itEnd; ++it)
145  {
146  add(**it);
147  }
148 
149  return true;
150  }
151 
152  default:
153  {
154  std::vector<CNormalSum*>::iterator it;
155  std::vector<CNormalSum*>::iterator itEnd = mSums.end();
156 
157  for (it = mSums.begin(); it != itEnd; ++it)
158  {
159  if (sum == **it)
160  {
161  return true;
162  }
163  }
164 
165  CNormalSum* tmp = new CNormalSum(sum);
166  mSums.push_back(tmp);
167  return true;
168  }
169  }
170 }
171 
172 /**
173  * Remove an itempower from this lcm, provided it is a factor
174  * @return true.
175  */
176 bool CNormalLcm::remove(const CNormalItemPower& itemPower)
177 {
178  std::set <CNormalItemPower*, compareItemPowers >::iterator it;
179  std::set <CNormalItemPower*, compareItemPowers >::iterator itEnd = mItemPowers.end();
180 
181  for (it = mItemPowers.begin(); it != itEnd; ++it)
182  {
183  if ((*it)->getItem().areEqual(itemPower.getItem()))
184  {
185  C_FLOAT64 dif = (*it)->getExp() - itemPower.getExp();
186 
187  if (dif <= -1.0E-100)
188  return false;
189 
190  if (fabs(dif) < 1.0E-100)
191  {
192  delete *it;
193  mItemPowers.erase(it);
194  return true;
195  }
196 
197  (*it)->setExp(dif);
198  return true;
199  }
200  }
201 
202  return false;
203 }
204 
205 /**
206  * Remove a fractionless sum from this lcm, provided it is a factor
207  * @return true.
208  */
209 bool CNormalLcm::remove(const CNormalSum& sum) //sum must not contain fractions!!
210 {
211  bool result = true;
212  std::set <CNormalItemPower*, compareItemPowers >::const_iterator it, itEnd;
213  std::vector<CNormalSum*>::iterator it2, itEnd2;
214  const CNormalProduct* pProduct = NULL;
215 
216  switch (sum.getProducts().size())
217  {
218  case 0:
219  result = false;
220  break;
221 
222  case 1:
223  pProduct = *sum.getProducts().begin();
224  itEnd = pProduct->getItemPowers().end();
225 
226  for (it = pProduct->getItemPowers().begin(); it != itEnd && result == true; ++it)
227  {
228  if (remove(**it) == false)
229  {
230  result = false;
231  }
232  }
233 
234  break;
235 
236  default:
237  itEnd2 = mSums.end();
238  result = false;
239 
240  for (it2 = mSums.begin(); it2 != itEnd2; ++it2)
241  {
242  if (**it2 == sum)
243  {
244  delete *it2;
245  mSums.erase(it2);
246  result = true;
247  break;
248  }
249  }
250 
251  // the below causes issues on VS, as in a way the iterator is no longer
252  // valid after removal, instead the result is set in the loop
253  //if (it2 == itEnd2)
254  //{
255  // result = false;
256  //}
257  }
258 
259  return result;
260 }
261 
262 /**
263  * Retrieve the set of itempowers of this lcm.
264  * @return mItemPowers.
265  */
266 const std::set <CNormalItemPower*, compareItemPowers >& CNormalLcm::getItemPowers() const
267 {
268  return mItemPowers;
269 }
270 
271 /**
272  * Retrieve the vector of sums of this lcm.
273  * @return mSums.
274  */
275 const std::vector<CNormalSum*>& CNormalLcm::getSums() const
276 {
277  return mSums;
278 }
279 
280 std::string CNormalLcm::toString() const
281 {
282  std::ostringstream os;
283  os << *this;
284  return os.str();
285 }
286 
287 std::ostream & operator<< (std::ostream &os, const CNormalLcm & d)
288 {
289  if (d.mItemPowers.size() + d.mSums.size() != 0)
290  {
291  bool firstFactor = true;
292  std::set <CNormalItemPower*, compareItemPowers >::const_iterator it;
293  std::set <CNormalItemPower*, compareItemPowers >::const_iterator itEnd = d.mItemPowers.end();
294 
295  for (it = d.mItemPowers.begin(); it != itEnd; ++it)
296  {
297  if (firstFactor == false)
298  {
299  os << " * ";
300  }
301 
302  os << **it;
303  firstFactor = false;
304  }
305 
306  std::vector<CNormalSum*>::const_iterator it2;
307  std::vector<CNormalSum*>::const_iterator it2End = d.mSums.end();
308 
309  for (it2 = d.mSums.begin(); it2 != it2End; ++it2)
310  {
311  if (firstFactor == false)
312  {
313  os << " * ";
314  }
315 
316  os << "(" << **it2 << ")";
317  firstFactor = false;
318  }
319  }
320  else
321  {
322  os << "1.0";
323  }
324 
325  return os;
326 }
327 
328 #ifdef COPASI_DEBUG
329 void CNormalLcm::refresh()
330 {
331  this->mInfix = this->toString();
332 }
333 #endif /* COPASI_DEBUG */
bool remove(const CNormalItemPower &itemPower)
Definition: CNormalLcm.cpp:176
const std::vector< CNormalSum * > & getSums() const
Definition: CNormalLcm.cpp:275
bool add(const CNormalItemPower &itemPower)
Definition: CNormalLcm.cpp:105
std::string toString() const
Definition: CNormalLcm.cpp:280
std::set< CNormalItemPower *, compareItemPowers > mItemPowers
Definition: CNormalLcm.h:39
std::ostream & operator<<(std::ostream &os, const CNormalLcm &d)
Definition: CNormalLcm.cpp:287
const std::set< CNormalItemPower *, compareItemPowers > & getItemPowers() const
const C_FLOAT64 & getExp() const
std::vector< CNormalSum * > mSums
Definition: CNormalLcm.h:40
#define C_FLOAT64
Definition: copasi.h:92
CNormalBase & getItem()
CNormalLcm & operator=(const CNormalLcm &src)
Definition: CNormalLcm.cpp:65
const std::set< CNormalProduct *, compareProducts > & getProducts() const
Definition: CNormalSum.cpp:416
const std::set< CNormalItemPower *, compareItemPowers > & getItemPowers() const
Definition: CNormalLcm.cpp:266