Cantera  2.2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Func1.cpp
Go to the documentation of this file.
1 //! @file Func1.cpp
4 
5 using namespace std;
6 
7 namespace Cantera
8 {
9 
10 Func1::Func1() :
11  m_c(0.0),
12  m_f1(0),
13  m_f2(0),
14  m_parent(0)
15 {
16 }
17 
18 Func1::Func1(const Func1& right) :
19  m_c(right.m_c),
20  m_f1(right.m_f1),
21  m_f2(right.m_f2),
22  m_parent(right.m_parent)
23 {
24 }
25 
26 Func1& Func1::operator=(const Func1& right)
27 {
28  if (&right == this) {
29  return *this;
30  }
31  m_c = right.m_c;
32  m_f1 = right.m_f1;
33  m_f2 = right.m_f2;
34  m_parent = right.m_parent;
35  return *this;
36 }
37 
39 {
40  Func1* nfunc = new Func1(*this);
41  return *nfunc;
42 }
43 
44 int Func1::ID() const
45 {
46  return 0;
47 }
48 
49 // Calls method eval to evaluate the function
50 doublereal Func1::operator()(doublereal t) const
51 {
52  return eval(t);
53 }
54 
55 // Evaluate the function.
56 doublereal Func1::eval(doublereal t) const
57 {
58  return 0.0;
59 }
60 
62 {
63  cout << "derivative error... ERR: ID = " << ID() << endl;
64  cout << write("x") << endl;
65  return *(new Func1);
66 }
67 
68 bool Func1::isIdentical(Func1& other) const
69 {
70  if ((ID() != other.ID()) || (m_c != other.m_c)) {
71  return false;
72  }
73  if (m_f1) {
74  if (!other.m_f1) {
75  return false;
76  }
77  if (!m_f1->isIdentical(*other.m_f1)) {
78  return false;
79  }
80  }
81  if (m_f2) {
82  if (!other.m_f2) {
83  return false;
84  }
85  if (!m_f2->isIdentical(*other.m_f2)) {
86  return false;
87  }
88  }
89  return true;
90 }
91 
92 //! accessor function for the returned constant
93 doublereal Func1::c() const
94 {
95  return m_c;
96 }
97 
98 // Function to set the stored constant
99 void Func1::setC(doublereal c)
100 {
101  m_c = c;
102 }
103 
104 //! accessor function for m_f1
106 {
107  return *m_f1;
108 }
109 
111 {
112  return *m_f2;
113 }
114 
115 int Func1::order() const
116 {
117  return 3;
118 }
119 
120 Func1& Func1::func1_dup() const
121 {
122  return m_f1->duplicate();
123 }
124 
125 Func1& Func1::func2_dup() const
126 {
127  return m_f2->duplicate();
128 }
129 
130 Func1* Func1::parent() const
131 {
132  return m_parent;
133 }
134 
135 void Func1::setParent(Func1* p)
136 {
137  m_parent = p;
138 }
139 
140 /*****************************************************************************/
141 
142 string Sin1::write(const string& arg) const
143 {
144  string c = "";
145  if (m_c != 1.0) {
146  c = fp2str(m_c);
147  }
148  return "\\sin(" + c + arg + ")";
149 }
150 
152 {
153  Func1* c = new Cos1(m_c);
154  Func1* r = &newTimesConstFunction(*c, m_c);
155  return *r;
156 }
157 /*****************************************************************************/
158 
160 {
161  Func1* s = new Sin1(m_c);
162  Func1* r = &newTimesConstFunction(*s, -m_c);
163  return *r;
164 }
165 
166 std::string Cos1::write(const std::string& arg) const
167 {
168  string c = "";
169  if (m_c != 1.0) {
170  c = fp2str(m_c);
171  }
172  return "\\cos("+c+arg+")";
173 }
174 
175 /**************************************************************************/
176 
178 {
179  Func1* f = new Exp1(m_c);
180  if (m_c != 1.0) {
181  return newTimesConstFunction(*f, m_c);
182  } else {
183  return *f;
184  }
185 }
186 
187 std::string Exp1::write(const std::string& arg) const
188 {
189  string c = "";
190  if (m_c != 1.0) {
191  c = fp2str(m_c);
192  }
193  return "\\exp("+c+arg+")";
194 }
195 
196 /******************************************************************************/
197 
199 {
200  Func1* r;
201  if (m_c == 0.0) {
202  r = new Const1(0.0);
203  } else if (m_c == 1.0) {
204  r = new Const1(1.0);
205  } else {
206  Func1* f = new Pow1(m_c - 1.0);
207  r = &newTimesConstFunction(*f, m_c);
208  }
209  return *r;
210 }
211 
212 string Func1::write(const std::string& arg) const
213 {
214  return "<unknown " + int2str(ID()) + ">("+arg+")";
215 }
216 
217 string Pow1::write(const std::string& arg) const
218 {
219  //cout << "Pow1" << endl;
220  string c = "";
221  if (m_c == 0.5) {
222  return "\\sqrt{" + arg + "}";
223  }
224  if (m_c == -0.5) {
225  return "\\frac{1}{\\sqrt{" + arg + "}}";
226  }
227  if (m_c != 1.0) {
228  c = fp2str(m_c);
229  return "\\left("+arg+"\\right)^{"+c+"}";
230  } else {
231  return arg;
232  }
233 }
234 
235 string Const1::write(const std::string& arg) const
236 {
237  return fp2str(m_c);
238 }
239 
240 string Ratio1::write(const std::string& arg) const
241 {
242  return "\\frac{" + m_f1->write(arg) + "}{"
243  + m_f2->write(arg) + "}";
244 }
245 
246 string Product1::write(const std::string& arg) const
247 {
248  string s = m_f1->write(arg);
249  if (m_f1->order() < order()) {
250  s = "\\left(" + s + "\\right)";
251  }
252  string s2 = m_f2->write(arg);
253  if (m_f2->order() < order()) {
254  s2 = "\\left(" + s2 + "\\right)";
255  }
256  return s + " " + s2;
257 }
258 
259 string Sum1::write(const std::string& arg) const
260 {
261  string s1 = m_f1->write(arg);
262  string s2 = m_f2->write(arg);
263  if (s2[0] == '-') {
264  return s1 + " - " + s2.substr(1,s2.size());
265  } else {
266  return s1 + " + " + s2;
267  }
268 }
269 
270 string Diff1::write(const std::string& arg) const
271 {
272  string s1 = m_f1->write(arg);
273  string s2 = m_f2->write(arg);
274  if (s2[0] == '-') {
275  return s1 + " + " + s2.substr(1,s2.size());
276  } else {
277  return s1 + " - " + s2;
278  }
279 }
280 
281 string Composite1::write(const std::string& arg) const
282 {
283  string g = m_f2->write(arg);
284  return m_f1->write(g);
285 }
286 
287 string TimesConstant1::write(const std::string& arg) const
288 {
289  string s = m_f1->write(arg);
290  if (m_f1->order() < order()) {
291  s = "\\left(" + s + "\\right)";
292  }
293  if (m_c == 1.0) {
294  return s;
295  }
296  if (m_c == -1.0) {
297  return "-"+s;
298  }
299  char n = s[0];
300  if (n >= '0' && n <= '9') {
301  s = "\\left(" + s + "\\right)";
302  }
303  return fp2str(m_c) + s;
304 }
305 
306 string PlusConstant1::write(const std::string& arg) const
307 {
308  if (m_c == 0.0) {
309  return m_f1->write(arg);
310  }
311  return m_f1->write(arg) + " + " + fp2str(m_c);
312 }
313 
314 doublereal Func1::isProportional(TimesConstant1& other)
315 {
316  if (isIdentical(other.func1())) {
317  return other.c();
318  }
319  return 0.0;
320 }
321 doublereal Func1::isProportional(Func1& other)
322 {
323  if (isIdentical(other)) {
324  return 1.0;
325  } else {
326  return 0.0;
327  }
328 }
329 
330 static bool isConstant(Func1& f)
331 {
332  if (f.ID() == ConstFuncType) {
333  return true;
334  } else {
335  return false;
336  }
337 }
338 
339 static bool isZero(Func1& f)
340 {
341  if (f.ID() == ConstFuncType && f.c() == 0.0) {
342  return true;
343  } else {
344  return false;
345  }
346 }
347 
348 static bool isOne(Func1& f)
349 {
350  if (f.ID() == ConstFuncType && f.c() == 1.0) {
351  return true;
352  } else {
353  return false;
354  }
355 }
356 
357 static bool isTimesConst(Func1& f)
358 {
359  if (f.ID() == TimesConstantFuncType) {
360  return true;
361  } else {
362  return false;
363  }
364 }
365 
366 static bool isExp(Func1& f)
367 {
368  if (f.ID() == ExpFuncType) {
369  return true;
370  } else {
371  return false;
372  }
373 }
374 
375 static bool isPow(Func1& f)
376 {
377  if (f.ID() == PowFuncType) {
378  return true;
379  } else {
380  return false;
381  }
382 }
383 
384 Func1& newSumFunction(Func1& f1, Func1& f2)
385 {
386  if (f1.isIdentical(f2)) {
387  return newTimesConstFunction(f1, 2.0);
388  }
389  if (isZero(f1)) {
390  delete &f1;
391  return f2;
392  }
393  if (isZero(f2)) {
394  delete &f2;
395  return f1;
396  }
397  doublereal c = f1.isProportional(f2);
398  if (c != 0) {
399  if (c == -1.0) {
400  return *(new Const1(0.0));
401  } else {
402  return newTimesConstFunction(f1, c + 1.0);
403  }
404  }
405  return *(new Sum1(f1, f2));
406 }
407 
408 Func1& newDiffFunction(Func1& f1, Func1& f2)
409 {
410  if (isZero(f2)) {
411  delete &f2;
412  return f1;
413  }
414  if (f1.isIdentical(f2)) {
415  delete &f1;
416  delete &f2;
417  return *(new Const1(0.0));
418  }
419  doublereal c = f1.isProportional(f2);
420  if (c != 0.0) {
421  if (c == 1.0) {
422  return *(new Const1(0.0));
423  } else {
424  return newTimesConstFunction(f1, 1.0 - c);
425  }
426  }
427  return *(new Diff1(f1, f2));
428 }
429 
430 Func1& newProdFunction(Func1& f1, Func1& f2)
431 {
432  if (isOne(f1)) {
433  delete &f1;
434  return f2;
435  }
436  if (isOne(f2)) {
437  delete &f2;
438  return f1;
439  }
440  if (isZero(f1) || isZero(f2)) {
441  delete &f1;
442  delete &f2;
443  return *(new Const1(0.0));
444  }
445  if (isConstant(f1) && isConstant(f2)) {
446  doublereal c1c2 = f1.c() * f2.c();
447  delete &f1;
448  delete &f2;
449  return *(new Const1(c1c2));
450  }
451  if (isConstant(f1)) {
452  doublereal c = f1.c();
453  delete &f1;
454  return newTimesConstFunction(f2, c);
455  }
456  if (isConstant(f2)) {
457  doublereal c = f2.c();
458  delete &f2;
459  return newTimesConstFunction(f1, c);
460  }
461 
462  if (isPow(f1) && isPow(f2)) {
463  Func1& p = *(new Pow1(f1.c() + f2.c()));
464  delete &f1;
465  delete &f2;
466  return p;
467  }
468 
469  if (isExp(f1) && isExp(f2)) {
470  Func1& p = *(new Exp1(f1.c() + f2.c()));
471  delete &f1;
472  delete &f2;
473  return p;
474  }
475 
476  bool tc1 = isTimesConst(f1);
477  bool tc2 = isTimesConst(f2);
478 
479  if (tc1 || tc2) {
480  doublereal c1 = 1.0, c2 = 1.0;
481  Func1* ff1 = 0, *ff2 = 0;
482  if (tc1) {
483  c1 = f1.c();
484  ff1 = &f1.func1_dup();
485  delete &f1;
486  } else {
487  ff1 = &f1;
488  }
489  if (tc2) {
490  c2 = f2.c();
491  ff2 = &f2.func1_dup();
492  delete &f2;
493  } else {
494  ff2 = &f2;
495  }
496  Func1& p = newProdFunction(*ff1, *ff2);
497 
498  if (c1* c2 != 1.0) {
499  return newTimesConstFunction(p, c1*c2);
500  } else {
501  return p;
502  }
503  } else {
504  return *(new Product1(f1, f2));
505  }
506 }
507 
508 Func1& newRatioFunction(Func1& f1, Func1& f2)
509 {
510  if (isOne(f2)) {
511  return f1;
512  }
513  if (isZero(f1)) {
514  return *(new Const1(0.0));
515  }
516  if (f1.isIdentical(f2)) {
517  delete &f1;
518  delete &f2;
519  return *(new Const1(1.0));
520  }
521  if (f1.ID() == PowFuncType && f2.ID() == PowFuncType) {
522  return *(new Pow1(f1.c() - f2.c()));
523  }
524  if (f1.ID() == ExpFuncType && f2.ID() == ExpFuncType) {
525  return *(new Exp1(f1.c() - f2.c()));
526  }
527  return *(new Ratio1(f1, f2));
528 }
529 
530 Func1& newCompositeFunction(Func1& f1, Func1& f2)
531 {
532  if (isZero(f1)) {
533  delete &f1;
534  delete &f2;
535  return *(new Const1(0.0));
536  }
537  if (isConstant(f1)) {
538  delete &f2;
539  return f1;
540  }
541  if (isPow(f1) && f1.c() == 1.0) {
542  delete &f1;
543  return f2;
544  }
545  if (isPow(f1) && f1.c() == 0.0) {
546  delete &f1;
547  delete &f2;
548  return *(new Const1(1.0));
549  }
550  if (isPow(f1) && isPow(f2)) {
551  doublereal c1c2 = f1.c() * f2.c();
552  delete &f1;
553  delete &f2;
554  return *(new Pow1(c1c2));
555  }
556  return *(new Composite1(f1, f2));
557 }
558 
559 Func1& newTimesConstFunction(Func1& f, doublereal c)
560 {
561  if (c == 0.0) {
562  delete &f;
563  return *(new Const1(0.0));
564  }
565  if (c == 1.0) {
566  return f;
567  }
568  if (f.ID() == TimesConstantFuncType) {
569  f.setC(f.c() * c);
570  return f;
571  }
572  return *(new TimesConstant1(f, c));
573 }
574 
575 Func1& newPlusConstFunction(Func1& f, doublereal c)
576 {
577  if (c == 0.0) {
578  return f;
579  }
580  if (isConstant(f)) {
581  doublereal cc = f.c() + c;
582  delete &f;
583  return *(new Const1(cc));
584  }
585  if (f.ID() == PlusConstantFuncType) {
586  f.setC(f.c() + c);
587  return f;
588  }
589  return *(new PlusConstant1(f, c));
590 }
591 
592 }
virtual int order() const
Return the order of the function, if it makes sense.
Definition: Func1.h:584
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
Definition: stringUtils.cpp:39
exp
Definition: Func1.h:212
Func1 & func2() const
accessor function for m_f2
Definition: Func1.cpp:110
pow
Definition: Func1.h:248
bool isIdentical(Func1 &other) const
Routine to determine if two functions are the same.
Definition: Func1.cpp:68
virtual Func1 & derivative() const
Creates a derivative to the current function.
Definition: Func1.cpp:61
implements the sin() function
Definition: Func1.h:135
virtual doublereal eval(doublereal t) const
Evaluate the function.
Definition: Func1.cpp:56
virtual Func1 & derivative() const
Creates a derivative to the current function.
Definition: Func1.cpp:177
virtual int order() const
Return the order of the function, if it makes sense.
Definition: Func1.cpp:115
cos
Definition: Func1.h:175
doublereal c() const
accessor function for the stored constant
Definition: Func1.cpp:93
Func1 & func1() const
accessor function for m_f1
Definition: Func1.cpp:105
virtual Func1 & duplicate() const
Duplicate the current function.
Definition: Func1.cpp:38
std::string fp2str(const double x, const std::string &fmt)
Convert a double into a c++ string.
Definition: stringUtils.cpp:28
void setC(doublereal c)
Function to set the stored constant.
Definition: Func1.cpp:99
virtual Func1 & derivative() const
Creates a derivative to the current function.
Definition: Func1.cpp:198
Base class for 'functor' classes that evaluate a function of one variable.
Definition: Func1.h:41
virtual int order() const
Return the order of the function, if it makes sense.
Definition: Func1.h:507
virtual Func1 & derivative() const
Creates a derivative to the current function.
Definition: Func1.cpp:159
Contains declarations for string manipulation functions within Cantera.
doublereal operator()(doublereal t) const
Calls method eval to evaluate the function.
Definition: Func1.cpp:50
virtual Func1 & derivative() const
Creates a derivative to the current function.
Definition: Func1.cpp:151
Constant.
Definition: Func1.h:285