COPASI API  4.16.103
CNormalGeneralPower.cpp
Go to the documentation of this file.
1 // Begin CVS Header
2 // $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/compareExpressions/CNormalGeneralPower.cpp,v $
3 // $Revision: 1.10 $
4 // $Name: $
5 // $Author: gauges $
6 // $Date: 2008/08/02 14:09:17 $
7 // End CVS Header
8 
9 // Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
10 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
11 // and The University of Manchester.
12 // All rights reserved.
13 
14 // Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
15 // Properties, Inc. and EML Research, gGmbH.
16 // All rights reserved.
17 
18 #ifdef WIN32
19 # pragma warning (disable: 4786)
20 # pragma warning (disable: 4243)
21 // warning C4355: 'this' : used in base member initializer list
22 # pragma warning (disable: 4355)
23 #endif // WIN32
24 
25 #include <sstream>
26 
27 #include "CNormalGeneralPower.h"
28 #include "CNormalFraction.h"
29 #include "CNormalSum.h"
30 #include "CNormalProduct.h"
31 
32 const char* CNormalGeneralPower::SYMBOLS[] = {"^", "%"};
33 
34 CNormalGeneralPower::CNormalGeneralPower(): CNormalBase(), mType(CNormalGeneralPower::INVALID), mpLeft(NULL), mpRight(NULL)
35 {}
36 
37 CNormalGeneralPower::CNormalGeneralPower(const CNormalGeneralPower& src): CNormalBase(src), mType(src.getType()), mpLeft(new CNormalFraction(src.getLeft())), mpRight(new CNormalFraction(src.getRight()))
38 {}
39 
41 {
42  if (this->mpLeft != NULL) delete this->mpLeft;
43  if (this->mpRight != NULL) delete this->mpRight;
44 }
45 
47 {
48  if (this->mpLeft != NULL) delete this->mpLeft;
49  if (this->mpRight != NULL) delete this->mpRight;
50  this->mType = src.getType();
51  this->mpLeft = new CNormalFraction(src.getLeft());
52  this->mpRight = new CNormalFraction(src.getRight());
53  return *this;
54 }
55 
56 std::string CNormalGeneralPower::toString() const
57  {
58  std::ostringstream s;
59  if (this->mType != INVALID)
60  {
61  // if the exponent is not 1, we have to add parentheses around the left
62  // side, otherwise we don't
63  // we check the numerator and the denominator separately because if they
64  // are both equal bot not 1, we want to display the actual fraction not the
65  // canceled fraction
66  if (!(this->mpRight->getNumerator().checkIsOne() && this->mpRight->getDenominator().checkIsOne()))
67  {
68  s << "(" << *this->mpLeft << ")";
69  s << CNormalGeneralPower::SYMBOLS[this->mType] << "(" << *this->mpRight << ")";
70  }
71  else
72  {
73  // we also have to addd parentesis if the denominator of the left
74  // side is 1
75  if (this->mpLeft->checkDenominatorOne())
76  {
77  s << "(" << *this->mpLeft << ")";
78  }
79  else
80  {
81  s << *this->mpLeft;
82  }
83  }
84  }
85  else
86  {
87  s << "(!!!INVALID GENERAL POWER!!!)";
88  }
89  return s.str();
90  }
91 
93 {
94  return *this->mpLeft;
95 }
96 
98  {
99  return *this->mpLeft;
100  }
101 
103 {
104  if (this->mpLeft != NULL) delete this->mpLeft;
105  this->mpLeft = new CNormalFraction(left);
106 }
107 
109 {
110  return *this->mpRight;
111 }
112 
114  {
115  return *this->mpRight;
116  }
117 
119 {
120  if (this->mpRight != NULL) delete this->mpRight;
121  this->mpRight = new CNormalFraction(right);
122 }
123 
125  {
126  return this->mType;
127  }
128 
130 {
131  this->mType = type;
132 }
133 
134 std::ostream& operator<<(std::ostream& os, const CNormalGeneralPower& pow)
135 {
136  os << pow.toString();
137  return os;
138 }
139 
141  {
142  return ((this->mType == rhs.mType) && (*this->mpLeft) == (*rhs.mpLeft) && (*this->mpRight) == (*rhs.mpRight));
143  }
144 
146  {
147  bool result = false;
148  if (this->mType < rhs.mType)
149  {
150  result = true;
151  }
152  else if (this->mType == rhs.mType)
153  {
154  if ((*this->mpLeft) < (*rhs.mpLeft))
155  {
156  result = true;
157  }
158  else if ((*this->mpLeft) == (*rhs.mpLeft))
159  {
160  result = ((*this->mpRight) < (*rhs.mpRight));
161  }
162  }
163  return result;
164  }
165 
167 {
168  bool result = true;
169  if (this->mpLeft != NULL && this->mpRight != NULL)
170  {
171  result = (this->mpLeft->simplify() && this->mpRight->simplify());
172  }
173  return result;
174 }
175 
177  {
178  return new CNormalGeneralPower(*this);
179  }
180 
182 {
183  // make sure we don't multiply with a general power that is 1
184  // this would make the simplification process more complicated.
185  if (generalPower.checkIsOne()) return;
186  if (this->checkIsOne())
187  {
188  delete this->mpLeft;
189  delete this->mpRight;
190  this->mpLeft = new CNormalFraction(*generalPower.mpLeft);
191  this->mpRight = new CNormalFraction(*generalPower.mpRight);
192  }
193  else
194  {
195  // (A/B)^(C/D)*(E/F)^(G/H) -> // (A^(C/D)*E^(G/H))/(B^(C/D)*F^(G/H))
196  // new exponent is 1
198  // initialize the new base with 1
200  // the numerator of the new base is (A^(C/D)*E^(G/H))
201  CNormalProduct* pTmpProduct = (*pNewBase->getNumerator().getProducts().begin());
202  assert(pTmpProduct != NULL);
203  // A^(C/D)
204  if (!this->mpLeft->getNumerator().checkIsOne())
205  {
206  CNormalGeneralPower* pTmpPower = new CNormalGeneralPower();
208  CNormalFraction* pTmpFraction = new CNormalFraction(*pNewExponent);
209  pTmpFraction->setNumerator(this->mpLeft->getNumerator());
210  pTmpPower->setLeft(*pTmpFraction);
211  delete pTmpFraction;
212  pTmpPower->setRight(*this->mpRight);
213  pTmpProduct->multiply(*pTmpPower);
214  delete pTmpPower;
215  }
216  // E^(G/H)
217  if (!generalPower.mpLeft->getNumerator().checkIsOne())
218  {
219  CNormalGeneralPower* pTmpPower = new CNormalGeneralPower();
221  CNormalFraction* pTmpFraction = new CNormalFraction(*pNewExponent);
222  pTmpFraction->setNumerator(generalPower.mpLeft->getNumerator());
223  pTmpPower->setLeft(*pTmpFraction);
224  delete pTmpFraction;
225  pTmpPower->setRight(*generalPower.mpRight);
226  pTmpProduct->multiply(*pTmpPower);
227  delete pTmpPower;
228  }
229  // the denominator of the new base is (B^(C/D)*F^(G/H))
230  pTmpProduct = (*pNewBase->getDenominator().getProducts().begin());
231  assert(pTmpProduct != NULL);
232  // B^(C/D)
233  if (!this->mpLeft->getDenominator().checkIsOne())
234  {
235  CNormalGeneralPower* pTmpPower = new CNormalGeneralPower();
237  CNormalFraction* pTmpFraction = new CNormalFraction(*pNewExponent);
238  pTmpFraction->setNumerator(this->mpLeft->getDenominator());
239  pTmpPower->setLeft(*pTmpFraction);
240  delete pTmpFraction;
241  pTmpPower->setRight(*this->mpRight);
242  pTmpProduct->multiply(*pTmpPower);
243  delete pTmpPower;
244  }
245  // F^(G/H)
246  if (!generalPower.mpLeft->getDenominator().checkIsOne())
247  {
248  CNormalGeneralPower* pTmpPower = new CNormalGeneralPower();
250  CNormalFraction* pTmpFraction = new CNormalFraction(*pNewExponent);
251  pTmpFraction->setNumerator(generalPower.mpLeft->getDenominator());
252  pTmpPower->setLeft(*pTmpFraction);
253  delete pTmpFraction;
254  pTmpPower->setRight(*generalPower.mpRight);
255  pTmpProduct->multiply(*pTmpPower);
256  delete pTmpPower;
257  }
258  delete this->mpRight;
259  this->mpRight = pNewExponent;
260  delete this->mpLeft;
261  this->mpLeft = pNewBase;
262  }
263 }
264 
266  {
267  // the general power is one if either the exponent is 0.0
268  // or if the base is 1.0
269  return (this->mpLeft->checkIsOne() ||
270  this->mpRight->checkIsZero());
271  }
272 
274 {
275  CNormalGeneralPower* pGeneralPower = new CNormalGeneralPower();
276  pGeneralPower->setType(CNormalGeneralPower::POWER);
277  delete pGeneralPower->mpLeft;
278  delete pGeneralPower->mpRight;
279  pGeneralPower->mpLeft = CNormalFraction::createUnitFraction();
280  pGeneralPower->mpRight = CNormalFraction::createUnitFraction();
281  return pGeneralPower;
282 }
virtual bool simplify()
static const char * SYMBOLS[]
CNormalSum & getNumerator()
bool checkIsOne() const
CNormalFraction & getLeft()
bool operator==(const CNormalGeneralPower &rhs) const
static CNormalGeneralPower * createUnitGeneralPower()
void multiply(const CNormalGeneralPower &generalPower)
static CNormalFraction * createUnitFraction()
CNormalSum & getDenominator()
bool checkIsZero() const
CNormalFraction & getRight()
virtual CNormalBase * copy() const
void setRight(const CNormalFraction &right)
CNormalFraction * mpRight
bool checkDenominatorOne() const
bool setNumerator(const CNormalSum &numerator)
bool checkIsOne() const
Definition: CNormalSum.cpp:850
void setLeft(const CNormalFraction &left)
virtual std::string toString() const
std::ostream & operator<<(std::ostream &os, const CNormalGeneralPower &pow)
bool operator<(const CNormalGeneralPower &rhs) const
bool multiply(const C_FLOAT64 &number)
CNormalGeneralPower & operator=(const CNormalGeneralPower &src)
const std::set< CNormalProduct *, compareProducts > & getProducts() const
Definition: CNormalSum.cpp:416
CNormalFraction * mpLeft