COPASI API  4.16.103
CNormalSum.cpp
Go to the documentation of this file.
1 // Begin CVS Header
2 // $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/compareExpressions/CNormalSum.cpp,v $
3 // $Revision: 1.24 $
4 // $Name: $
5 // $Author: ssahle $
6 // $Date: 2012/04/22 14:51:17 $
7 // End CVS Header
8 
9 // Copyright (C) 2012 - 2010 by Pedro Mendes, Virginia Tech Intellectual
10 // Properties, Inc., University of Heidelberg, and The University
11 // of Manchester.
12 // All rights reserved.
13 
14 // Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
15 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
16 // and The University of Manchester.
17 // All rights reserved.
18 
19 // Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
20 // Properties, Inc. and EML Research, gGmbH.
21 // All rights reserved.
22 
23 #ifdef WIN32
24 # pragma warning (disable: 4786)
25 # pragma warning (disable: 4243)
26 // warning C4355: 'this' : used in base member initializer list
27 # pragma warning (disable: 4355)
28 #endif // WIN32
29 
30 #include <vector>
31 #include <cmath>
32 #include <sstream>
33 
34 #include "copasi.h"
35 
36 #include "CNormalItemPower.h"
37 #include "CNormalProduct.h"
38 #include "CNormalLcm.h"
39 #include "CNormalFraction.h"
40 #include "CNormalSum.h"
41 #include "CNormalGeneralPower.h"
42 
44 
45 bool compareProducts::operator()(const CNormalProduct* product1, const CNormalProduct* product2) const
46 {
47  // first compare the factors
48  if (product1->getFactor() < product2->getFactor())
49  {
50  return true;
51  }
52  else if (product2->getFactor() < product1->getFactor())
53  {
54  return false;
55  }
56 
57  std::set<CNormalItemPower*, compareItemPowers >::const_iterator it;
58  std::set<CNormalItemPower*, compareItemPowers >::const_iterator itEnd = product1->getItemPowers().end();
59  std::set<CNormalItemPower*, compareItemPowers >::const_iterator it2;
60  std::set<CNormalItemPower*, compareItemPowers >::const_iterator it2End = product2->getItemPowers().end();
61 
62  for (it = product1->getItemPowers().begin(), it2 = product2->getItemPowers().begin(); (it != itEnd) && (it2 != it2End); ++it, ++it2)
63  {
64  if (**it < **it2) return true;
65 
66  if (**it2 < **it) return false;
67  }
68 
69  return (product1->getItemPowers().size() < product2->getItemPowers().size());
70 }
71 
72 /**
73  * Default constructor
74  */
76 {}
77 
78 /**
79  * Copy Constructor
80  */
82 {
83  std::set<CNormalProduct*, compareProducts >::const_iterator it;
84  std::set<CNormalProduct*, compareProducts >::const_iterator itEnd = src.mProducts.end();
85  const CNormalProduct* pTmpProduct = NULL;
86 
87  for (it = src.mProducts.begin(); it != itEnd; ++it)
88  {
89  pTmpProduct = *it;
90  //std::string s = pTmpProduct->toString();
91  bool tmpRes = mProducts.insert(new CNormalProduct(*pTmpProduct)).second;
92  assert(tmpRes == true);
93  }
94 
95  std::set<CNormalFraction*>::const_iterator it2;
96  std::set<CNormalFraction*>::const_iterator it2End = src.mFractions.end();
97 
98  for (it2 = src.mFractions.begin(); it2 != it2End; ++it2)
99  {
100  bool tmpRes = mFractions.insert(new CNormalFraction(**it2)).second;
101  assert(tmpRes == true);
102  }
103 }
104 
105 /**
106  * Assignment operator
107  */
109 {
110  std::set<CNormalProduct*, compareProducts >::const_iterator it;
111  std::set<CNormalProduct*, compareProducts >::const_iterator itEnd = src.mProducts.end();
112 
113  for (it = src.mProducts.begin(); it != itEnd; ++it)
114  mProducts.insert(new CNormalProduct(**it));
115 
116  std::set<CNormalFraction*>::const_iterator it2;
117  std::set<CNormalFraction*>::const_iterator it2End = src.mFractions.end();
118 
119  for (it2 = src.mFractions.begin(); it2 != it2End; ++it2)
120  mFractions.insert(new CNormalFraction(**it2));
121 
122  return *this;
123 }
124 
125 /**
126  * Destructor
127  */
129 {
130  std::set<CNormalProduct*, compareProducts >::const_iterator it;
131  std::set<CNormalProduct*, compareProducts >::const_iterator itEnd = mProducts.end();
132 
133  for (it = mProducts.begin(); it != itEnd; ++it)
134  delete *it;
135 
136  std::set<CNormalFraction*>::const_iterator it2;
137  std::set<CNormalFraction*>::const_iterator it2End = mFractions.end();
138 
139  for (it2 = mFractions.begin(); it2 != it2End; ++it2)
140  delete *it2;
141 }
142 
143 /**
144  * Retrieve the number of summands of this sum.
145  * @return int
146  */
148 {
149  return mProducts.size() + mFractions.size();
150 }
151 
152 /**
153  * Add product to this sum.
154  * @return true.
155  */
156 bool CNormalSum::add(const CNormalProduct& product)
157 {
158  if (fabs(product.getFactor()) < 1.0E-100)
159  {
160  return true;
161  }
162 
163  std::set<CNormalProduct*, compareProducts >::iterator it = mProducts.begin();
164  std::set<CNormalProduct*, compareProducts >::iterator itEnd = mProducts.end();
165 
166  while (it != itEnd)
167  {
168  if ((*it)->checkSamePowerList(product))
169  {
170  (*it)->setFactor((*it)->getFactor() + product.getFactor());
171 
172  // if this results in a 0, remove the item
173  if (fabs((*it)->getFactor()) < 1.0E-100)
174  {
175  //unsigned int count=this->mProducts.size();
176  mProducts.erase(it);
177  //assert(count == this->mProducts.size()+1);
178  }
179 
180  return true;
181  }
182 
183  ++it;
184  }
185 
186  CNormalProduct* tmp = new CNormalProduct(product);
187  /*bool result=*/mProducts.insert(tmp);//.second;
188  //assert(result == true);
189  return true;
190 }
191 
192 /**
193  * Add fraction to this sum.
194  * @return true.
195  */
196 bool CNormalSum::add(const CNormalFraction& fraction)
197 {
198  if (fraction.getNumerator().getSize() == 0)
199  return true;
200 
201  std::set<CNormalFraction*>::iterator it;
202  std::set<CNormalFraction*>::iterator itEnd = mFractions.end();
203 
204  for (it = mFractions.begin(); it != itEnd; ++it)
205  {
206  if (**it == fraction)
207  {
208  (*it)->multiply(2.0);
209  return true;
210  }
211  }
212 
213  CNormalFraction* tmp = new CNormalFraction(fraction);
214  mFractions.insert(tmp);
215  return true;
216 }
217 
218 /**
219  * Add a sum to this sum.
220  * @return true.
221  */
222 bool CNormalSum::add(const CNormalSum& sum)
223 {
224  std::set<CNormalProduct*, compareProducts >::const_iterator itProduct = sum.mProducts.begin();
225  std::set<CNormalProduct*, compareProducts >::const_iterator itProductEnd = sum.mProducts.end();
226 
227  while (itProduct != itProductEnd)
228  {
229  add(**itProduct);
230  ++itProduct;
231  }
232 
233  std::set<CNormalFraction*>::const_iterator itFraction = sum.getFractions().begin();
234  std::set<CNormalFraction*>::const_iterator itFractionEnd = sum.getFractions().end();
235 
236  while (itFraction != itFractionEnd)
237  {
238  add(**itFraction);
239  ++itFraction;
240  }
241 
242  return true;
243 }
244 
245 /**
246  * Multiply this sum with a number.
247  * @return true.
248  */
249 bool CNormalSum::multiply(const C_FLOAT64& number)
250 {
251  if (fabs(number) < 1.0E-100)
252  {
253  std::set<CNormalProduct*, compareProducts >::iterator it3;
254  std::set<CNormalProduct*, compareProducts >::iterator it3End = mProducts.end();
255 
256  for (it3 = mProducts.begin(); it3 != it3End; ++it3)
257  delete *it3;
258 
259  std::set<CNormalFraction*>::iterator it4;
260  std::set<CNormalFraction*>::iterator it4End = mFractions.end();
261 
262  for (it4 = mFractions.begin(); it4 != it4End; ++it4)
263  delete *it4;
264 
265  return true;
266  }
267 
268  std::set<CNormalProduct*, compareProducts >::iterator it;
269  std::set<CNormalProduct*, compareProducts >::iterator itEnd = mProducts.end();
270 
271  for (it = mProducts.begin(); it != itEnd; ++it)
272  (*it)->multiply(number);
273 
274  std::set<CNormalFraction*>::iterator it2;
275  std::set<CNormalFraction*>::iterator it2End = mFractions.end();
276 
277  for (it2 = mFractions.begin(); it2 != it2End; ++it2)
278  (*it2)->multiply(number);
279 
280  return true;
281 }
282 
283 /**
284  * Multiply this sum with an itempower.
285  * @return true.
286  */
288 {
289  std::set<CNormalProduct*, compareProducts >::iterator it;
290  std::set<CNormalProduct*, compareProducts >::iterator itEnd = mProducts.end();
291 
292  for (it = mProducts.begin(); it != itEnd; ++it)
293  (*it)->multiply(itemPower);
294 
295  std::set<CNormalFraction*>::iterator it2;
296  std::set<CNormalFraction*>::iterator it2End = mFractions.end();
297 
298  for (it2 = mFractions.begin(); it2 != it2End; ++it2)
299  (*it2)->multiply(itemPower);
300 
301  return true;
302 }
303 
304 /**
305  * Multiply this sum with another sum, both do not contain fractions!!
306  * @return true.
307  */
309 {
310  std::set<CNormalProduct*, compareProducts > tmpProducts = mProducts;
311  mProducts.clear();
312  std::set<CNormalProduct*, compareProducts >::iterator it;
313  std::set<CNormalProduct*, compareProducts >::iterator itEnd = tmpProducts.end();
314  CNormalSum* pSum = NULL;
315 
316  for (it = tmpProducts.begin(); it != itEnd; ++it)
317  {
318  pSum = (*it)->multiply(sum);
319  assert(pSum != NULL);
320  add(*pSum);
321  delete pSum;
322  delete *it;
323  }
324 
325  return true;
326 }
327 
328 /**
329  * Multiply this sum by a lcm
330  * Numerator and denominator of mFractions do not contain further fractions!
331  * @return true.
332  */
334 {
335  //std::string s = lcm.toString();
336  std::set<CNormalProduct*, compareProducts > tmpProducts = mProducts;
337  mProducts.clear();
338  std::set<CNormalProduct*, compareProducts >::const_iterator it2;
339  std::set<CNormalProduct*, compareProducts >::const_iterator it2End = tmpProducts.end();
340 
341  for (it2 = tmpProducts.begin(); it2 != it2End; ++it2)
342  {
343  const CNormalSum* summand = (*it2)->multiply(lcm);
344  add(*summand);
345  delete summand;
346  delete *it2;
347  }
348 
349  std::set<CNormalFraction*>::const_iterator it;
350  std::set<CNormalFraction*>::const_iterator itEnd = mFractions.end();
351 
352  for (it = mFractions.begin(); it != itEnd; ++it)
353  {
354  const CNormalSum* summand2 = (*it)->multiply(lcm);
355  //std::string s2 = (*it)->toString();
356  assert(summand2 != NULL);
357  add(*summand2);
358  delete summand2;
359  delete *it;
360  }
361 
362  mFractions.clear(); //after multiplication this sum does not contain fractions anymore
363  return true;
364 }
365 
366 /**
367  * Divide this sum by an itempower, provided it is a factor of it
368  * -This sum does not contain fractions!
369  * @return true.
370  */
371 bool CNormalSum::divide(const CNormalItemPower& itemPower)
372 {
373  std::set<CNormalProduct*, compareProducts >::iterator it;
374  std::set<CNormalProduct*, compareProducts >::iterator itEnd = mProducts.end();
375 
376  for (it = mProducts.begin(); it != itEnd; ++it)
377  (*it)->remove(itemPower);
378 
379  return true;
380 }
381 
382 C_FLOAT64 CNormalSum::checkFactor(const CNormalItemPower& itemPower) const //sum does not contain fractions!!
383 {
384  // TODO incorporate the denominator of the product if it is not 1
385  C_FLOAT64 exp = itemPower.getExp();
386  std::set<CNormalProduct*, compareProducts >::const_iterator it;
387  std::set<CNormalProduct*, compareProducts >::const_iterator itEnd = mProducts.end();
388 
389  for (it = mProducts.begin(); it != itEnd; ++it)
390  {
391  bool containsFactor = false;
392  std::set<CNormalItemPower*, compareItemPowers >::const_iterator it2;
393  std::set<CNormalItemPower*, compareItemPowers >::const_iterator it2End = (*it)->getItemPowers().end();
394 
395  for (it2 = (*it)->getItemPowers().begin(); it2 != it2End; ++it2)
396  {
397  if ((*it2)->getItem().areEqual(itemPower.getItem()))
398  {
399  exp = (*it2)->getExp() < exp ? (*it2)->getExp() : exp;
400  containsFactor = true;
401  break;
402  }
403  }
404 
405  if (containsFactor == false)
406  return 0;
407  }
408 
409  return exp;
410 }
411 
412 /**
413  * Retrieve the set of products of this sum.
414  * @return mProducts
415  */
416 const std::set<CNormalProduct*, compareProducts >& CNormalSum::getProducts() const
417 {
418  return mProducts;
419 }
420 
421 /**
422  * Retrieve the set of fractions of this sum.
423  * @return mFractions.
424  */
425 const std::set<CNormalFraction*>& CNormalSum::getFractions() const
426 {
427  return mFractions;
428 }
429 
430 /**
431  * Examine equality of two sums.
432  * @return bool.
433  */
434 bool CNormalSum::operator==(const CNormalSum & rhs) const
435 {
436  if (mProducts.size() != rhs.mProducts.size())
437  return false;
438 
439  if (mFractions.size() != rhs.mFractions.size())
440  return false;
441 
442  std::set<CNormalProduct*, compareProducts >::const_iterator it;
443  std::set<CNormalProduct*, compareProducts >::const_iterator itEnd = this->mProducts.end();
444  std::set<CNormalProduct*, compareProducts >::const_iterator it2;
445  //std::set<CNormalProduct*, compareProducts >::const_iterator it2End = rhs.mProducts.end();
446 
447  for (it = mProducts.begin(), it2 = rhs.mProducts.begin(); it != itEnd; ++it, ++it2)
448  {
449  if (!(**it == **it2))
450  return false;
451  }
452 
453  std::set<CNormalFraction*>::const_iterator it3;
454  std::set<CNormalFraction*>::const_iterator it3End = this->mFractions.end();
455  std::set<CNormalFraction*>::const_iterator it4;
456  //std::set<CNormalFraction*>::const_iterator it4End = rhs.mFractions.end();
457 
458  for (it3 = mFractions.begin(), it4 = rhs.mFractions.begin(); it3 != it3End; ++it3, ++it4)
459  {
460  if (!(**it3 == **it4))
461  return false;
462  }
463 
464  return true;
465 }
466 
467 std::ostream & operator<< (std::ostream &os, const CNormalSum & d)
468 {
469  os << d.toString();
470  return os;
471 }
472 
473 std::string CNormalSum::toString() const
474 {
475  std::ostringstream os;
476 
477  if (this->getSize() != 0)
478  {
479  bool firstSummand = true;
480  std::set<CNormalProduct*, compareProducts >::const_iterator it;
481  std::set<CNormalProduct*, compareProducts >::const_iterator itEnd = this->mProducts.end();
482 
483  for (it = this->mProducts.begin(); it != itEnd; ++it)
484  {
485  if (firstSummand == false)
486  os << " + ";
487 
488  os << **it;
489  firstSummand = false;
490  }
491 
492  std::set<CNormalFraction*>::const_iterator it2;
493  std::set<CNormalFraction*>::const_iterator it2End = this->mFractions.end();
494 
495  for (it2 = this->mFractions.begin(); it2 != it2End; ++it2)
496  {
497  if (firstSummand == false)
498  os << " + ";
499 
500  os << **it2;
501  firstSummand = false;
502  }
503  }
504  else
505  os << "0.0";
506 
507  return os.str();
508 }
509 
511 {
512  return new CNormalSum(*this);
513 }
514 
515 bool CNormalSum::operator<(const CNormalSum& rhs) const
516 {
517  bool result = false;
518 
519  if (this->mFractions.size() < rhs.mFractions.size())
520  {
521  result = true;
522  }
523  else if (this->mFractions.size() == rhs.mFractions.size())
524  {
525  std::set<CNormalFraction*>::const_iterator it = this->mFractions.begin(), endit = this->mFractions.end();
526  std::set<CNormalFraction*>::const_iterator it2 = rhs.mFractions.begin();//, endit2 = rhs.mFractions.end();
527 
528  while (result == false && it != endit)
529  {
530  if ((**it) < (**it2))
531  {
532  result = true;
533  }
534  // if the fraction from the RHS is smaller than the one from here we
535  // stop and declare that the rhs is smaller
536  else if (!((**it) == (**it2)))
537  {
538  break;
539  }
540 
541  ++it;
542  ++it2;
543  }
544 
545  // if all fractions were equal
546  if (result == false && it == endit)
547  {
548  if (this->mProducts.size() < rhs.mProducts.size())
549  {
550  result = true;
551  }
552  else if (this->mProducts.size() == rhs.mProducts.size())
553  {
554  std::set<CNormalProduct*, compareProducts>::const_iterator it3 = this->mProducts.begin(), endit3 = this->mProducts.end();
555  std::set<CNormalProduct*, compareProducts>::const_iterator it4 = rhs.mProducts.begin();//, endit4 = rhs.mProducts.end();
556 
557  // I can not use the sorter to compare because the sorter does
558  // not take the factor of a product into account.
559  // This is a feature, but a bug
560  while (result == false && it3 != endit3)
561  {
562  if ((**it3) < (**it4))
563  {
564  result = true;
565  }
566  // if the fraction from the RHS is smaller than the one from here we
567  // stop and declare that the rhs is smaller
568  else if (!((**it3) == (**it4)))
569  {
570  break;
571  }
572 
573  ++it3;
574  ++it4;
575  }
576  }
577  }
578  }
579 
580  return result;
581 }
582 
583 void CNormalSum::setProducts(const std::set<CNormalProduct*, compareProducts>& set)
584 {
585  std::set<CNormalProduct*, compareProducts>::const_iterator it = this->mProducts.begin(), endit = this->mProducts.end();
586 
587  while (it != endit)
588  {
589  delete *it;
590  ++it;
591  }
592 
593  it = set.begin(), endit = set.end();
594  this->mProducts.clear();
595 
596  while (it != endit)
597  {
598  this->mProducts.insert(new CNormalProduct(**it));
599  ++it;
600  }
601 }
602 
603 void CNormalSum::setFractions(const std::set<CNormalFraction*>& set)
604 {
605  std::set<CNormalFraction*>::const_iterator it = this->mFractions.begin(), endit = this->mFractions.end();
606 
607  while (it != endit)
608  {
609  delete *it;
610  ++it;
611  }
612 
613  it = set.begin(), endit = set.end();
614  this->mFractions.clear();
615 
616  while (it != endit)
617  {
618  this->mFractions.insert(new CNormalFraction(**it));
619  ++it;
620  }
621 }
622 
624 {
625  bool result = true;
626  // it is a bad idea to work directly on the items in the set.
627  // this messes up the set
628  // better copy the set first
629  std::set<CNormalFraction*> fractionsCopy(this->mFractions);
630  this->mFractions.clear();
631  std::set<CNormalFraction*>::iterator it3 = fractionsCopy.begin(), endit3 = fractionsCopy.end();
632  CNormalFraction* pTmpFraction = NULL;
633 
634  while (it3 != endit3)
635  {
636  pTmpFraction = *it3;
637  pTmpFraction->simplify();
638  this->add(*pTmpFraction);
639  delete pTmpFraction;
640  ++it3;
641  }
642 
643  std::set<CNormalProduct*, compareProducts>::iterator it = this->mProducts.begin(), endit = this->mProducts.end();
644  // add code to find general power items with exponent 1 where the parent
645  // power item also has exponent 1
646  // if the base of those has a denominator of 1, we add the products of
647  // the numerator to this sum, otherwise, we have to add the whole base
648  // to the fractions of this sum
649  // afterwards, we have to simplify all products and all fractions again
650  std::vector<CNormalBase*> newProducts;
651  // go through all products and check the denominators
652  CNormalProduct* pTmpProduct;
653  CNormalBase* pTmpProduct2;
654 
655  while (it != endit)
656  {
657  pTmpProduct = *it;
658  pTmpProduct->simplify();
659 
660  if (pTmpProduct->getItemPowers().size() == 1 &&
661  fabs(((*pTmpProduct->getItemPowers().begin())->getExp() - 1.0) / 1.0) < 1e-12 &&
662  (*pTmpProduct->getItemPowers().begin())->getItemType() == CNormalItemPower::POWER &&
663  ((CNormalGeneralPower&)(*pTmpProduct->getItemPowers().begin())->getItem()).getRight().checkNumeratorOne() &&
664  ((CNormalGeneralPower&)(*pTmpProduct->getItemPowers().begin())->getItem()).getRight().checkDenominatorOne()
665  )
666  {
667  if (((CNormalGeneralPower&)(*pTmpProduct->getItemPowers().begin())->getItem()).getLeft().checkDenominatorOne())
668  {
669  // this copy returns a CNormalSum
670  // in order to keep the factor, we have to multiply
671  // the sum with the factor
672  pTmpProduct2 = ((CNormalGeneralPower&)(*pTmpProduct->getItemPowers().begin())->getItem()).getLeft().getNumerator().copy();
673  dynamic_cast<CNormalSum*>(pTmpProduct2)->multiply(pTmpProduct->getFactor());
674  newProducts.push_back(pTmpProduct2);
675  }
676  else
677  {
678  // this copy returns a fraction
679  // so in order to retain the factor, we need to multiply the fraction with
680  // a factor
681  pTmpProduct2 = ((CNormalGeneralPower&)(*pTmpProduct->getItemPowers().begin())->getItem()).getLeft().copy();
682  dynamic_cast<CNormalFraction*>(pTmpProduct2)->multiply(pTmpProduct->getFactor());
683  newProducts.push_back(pTmpProduct2);
684  }
685 
686  delete pTmpProduct;
687  }
688  else
689  {
690  // if the denominator is not NULL, transform the product to a fraction
691  CNormalGeneralPower* pDenom = pTmpProduct->getDenominator();
692 
693  if (pDenom == NULL || pDenom->checkIsOne())
694  {
695  newProducts.push_back(pTmpProduct);
696  }
697  else
698  {
699  // before creating the product, the denominators of all general items in
700  // the product have to be set to 1 by calling setDenominatorsOne on the product
701  pTmpProduct->setDenominatorsOne();
702  CNormalFraction* pFraction = NULL;
703 
704  if (pDenom->getRight().checkIsOne())
705  {
706  // the denominator is the left side of pDenom
707  pFraction = new CNormalFraction(pDenom->getLeft());
708  //
709  //pFraction = new CNormalFraction(pDenom->getLeft());
710  //// now we set the numerator
711  //CNormalSum* pSum = new CNormalSum();
712  //pSum->add(**it);
713  //pFraction->setNumerator(*pSum);
714  //delete pSum;
715  }
716  else
717  {
718  // the fraction has the found denominator as its denominator and the
719  // numerator is the product of all items
720  pFraction = new CNormalFraction();
721  CNormalSum* pSum = new CNormalSum();
722  pSum->add(*pTmpProduct);
723  pFraction->setNumerator(*pSum);
724  delete pSum;
725  // now we have to invert the general fraction that is the
726  // denominator
728  CNormalSum* pTmpSum = new CNormalSum(pDenom->getLeft().getDenominator());
729  pTmpFraction->setNumerator(*pTmpSum);
730  delete pTmpSum;
731  pDenom->setLeft(*pTmpFraction);
732  delete pTmpFraction;
734  CNormalItemPower* pTmpItemPower = new CNormalItemPower();
735  pTmpItemPower->setExp(1.0);
736  pTmpItemPower->setItem(*pDenom);
737  pTmpProduct->multiply(*pTmpItemPower);
738  delete pTmpItemPower;
739  pTmpSum = new CNormalSum();
740  pTmpSum->add(*pTmpProduct);
741  delete pTmpProduct;
742  pFraction->setDenominator(*pTmpSum);
743  delete pTmpSum;
744  }
745 
746  delete pTmpProduct;
747  newProducts.push_back(pFraction);
748  }
749 
750  if (pDenom != NULL) delete pDenom;
751  }
752 
753  ++it;
754  }
755 
756  this->mProducts.clear();
757  std::vector<CNormalBase*>::const_iterator it2 = newProducts.begin(), endit2 = newProducts.end();
758  const CNormalFraction* pFrac = NULL;
759  const CNormalSum* pSum = NULL;
760  const CNormalProduct* pProd = NULL;
761  std::set<CNormalSum*> multipliers;
762 
763  while (it2 != endit2)
764  {
765  pProd = dynamic_cast<const CNormalProduct*>(*it2);
766 
767  if (pProd != NULL)
768  {
769  this->add(*pProd);
770  }
771  else
772  {
773  pFrac = dynamic_cast<const CNormalFraction*>(*it2);
774 
775  if (pFrac != NULL)
776  {
777  this->add(*pFrac);
778  }
779  else
780  {
781  pSum = dynamic_cast<const CNormalSum*>(*it2);
782 
783  if (pSum != NULL)
784  {
785  this->add(*pSum);
786  /*
787  // check if the sum contains more then one product
788  // we have to multiply the sum with that other sum in the end
789  if(pSum->getProducts().size()>1)
790  {
791  multipliers.insert(static_cast<CNormalSum*>(pSum->copy()));
792  }
793  else
794  {
795  if(pSum->getProducts().size()==1 && (*pSum->getProducts().begin())->getItemPowers.size()==1)
796  {
797  // check if the one item power is a general power with
798  // an exponent of one and a denominator of one.
799  const CNormalItemPower* pPower=(*(*pSum->getProducts().begin())->getItemPowers().begin());
800  if(fabs(pPow->getExp()-1.0/1.0)<1e-12 && pPower->getItemType()==CNormalItemPower::POWER)
801  {
802  // check if it is a power operator and not modulo,
803  // check if the exponent is one and the denominator
804  // is one
805  const CNormalGeneralPower* pGenPow=static_cast<const CNormalGeneralPower*>(pPower->getItem());
806  if(pGenPow->getType()==CNormalGeneralPower::POWER && pGenPower->getRight().checkIsOne() && pGenPower->getLeft().checkDenominatorOne())
807  {
808  // check if there are more then one product in
809  }
810  else
811  {
812  this->add(*pSum);
813  }
814  }
815  else
816  {
817  this->add(*pSum);
818  }
819  }
820  else
821  {
822  this->add(*pSum);
823  }
824  }*/
825  }
826  else
827  {
828  // this can never happen
829  fatalError();
830  }
831  }
832  }
833 
834  delete *it2;
835  ++it2;
836  }
837 
838  std::set<CNormalSum*>::iterator it4 = multipliers.begin(), endit4 = multipliers.end();
839 
840  while (it4 != endit4)
841  {
842  this->multiply(**it4);
843  delete *it4;
844  ++it4;
845  }
846 
847  return result;
848 }
849 
851 {
852  bool result = false;
853 
854  if ((mProducts.size() == 1))
855  {
856 
857  CNormalGeneralPower* pTmpPow = (*mProducts.begin())->getDenominator();
858 
859  if ((mFractions.size() == 0)
860  && ((*mProducts.begin())->getItemPowers().size() == 0)
861  && (fabs((*mProducts.begin())->getFactor() - 1.0) < 1.E-100)
862  && ((pTmpPow == NULL) || (pTmpPow->checkIsOne()))
863  )
864  {
865  result = true;
866  }
867 
868  if (pTmpPow != NULL) delete pTmpPow;
869  }
870 
871  return result;
872 }
873 
875 {
876  // fractions must be zero and products must be either 0 or 1 with a
877  // factor of 0.0
878  if (mFractions.size() == 0 &&
879  (mProducts.size() == 0
880  || (mProducts.size() == 1 && ((*mProducts.begin())->getItemPowers().size() == 0) && (fabs((*mProducts.begin())->getFactor() - 0.0) < 1.E-100)))
881  )
882  {
883  return true;
884  }
885 
886  return false;
887 }
888 
890 {
891  CNormalSum* pSum = new CNormalSum();
893  pSum->add(*pTmpProduct);
894  delete pTmpProduct;
895  return pSum;
896 }
897 
899 {
900  std::set<CNormalProduct*, compareProducts >::const_iterator it = pSum->mProducts.begin();
901  std::set<CNormalProduct*, compareProducts >::const_iterator itEnd = pSum->mProducts.end();
902  std::cout << "products: " << std::endl;
903 
904  while (it != itEnd)
905  {
906  std::cout << (*it)->toString() << std::endl;
907  ++it;
908  }
909 
910  std::cout << std::endl;
911  std::cout << std::endl;
912  std::cout << std::endl;
913 
914 }
virtual bool simplify()
virtual bool simplify()
Definition: CNormalSum.cpp:623
CNormalSum & getNumerator()
static CNormalProduct * createUnitProduct()
bool checkIsOne() const
bool operator()(const CNormalProduct *product1, const CNormalProduct *product2) const
Definition: CNormalSum.cpp:45
int getSize() const
Definition: CNormalSum.cpp:147
virtual std::string toString() const
Definition: CNormalSum.cpp:473
CNormalFraction & getLeft()
virtual CNormalBase * copy() const
Definition: CNormalSum.cpp:510
#define fatalError()
virtual bool simplify()
std::set< CNormalProduct *, compareProducts > mProducts
Definition: CNormalSum.h:52
CNormalGeneralPower * getDenominator() const
std::ostream & operator<<(std::ostream &os, const CNormalSum &d)
Definition: CNormalSum.cpp:467
bool add(const CNormalProduct &product)
Definition: CNormalSum.cpp:156
C_FLOAT64 checkFactor(const CNormalItemPower &itemPower) const
Definition: CNormalSum.cpp:382
static CNormalFraction * createUnitFraction()
bool setItem(const CNormalBase &item)
const std::set< CNormalFraction * > & getFractions() const
Definition: CNormalSum.cpp:425
bool operator==(const CNormalSum &rhs) const
Definition: CNormalSum.cpp:434
bool divide(const CNormalItemPower &itemPower)
Definition: CNormalSum.cpp:371
CNormalSum & getDenominator()
bool setDenominator(const CNormalSum &denominator)
const std::set< CNormalItemPower *, compareItemPowers > & getItemPowers() const
CNormalFraction & getRight()
virtual ~CNormalSum()
Definition: CNormalSum.cpp:128
void setFractions(const std::set< CNormalFraction * > &set)
Definition: CNormalSum.cpp:603
const C_FLOAT64 & getFactor() const
CNormalSum & operator=(const CNormalSum &src)
Definition: CNormalSum.cpp:108
bool setNumerator(const CNormalSum &numerator)
#define C_FLOAT64
Definition: copasi.h:92
bool checkIsOne() const
Definition: CNormalSum.cpp:850
void setProducts(const std::set< CNormalProduct *, compareProducts > &set)
Definition: CNormalSum.cpp:583
bool checkIsZero() const
Definition: CNormalSum.cpp:874
void setLeft(const CNormalFraction &left)
std::set< CNormalFraction * > mFractions
Definition: CNormalSum.h:53
static CNormalSum * createUnitSum()
Definition: CNormalSum.cpp:889
static void printProducts(const CNormalSum *pSum)
Definition: CNormalSum.cpp:898
bool operator<(const CNormalSum &rhs) const
Definition: CNormalSum.cpp:515
bool multiply(const C_FLOAT64 &number)
virtual CNormalBase * copy() const =0
const std::set< CNormalProduct *, compareProducts > & getProducts() const
Definition: CNormalSum.cpp:416
bool multiply(const C_FLOAT64 &number)
Definition: CNormalSum.cpp:249
bool setExp(const C_FLOAT64 &number)