COPASI API  4.16.103
CEvaluationNodeFunction.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010 - 2015 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) 2005 - 2007 by Pedro Mendes, Virginia Tech Intellectual
12 // Properties, Inc. and EML Research, gGmbH.
13 // All rights reserved.
14 
15 #include "copasi.h"
16 
17 #include "CEvaluationNode.h"
18 #include <sstream>
19 #include "CEvaluationTree.h"
20 
22 
23 #include "sbml/math/ASTNode.h"
24 #include "sbml/ConverterASTNode.h"
25 
26 CRandom * CEvaluationNodeFunction::mpRandom = NULL;
27 
28 // static
29 C_FLOAT64 CEvaluationNodeFunction::runiform(const C_FLOAT64 & lowerBound, const C_FLOAT64 & upperBound)
30 {return lowerBound + mpRandom->getRandomOO() * (upperBound - lowerBound);}
31 
32 // static
34 {return mpRandom->getRandomNormal(mean, sd);}
35 
36 //static
38  const C_FLOAT64 & scale)
39 {
40  return mpRandom->getRandomGamma(shape, scale);
41 }
42 
43 //static
45 {
46  return mpRandom->getRandomPoisson(mu);
47 }
48 
49 // static
51 {
52  return std::max(x1, x2);
53 }
54 
55 // static
57 {
58  return std::min(x1, x2);
59 }
60 
62  CEvaluationNode(CEvaluationNode::INVALID, ""),
63  mpFunction(NULL),
64  mpFunction2(NULL),
65  mpFunction4(NULL),
66  mpArg1(NULL),
67  mpArg2(NULL),
68  mpArg3(NULL),
69  mpArg4(NULL)
71 
73  const Data & data):
74  CEvaluationNode((Type)(CEvaluationNode::FUNCTION | subType), data),
75  mpFunction(NULL),
76  mpFunction2(NULL),
77  mpFunction4(NULL),
78  mpArg1(NULL),
79  mpArg2(NULL),
80  mpArg3(NULL),
81  mpArg4(NULL)
82 {
83  switch (subType)
84  {
85  case LOG:
86  mpFunction = log;
87  break;
88 
89  case LOG10:
90  mpFunction = log10;
91  break;
92 
93  case EXP:
94  mpFunction = exp;
95  break;
96 
97  case SIN:
98  mpFunction = sin;
99  break;
100 
101  case COS:
102  mpFunction = cos;
103  break;
104 
105  case TAN:
106  mpFunction = tan;
107  break;
108 
109  case SEC:
110  mpFunction = sec;
111  break;
112 
113  case CSC:
114  mpFunction = csc;
115  break;
116 
117  case COT:
118  mpFunction = cot;
119  break;
120 
121  case SINH:
122  mpFunction = sinh;
123  break;
124 
125  case COSH:
126  mpFunction = cosh;
127  break;
128 
129  case TANH:
130  mpFunction = tanh;
131  break;
132 
133  case SECH:
134  mpFunction = sech;
135  break;
136 
137  case CSCH:
138  mpFunction = csch;
139  break;
140 
141  case COTH:
142  mpFunction = coth;
143  break;
144 
145  case ARCSIN:
146  mpFunction = asin;
147  break;
148 
149  case ARCCOS:
150  mpFunction = acos;
151  break;
152 
153  case ARCTAN:
154  mpFunction = atan;
155  break;
156 
157  case ARCSEC:
158  mpFunction = arcsec;
159  break;
160 
161  case ARCCSC:
162  mpFunction = arccsc;
163  break;
164 
165  case ARCCOT:
166  mpFunction = arccot;
167  break;
168 
169  case ARCSINH:
170  mpFunction = asinh;
171  break;
172 
173  case ARCCOSH:
174  mpFunction = acosh;
175  break;
176 
177  case ARCTANH:
178  mpFunction = atanh;
179  break;
180 
181  case ARCSECH:
182  mpFunction = asech;
183  break;
184 
185  case ARCCSCH:
186  mpFunction = acsch;
187  break;
188 
189  case ARCCOTH:
190  mpFunction = acoth;
191  break;
192 
193  case SQRT:
194  mpFunction = sqrt;
195  break;
196 
197  case ABS:
198  mpFunction = fabs;
199  break;
200 
201  case FLOOR:
202  mpFunction = floor;
203  break;
204 
205  case CEIL:
206  mpFunction = ceil;
207  break;
208 
209  case FACTORIAL:
211  break;
212 
213  case MINUS:
214  mpFunction = minus;
215  break;
216 
217  case PLUS:
218  mpFunction = plus;
219  break;
220 
221  case NOT:
223  break;
224 
225  case RUNIFORM:
227 
228  if (!mpRandom)
230 
231  break;
232 
233  case RNORMAL:
235 
236  if (!mpRandom)
238 
239  break;
240 
241  case RPOISSON:
243 
244  if (!mpRandom)
246 
247  break;
248 
249  case RGAMMA:
251 
252  if (!mpRandom)
254 
255  break;
256 
257  case MAX:
258  mpFunction2 = max;
259  break;
260 
261  case MIN:
262  mpFunction2 = min;
263  break;
264 
265  default:
266  mpFunction = NULL;
267  fatalError();
268  break;
269  }
270 
272 }
273 
275  CEvaluationNode(src),
276  mpFunction(src.mpFunction),
277  mpFunction2(src.mpFunction2),
278  mpFunction4(src.mpFunction4),
279  mpArg1(NULL),
280  mpArg2(NULL),
281  mpArg3(NULL),
282  mpArg4(NULL)
283 {}
284 
286 
288 {
289  mpArg1 = static_cast<CEvaluationNode *>(getChild());
290 
291  if (mpArg1 == NULL) return false;
292 
293  if (mpFunction)
294  return (mpArg1->getSibling() == NULL); // We must have only one child
295 
296  mpArg2 = static_cast<CEvaluationNode *>(mpArg1->getSibling());
297 
298  if (mpArg2 == NULL) return false;
299 
300  if (mpFunction2)
301  return (mpArg2->getSibling() == NULL); // We must have exactly 1 children
302 
303  // equality
304  mpArg3 = static_cast<CEvaluationNode *>(mpArg2->getSibling());
305 
306  if (mpArg3 == NULL) return false;
307 
308  mpArg4 = static_cast<CEvaluationNode *>(mpArg3->getSibling());
309 
310  if (mpArg4 == NULL) return false;
311 
312  return (mpArg4->getSibling() == NULL); // We must have exactly 4 children
313 }
314 
315 // virtual
316 std::string CEvaluationNodeFunction::getInfix(const std::vector< std::string > & children) const
317 {
318  if (const_cast<CEvaluationNodeFunction *>(this)->compile(NULL))
319  switch (mType & 0x00FFFFFF)
320  {
321  case MINUS:
322  case PLUS:
323  return handleSign(children[0]);
324 
325  case RUNIFORM:
326  case RNORMAL:
327  case RGAMMA:
328  case MAX:
329  case MIN:
330  return mData + "(" + children[0] + "," + children[1] + ")";
331 
332  case RPOISSON:
333  return mData + "(" + children[0] + ")";
334 
335  case NOT:
336  return handleNot(children[0]);
337 
338  default:
339  return mData + "(" + children[0] + ")";
340  }
341  else
342  return "@";
343 }
344 
345 // virtual
346 std::string CEvaluationNodeFunction::getDisplayString(const std::vector< std::string > & children) const
347 {
348  if (const_cast<CEvaluationNodeFunction *>(this)->compile(NULL))
349  switch (mType & 0x00FFFFFF)
350  {
351  case MINUS:
352  case PLUS:
353  return handleSign(children[0]);
354 
355  case RUNIFORM:
356  case RNORMAL:
357  case RGAMMA:
358  case MAX:
359  case MIN:
360  return mData + "(" + children[0] + "," + children[1] + ")";
361 
362  case RPOISSON:
363  return mData + "(" + children[0] + ")";
364 
365  case NOT:
366  return handleNot(children[0]);
367 
368  default:
369  return mData + "(" + children[0] + ")";
370  }
371  else
372  return "@";
373 }
374 
375 // virtual
376 std::string CEvaluationNodeFunction::getCCodeString(const std::vector< std::string > & children) const
377 {
378  if (const_cast<CEvaluationNodeFunction *>(this)->compile(NULL))
379  {
380  std::string data = "";
381 
382  switch ((SubType)CEvaluationNode::subType(this->getType()))
383  {
384  case LOG:
385  data = "log";
386  break;
387 
388  case LOG10:
389  data = "log10";
390  break;
391 
392  case EXP:
393  data = "exp";
394  break;
395 
396  case SIN:
397  data = "sin";
398  break;
399 
400  case COS:
401  data = "cos";
402  break;
403 
404  case TAN:
405  data = "tan";
406  break;
407 
408  case SINH:
409  data = "sinh";
410  break;
411 
412  case COSH:
413  data = "cosh";
414  break;
415 
416  case TANH:
417  data = "tanh";
418  break;
419 
420  case ARCSIN:
421  data = "asin";
422  break;
423 
424  case ARCCOS:
425  data = "acos";
426  break;
427 
428  case ARCTAN:
429  data = "atan";
430  break;
431 
432  case ARCSINH:
433  data = "asinh";
434  break;
435 
436  case ARCCOSH:
437  data = "acosh";
438  break;
439 
440  case ARCTANH:
441  data = "atanh";
442  break;
443 
444  case SQRT:
445  data = "sqrt";
446  break;
447 
448  case ABS:
449  data = "abs";
450  break;
451 
452  case NOT:
453  data = "!";
454  break;
455 
456  case MINUS:
457  data = "-";
458  break;
459 
460  case PLUS:
461  break;
462 
463  case SEC:
464  data = "sec";
465  break;
466 
467  case CSC:
468  data = "csc";
469  break;
470 
471  case COT:
472  data = "cot";
473  break;
474 
475  case SECH:
476  data = "sech";
477  break;
478 
479  case CSCH:
480  data = "csch";
481  break;
482 
483  case COTH:
484  data = "coth";
485  break;
486 
487  case ARCSEC:
488  data = "arcsec";
489  break;
490 
491  case ARCCSC:
492  data = "arccsc";
493  break;
494 
495  case ARCCOT:
496  data = "arccot";
497  break;
498 
499  case ARCSECH:
500  data = "asech";
501  break;
502 
503  case ARCCSCH:
504  data = "acsch";
505  break;
506 
507  case ARCCOTH:
508  data = "acoth";
509  break;
510 
511  case FLOOR:
512  data = "floor";
513  break;
514 
515  case CEIL:
516  data = "ceil";
517  break;
518 
519  case FACTORIAL:
520  data = "factorial";
521  break;
522 
523  case RUNIFORM:
524  data = "user_provided_uniform";
525  break;
526 
527  case RNORMAL:
528  data = "user_provided_normal";
529  break;
530 
531  case RGAMMA:
532  data = "user_provided_normal";
533  break;
534 
535  case RPOISSON:
536  data = "user_provided_normal";
537  break;
538 
539  case MAX:
540  data = "max";
541  break;
542 
543  case MIN:
544  data = "min";
545  break;
546 
547  default:
548  data = "@";
549  break;
550  }
551 
552  switch (mType & 0x00FFFFFF)
553  {
554  case MINUS:
555  return "(" + data + children[0] + ")";
556  break;
557 
558  case PLUS:
559  //return handleSign(mpLeft->getDisplay_C_String(pTree));
560  return children[0];
561  break;
562 
563  case RUNIFORM:
564  case RNORMAL:
565  case RGAMMA:
566  case MAX:
567  case MIN:
568  return data + "(" + children[0] + "," + children[1] + ")";
569 
570  default:
571  return data + "(" + children[0] + ")";
572  }
573  }
574 
575  //else
576  return "@";
577 }
578 
579 // virtual
580 std::string CEvaluationNodeFunction::getBerkeleyMadonnaString(const std::vector< std::string > & children) const
581 {
582  std::string data = "";
583 
584  if (const_cast<CEvaluationNodeFunction *>(this)->compile(NULL))
585  {
586  data = mData;
587 
588  switch ((SubType)CEvaluationNode::subType(this->getType()))
589  {
590  case LOG:
591  case LOG10:
592  case EXP:
593  case SIN:
594  case COS:
595  case TAN:
596  case SINH:
597  case COSH:
598  case TANH:
599  case ARCSIN:
600  case ARCCOS:
601  case ARCTAN:
602  case ARCSINH:
603  case ARCCOSH:
604  case ARCTANH:
605  case SQRT:
606  case ABS:
607  case NOT:
608  break;
609 
610  case MINUS:
611  data = "-";
612  break;
613 
614  case PLUS:
615  data = "";
616  break;
617 
618  case SEC:
619  case CSC:
620  case COT:
621  case SECH:
622  case CSCH:
623  case COTH:
624  case ARCSEC:
625  case ARCCSC:
626  case ARCCOT:
627  case ARCSECH:
628  case ARCCSCH:
629  case ARCCOTH:
630  case FLOOR:
631  case CEIL:
632  case FACTORIAL:
633  case RUNIFORM:
634  case RNORMAL:
635  case RGAMMA:
636  case RPOISSON:
637  case MAX:
638  case MIN:
639  default:
640  data = "ILLEGAL FUNCTION";
641  break;
642  }
643 
644  switch (mType & 0x00FFFFFF)
645  {
646  case MINUS:
647  return "(" + data + children[0] + ")";
648  break;
649 
650  case PLUS:
651  //return handleSign(mpLeft->getDisplay_MMD_String(pTree));
652  return children[0];
653  break;
654 
655  case RUNIFORM:
656  case RNORMAL:
657  case RGAMMA:
658  case MAX:
659  case MIN:
660  return data + "(" + children[0] + "," + children[1] + ")";
661 
662  default:
663  return data + "(" + children[0] + ")";
664  }
665  }
666 
667  //else
668  return "@";
669 }
670 
671 // virtual
672 std::string CEvaluationNodeFunction::getXPPString(const std::vector< std::string > & children) const
673 {
674  std::string data = "";
675 
676  if (const_cast<CEvaluationNodeFunction *>(this)->compile(NULL))
677  {
678  data = mData;
679 
680  switch ((SubType)CEvaluationNode::subType(this->getType()))
681  {
682  case LOG:
683  case LOG10:
684  case EXP:
685  case SIN:
686  case COS:
687  case TAN:
688  case SINH:
689  case COSH:
690  case TANH:
691  case ARCSIN:
692  case ARCCOS:
693  case ARCTAN:
694  case SQRT:
695  case ABS:
696  case NOT:
697  case PLUS:
698  break;
699 
700  case MINUS:
701  data = "-";
702  break;
703 
704  case FLOOR:
705  data = "flr";
706  break;
707 
708  case CEIL:
709  data = "ceil";
710  break;
711 
712  case ARCSINH:
713  case ARCCOSH:
714  case ARCTANH:
715  case SEC:
716  case CSC:
717  case COT:
718  case SECH:
719  case CSCH:
720  case COTH:
721  case ARCSEC:
722  case ARCCSC:
723  case ARCCOT:
724  case ARCSECH:
725  case ARCCSCH:
726  case ARCCOTH:
727  case FACTORIAL:
728  case RUNIFORM:
729  case RNORMAL:
730  case RGAMMA:
731  case RPOISSON:
732  case MAX:
733  case MIN:
734  default:
735  data = "@"; //TODO
736  break;
737  }
738 
739  switch (mType & 0x00FFFFFF)
740  {
741  case MINUS:
742  return "(" + data + children[0] + ")";
743  break;
744 
745  case PLUS:
746  return children[0];
747  break;
748 
749  case RUNIFORM:
750  case RNORMAL:
751  case RGAMMA:
752  case MAX:
753  case MIN:
754  return data + "(" + children[0] + "," + children[1] + ")";
755 
756  default:
757  return data + "(" + children[0] + ")";
758  }
759  }
760  else
761  return "@"; //TODO
762 
763  return ""; //should never be reached, only because of warning
764 }
765 
766 // static
767 CEvaluationNode * CEvaluationNodeFunction::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children)
768 {
769  assert(pASTNode->getNumChildren() == children.size());
770 
771  size_t iMax = children.size();
772 
773  int type = (int)pASTNode->getType();
775  std::string data = "";
776 
777  if (type == AST_FUNCTION_ROOT)
778  {
779  CEvaluationNode * pNode = NULL;
780 
781  switch (iMax)
782  {
783  case 1:
785  pNode->addChild(children[0]);
786  break;
787 
788  case 2:
789  /**
790  * Replaces all root nodes with the corresponding power
791  * operator since COPASI does not have the ROOT function.
792  */
793  {
795  pNode->addChild(children[1]); // Value
797  pNode->addChild(pExponent);
799  pExponent->addChild(children[0]); // Degree
800  }
801  break;
802  }
803 
804  return pNode;
805  }
806  else if (type == AST_FUNCTION_LOG && iMax == 2)
807  {
808  /**
809  * Replaces all LOG10 (AST_FUNCTION_LOG) nodes that have two
810  * children with the quotient of two LOG10 nodes with the base
811  * as the argument for the divisor LOG10 node.
812  */
813 
816  pValue->addChild(children[1]);
818  pBase->addChild(children[0]);
819  pNode->addChild(pValue);
820  pNode->addChild(pBase);
821 
822  return pNode;
823  }
824 
825  switch (type)
826  {
827  case AST_FUNCTION_ABS:
828  subType = ABS;
829  data = "abs";
830  break;
831 
832  case AST_FUNCTION_ARCCOS:
833  subType = ARCCOS;
834  data = "acos";
835  break;
836 
837  case AST_FUNCTION_ARCCOSH:
838  subType = ARCCOSH;
839  data = "arccosh";
840  break;
841 
842  case AST_FUNCTION_ARCCOT:
843  subType = ARCCOT;
844  data = "arccot";
845  break;
846 
847  case AST_FUNCTION_ARCCOTH:
848  subType = ARCCOTH;
849  data = "arccoth";
850  break;
851 
852  case AST_FUNCTION_ARCCSC:
853  subType = ARCCSC;
854  data = "arccsc";
855  break;
856 
857  case AST_FUNCTION_ARCCSCH:
858  subType = ARCCSCH;
859  data = "arccsch";
860  break;
861 
862  case AST_FUNCTION_ARCSEC:
863  subType = ARCSEC;
864  data = "arcsec";
865  break;
866 
867  case AST_FUNCTION_ARCSECH:
868  subType = ARCSECH;
869  data = "arcsech";
870  break;
871 
872  case AST_FUNCTION_ARCSIN:
873  subType = ARCSIN;
874  data = "asin";
875  break;
876 
877  case AST_FUNCTION_ARCSINH:
878  subType = ARCSINH;
879  data = "arcsinh";
880  break;
881 
882  case AST_FUNCTION_ARCTAN:
883  subType = ARCTAN;
884  data = "atan";
885  break;
886 
887  case AST_FUNCTION_ARCTANH:
888  subType = ARCTANH;
889  data = "arctanh";
890  break;
891 
892  case AST_FUNCTION_CEILING:
893  subType = CEIL;
894  data = "ceil";
895  break;
896 
897  case AST_FUNCTION_COS:
898  subType = COS;
899  data = "cos";
900  break;
901 
902  case AST_FUNCTION_COSH:
903  subType = COSH;
904  data = "cosh";
905  break;
906 
907  case AST_FUNCTION_COT:
908  subType = COT;
909  data = "cot";
910  break;
911 
912  case AST_FUNCTION_COTH:
913  subType = COTH;
914  data = "coth";
915  break;
916 
917  case AST_FUNCTION_CSC:
918  subType = CSC;
919  data = "csc";
920  break;
921 
922  case AST_FUNCTION_CSCH:
923  subType = CSCH;
924  data = "csch";
925  break;
926 
927  case AST_FUNCTION_EXP:
928  subType = EXP;
929  data = "exp";
930  break;
931 
932  case AST_FUNCTION_FACTORIAL:
933  subType = FACTORIAL;
934  data = "factorial";
935  break;
936 
937  case AST_FUNCTION_FLOOR:
938  subType = FLOOR;
939  data = "floor";
940  break;
941 
942  case AST_FUNCTION_LN:
943  subType = LOG;
944  data = "log";
945  break;
946 
947  case AST_FUNCTION_LOG:
948  subType = LOG10;
949  data = "log10";
950  break;
951 
952  case AST_FUNCTION_SEC:
953  subType = SEC;
954  data = "sec";
955  break;
956 
957  case AST_FUNCTION_SECH:
958  subType = SECH;
959  data = "sech";
960  break;
961 
962  case AST_FUNCTION_SIN:
963  subType = SIN;
964  data = "sin";
965  break;
966 
967  case AST_FUNCTION_SINH:
968  subType = SINH;
969  data = "sinh";
970  break;
971 
972  case AST_FUNCTION_TAN:
973  subType = TAN;
974  data = "tan";
975  break;
976 
977  case AST_FUNCTION_TANH:
978  subType = TANH;
979  data = "tanh";
980  break;
981 
982  case AST_LOGICAL_NOT:
983  subType = NOT;
984  data = "not";
985  break;
986 
987  default:
988  subType = INVALID;
989  fatalError();
990  break;
991  }
992 
993  assert(iMax == 1);
994  CEvaluationNode * pNode = new CEvaluationNodeFunction(subType, data);
995 
996  if (!children.empty())
997  pNode->addChild(children[0]);
998 
999  return pNode;
1000 }
1001 
1002 // virtual
1004 {
1006  {
1007  case NOT:
1008  return true;
1009 
1010  default:
1011  return false;
1012  }
1013 }
1014 
1015 ASTNode* CEvaluationNodeFunction::toAST(const CCopasiDataModel* pDataModel) const
1016 {
1018  ASTNode* node = new ASTNode();
1019  bool needFirstArg = true;
1020 
1021  switch (subType)
1022  {
1023  case INVALID:
1024  break;
1025 
1026  case LOG:
1027  node->setType(AST_FUNCTION_LN);
1028  break;
1029 
1030  case LOG10:
1031  {
1032  // log 10 needs two children, the log and the base
1033  node->setType(AST_FUNCTION_LOG);
1034 
1035  ASTNode* logBase = new ASTNode();
1036  logBase->setType(AST_INTEGER);
1037  logBase->setValue(10);
1038  node->addChild(logBase);
1039 
1040  break;
1041  }
1042 
1043  case EXP:
1044  node->setType(AST_FUNCTION_EXP);
1045  break;
1046 
1047  case SIN:
1048  node->setType(AST_FUNCTION_SIN);
1049  break;
1050 
1051  case COS:
1052  node->setType(AST_FUNCTION_COS);
1053  break;
1054 
1055  case TAN:
1056  node->setType(AST_FUNCTION_TAN);
1057  break;
1058 
1059  case SEC:
1060  node->setType(AST_FUNCTION_SEC);
1061  break;
1062 
1063  case CSC:
1064  node->setType(AST_FUNCTION_CSC);
1065  break;
1066 
1067  case COT:
1068  node->setType(AST_FUNCTION_COT);
1069  break;
1070 
1071  case SINH:
1072  node->setType(AST_FUNCTION_SINH);
1073  break;
1074 
1075  case COSH:
1076  node->setType(AST_FUNCTION_COSH);
1077  break;
1078 
1079  case TANH:
1080  node->setType(AST_FUNCTION_TANH);
1081  break;
1082 
1083  case SECH:
1084  node->setType(AST_FUNCTION_SECH);
1085  break;
1086 
1087  case CSCH:
1088  node->setType(AST_FUNCTION_CSCH);
1089  break;
1090 
1091  case COTH:
1092  node->setType(AST_FUNCTION_COTH);
1093  break;
1094 
1095  case ARCSIN:
1096  node->setType(AST_FUNCTION_ARCSIN);
1097  break;
1098 
1099  case ARCCOS:
1100  node->setType(AST_FUNCTION_ARCCOS);
1101  break;
1102 
1103  case ARCTAN:
1104  node->setType(AST_FUNCTION_ARCTAN);
1105  break;
1106 
1107  case ARCSEC:
1108  node->setType(AST_FUNCTION_ARCSEC);
1109  break;
1110 
1111  case ARCCSC:
1112  node->setType(AST_FUNCTION_ARCCSC);
1113  break;
1114 
1115  case ARCCOT:
1116  node->setType(AST_FUNCTION_ARCCOT);
1117  break;
1118 
1119  case ARCSINH:
1120  node->setType(AST_FUNCTION_ARCSINH);
1121  break;
1122 
1123  case ARCCOSH:
1124  node->setType(AST_FUNCTION_ARCCOSH);
1125  break;
1126 
1127  case ARCTANH:
1128  node->setType(AST_FUNCTION_ARCTANH);
1129  break;
1130 
1131  case ARCSECH:
1132  node->setType(AST_FUNCTION_ARCSECH);
1133  break;
1134 
1135  case ARCCSCH:
1136  node->setType(AST_FUNCTION_ARCCSCH);
1137  break;
1138 
1139  case ARCCOTH:
1140  node->setType(AST_FUNCTION_ARCCOTH);
1141  break;
1142 
1143  case SQRT:
1144  node->setType(AST_FUNCTION_ROOT);
1145  break;
1146 
1147  case ABS:
1148  node->setType(AST_FUNCTION_ABS);
1149  break;
1150 
1151  case CEIL:
1152  node->setType(AST_FUNCTION_CEILING);
1153  break;
1154 
1155  case FLOOR:
1156  node->setType(AST_FUNCTION_FLOOR);
1157  break;
1158 
1159  case FACTORIAL:
1160  node->setType(AST_FUNCTION_FACTORIAL);
1161  break;
1162 
1163  case MINUS:
1164  node->setType(AST_MINUS);
1165  break;
1166 
1167  case PLUS:
1168  // if this is the unary plus as I suspect,
1169  // the node will be replaced by its only child
1170  delete node;
1171  node = dynamic_cast<const CEvaluationNode*>(this->getChild())->toAST(pDataModel);
1172  break;
1173 
1174  case NOT:
1175  node->setType(AST_LOGICAL_NOT);
1176  break;
1177 
1178  case RUNIFORM:
1179  {
1180  needFirstArg = false;
1181  node->setType(AST_FUNCTION);
1182  node->setName("RUNIFORM");
1183  const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
1184  const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling());
1185  node->addChild(child->toAST(pDataModel));
1186  node->addChild(sibling->toAST(pDataModel));
1187  }
1188  break;
1189 
1190  case RNORMAL:
1191  {
1192  needFirstArg = false;
1193  node->setType(AST_FUNCTION);
1194  node->setName("RNORMAL");
1195  const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
1196  const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling());
1197  node->addChild(child->toAST(pDataModel));
1198  node->addChild(sibling->toAST(pDataModel));
1199  }
1200  break;
1201 
1202  case RGAMMA:
1203  {
1204  needFirstArg = false;
1205  node->setType(AST_FUNCTION);
1206  node->setName("RGAMMA");
1207  const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
1208  const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling());
1209  node->addChild(child->toAST(pDataModel));
1210  node->addChild(sibling->toAST(pDataModel));
1211  }
1212  break;
1213 
1214  case RPOISSON:
1215  {
1216  needFirstArg = false;
1217  node->setType(AST_FUNCTION);
1218  node->setName("RPOISSON");
1219  const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
1220  node->addChild(child->toAST(pDataModel));
1221  }
1222  break;
1223 
1224  case MAX:
1225  {
1226  needFirstArg = false;
1227  node->setType(AST_FUNCTION);
1228  node->setName("MAX");
1229  const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
1230  const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling());
1231  node->addChild(child->toAST(pDataModel));
1232  node->addChild(sibling->toAST(pDataModel));
1233  }
1234  break;
1235 
1236  case MIN:
1237  {
1238  needFirstArg = false;
1239  node->setType(AST_FUNCTION);
1240  node->setName("MIN");
1241  const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
1242  const CEvaluationNode* sibling = dynamic_cast<const CEvaluationNode*>(child->getSibling());
1243  node->addChild(child->toAST(pDataModel));
1244  node->addChild(sibling->toAST(pDataModel));
1245  }
1246  break;
1247  // :TODO: Bug 894: Implement me.
1248  //fatalError();
1249  break;
1250  }
1251 
1252  if (subType != INVALID)
1253  {
1254  // the following is a workaround for a bug in libsbml 3.1.1 and 3.2.0
1255  // where libsbml does not handle the case correctly that a root
1256  // function can have one or two children (MathML.cpp in function
1257  // writeFunctionRoot)
1258  if (subType == SQRT)
1259  {
1260  // add a degree node of value 2 as the first child
1261  ASTNode* pDegreeNode = new ASTNode();
1262  pDegreeNode->setType(AST_INTEGER);
1263  pDegreeNode->setValue(2);
1264  node->addChild(pDegreeNode);
1265  }
1266 
1267  if (needFirstArg)
1268  {
1269  const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(this->getChild());
1270  node->addChild(child->toAST(pDataModel));
1271  }
1272  }
1273 
1274  return node;
1275 }
1276 
1277 CEvaluationNode* CEvaluationNodeFunction::simplifyNode(const std::vector<CEvaluationNode*>& children) const
1278 {
1279  assert(children.size() > 0);
1280  CEvaluationNode* child1 = children[0];
1281 
1282  switch (mType & 0x00FFFFFF)
1283  {
1284  case MINUS:
1285  {
1286  switch (CEvaluationNode::type(child1->getType()))
1287  {
1289  {
1290  switch ((CEvaluationNodeOperator::SubType) CEvaluationNode::subType(child1->getType()))
1291  {
1293  {
1294  // -(a/b) -> (-a)/b
1295  // want to recognize a fraction in a sum easily
1297  CEvaluationNode *newchild1 = CEvaluationNode::create((Type)(FUNCTION | MINUS), "-");
1298  CEvaluationNode *newchild2 = dynamic_cast<CEvaluationNode*>(child1->getChild()->getSibling())->copyBranch();
1299  CEvaluationNode *grandchild = dynamic_cast<CEvaluationNode*>(child1->getChild())->copyBranch();
1300  newnode->addChild(newchild1, NULL);
1301  newnode->addChild(newchild2, newchild1);
1302  newchild1->addChild(grandchild, NULL);
1303  delete child1;
1304  return newnode;
1305  }
1306 
1308  {
1309  // -(a+b) -> (-a)+(-b)
1310  // negativity should be property of product
1312  CEvaluationNode *newchild1 = CEvaluationNode::create((Type)(FUNCTION | MINUS), "-");
1313  CEvaluationNode *newchild2 = CEvaluationNode::create((Type)(FUNCTION | MINUS), "-");
1314  CEvaluationNode *grandchild1 = dynamic_cast<CEvaluationNode*>(child1->getChild())->copyBranch();
1315  CEvaluationNode *grandchild2 = dynamic_cast<CEvaluationNode*>(child1->getChild()->getSibling())->copyBranch();
1316  newnode->addChild(newchild1, NULL);
1317  newnode->addChild(newchild2, newchild1);
1318  newchild1->addChild(grandchild1, NULL);
1319  newchild2->addChild(grandchild2, NULL);
1320  delete child1;
1321  return newnode;
1322  }
1323 
1324  default: // cases POWER, MULTIPLY, MODULUS. don't expect MINUS to occur anymore
1325  {
1326  CEvaluationNode *newnode = copyNode(children);
1327  return newnode;
1328  }
1329  }
1330  }
1331 
1333  {
1334  if (child1->getData() == "-")
1335  {
1336  // -(-a) -> a
1337  CEvaluationNode *newnode = dynamic_cast<CEvaluationNode*>(child1->getChild())->copyBranch();
1338  delete child1;
1339  return newnode;
1340  }
1341 
1342  // default: copy
1343  CEvaluationNode *newnode = copyNode(children);
1344  return newnode;
1345  }
1346 
1348  {
1349  std::stringstream tmp;
1350  tmp << child1->getValue() *(-1.0);
1352  delete child1;
1353  return newnode;
1354  }
1355 
1356  default: //cases VARIABLE, CONSTANT..
1357  {
1358  CEvaluationNode *newnode = copyNode(children);
1359  return newnode;
1360  }
1361  }
1362 
1363  break;
1364  }
1365 
1366  case SQRT:
1367  {
1368  // write as ^0.5
1371  newnode->addChild(child1, NULL);
1372  newnode->addChild(newchild2, child1);
1373  return newnode;
1374  }
1375 
1376  default:
1377  {
1378  CEvaluationNode *newnode = copyNode(children);
1379  return newnode;
1380  }
1381  }
1382 }
1383 
1384 std::string CEvaluationNodeFunction::handleSign(const std::string & str) const
1385 {
1386  Data Result;
1387 
1388  Type T = mpArg1->getType();
1389 
1390  if ((T & 0xFF000000) == OPERATOR)
1391  {
1392  Result = mData + "(" + str + ")";
1393  }
1394  else if (getParent() != NULL &&
1395  static_cast< const CEvaluationNode * >(getParent())->getType() == (OPERATOR | CEvaluationNodeOperator::POWER))
1396  {
1397  Result = "(" + mData + str + ")";
1398  }
1399  else
1400  {
1401  Result = mData + str;
1402  }
1403 
1404  return Result;
1405 }
1406 
1407 std::string CEvaluationNodeFunction::handleNot(const std::string & str) const
1408 {
1409  Data Result = mData + " ";
1410 
1411  Type T = mpArg1->getType();
1412 
1413  if ((T & 0xFF000000) == LOGICAL)
1414  {
1415  Result += "(" + str + ")";
1416  }
1417  else
1418  Result += str;
1419 
1420  return Result;
1421 }
1422 
1424 {return mpArg1;}
1426 {return mpArg1;}
1427 
1428 #include "utilities/copasimathml.h"
1429 
1430 // virtual
1431 std::string CEvaluationNodeFunction::getMMLString(const std::vector< std::string > & children,
1432  bool expand,
1433  const std::vector< std::vector< std::string > > & /* variables */) const
1434 {
1435  std::ostringstream out;
1436 
1437  std::string data = "";
1438  std::string ldata = "";
1439  std::string rdata = "";
1440 
1444 
1445  bool flag1 = false;
1446 
1447  switch (mType & 0x00FFFFFF)
1448  {
1449  case INVALID:
1450  data = "@";
1451  break;
1452 
1453  case LOG:
1454  data = "ln";
1455  break;
1456 
1457  case LOG10:
1458  break;
1459 
1460  case EXP:
1461  break;
1462 
1463  case SIN:
1464  data = "sin";
1465  break;
1466 
1467  case COS:
1468  data = "cos";
1469  break;
1470 
1471  case TAN:
1472  data = "tan";
1473  break;
1474 
1475  case SEC:
1476  data = "sec";
1477  break;
1478 
1479  case CSC:
1480  data = "csc";
1481  break;
1482 
1483  case COT:
1484  data = "cot";
1485  break;
1486 
1487  case SINH:
1488  data = "sinh";
1489  break;
1490 
1491  case COSH:
1492  data = "cosh";
1493  break;
1494 
1495  case TANH:
1496  data = "tanh";
1497  break;
1498 
1499  case SECH:
1500  data = "sech";
1501  break;
1502 
1503  case CSCH:
1504  data = "csch";
1505  break;
1506 
1507  case COTH:
1508  data = "coth";
1509  break;
1510 
1511  case ARCSIN:
1512  data = "arcsin";
1513  break;
1514 
1515  case ARCCOS:
1516  data = "arccos";
1517  break;
1518 
1519  case ARCTAN:
1520  data = "arctan";
1521  break;
1522 
1523  case ARCSEC:
1524  data = "arcsec";
1525  break;
1526 
1527  case ARCCSC:
1528  data = "arccsc";
1529  break;
1530 
1531  case ARCCOT:
1532  data = "arccot";
1533  break;
1534 
1535  case ARCSINH:
1536  data = "arcsinh";
1537  break;
1538 
1539  case ARCCOSH:
1540  data = "arccosh";
1541  break;
1542 
1543  case ARCTANH:
1544  data = "arctanh";
1545  break;
1546 
1547  case ARCSECH:
1548  data = "arcsech";
1549  break;
1550 
1551  case ARCCSCH:
1552  data = "arccsch";
1553  break;
1554 
1555  case ARCCOTH:
1556  data = "arccoth";
1557  break;
1558 
1559  case SQRT:
1560  ldata = "<msqrt>";
1561  rdata = "</msqrt>";
1562  break;
1563 
1564  case ABS:
1565  ldata = "|";
1566  rdata = "|";
1567  break;
1568 
1569  case CEIL:
1570  data = "ceil";
1571  break;
1572 
1573  case FLOOR:
1574  data = "floor";
1575  break;
1576 
1577  case FACTORIAL:
1578  break;
1579 
1580  case MINUS:
1581  break;
1582 
1583  case PLUS:
1584  break;
1585 
1586  case NOT:
1587  data = "!";
1588  break;
1589  }
1590 
1591  const CEvaluationNode * pParent = static_cast<const CEvaluationNode *>(getParent());
1592 
1593  out << "<mrow>" << std::endl;
1594 
1595  switch (mType & 0x00FFFFFF)
1596  {
1597  case PLUS:
1598 
1599  flag = ((mpArg1->getType() == (CEvaluationNode::OPERATOR | PLUS))
1601  || (((mpArg1->getType() & 0xFF000000) == CEvaluationNode::CALL) && expand));
1602 
1603  if (flag) out << "<mfenced>" << std::endl;
1604 
1605  out << children[0];
1606 
1607  if (flag) out << "</mfenced>" << std::endl;
1608 
1609  break;
1610 
1611  case MINUS:
1612 
1613  if (pParent != 0)
1614  {
1615  Type T = pParent->getType();
1616 
1617  flag1 = ((T & 0xFF000000) == OPERATOR &&
1618  this == static_cast<const CEvaluationNode *>(pParent->getChild()->getSibling()));
1619 
1620  flag1 |= (T == (OPERATOR | CEvaluationNodeOperator::POWER));
1621 
1622  if (flag1) out << "<mfenced>" << std::endl;
1623 
1624  if (flag1) out << "<mrow>" << std::endl;
1625  }
1626 
1627  out << "<mo>" << "-" << "</mo>" << std::endl;
1628 
1629  if (!flag) out << "<mfenced>" << std::endl;
1630 
1631  out << children[0];
1632 
1633  if (!flag) out << "</mfenced>" << std::endl;
1634 
1635  if (flag1) out << "</mrow>" << std::endl;
1636 
1637  if (flag1) out << "</mfenced>" << std::endl;
1638 
1639  break;
1640 
1641  case FACTORIAL:
1642 
1643  if (!flag) out << "<mfenced>" << std::endl;
1644 
1645  out << children[0];
1646 
1647  if (!flag) out << "</mfenced>" << std::endl;
1648 
1649  out << "<mo>" << "!" << "</mo>" << std::endl;
1650 
1651  break;
1652 
1653  case SQRT:
1654  case ABS:
1655 
1656  out << ldata << std::endl;
1657 
1658  out << children[0];
1659 
1660  out << rdata << std::endl;
1661 
1662  break;
1663 
1664  case EXP:
1665 
1666  out << "<msup>" << std::endl;
1667  out << "<mo> e </mo>" << std::endl;
1668 
1669  out << children[0];
1670 
1671  out << "</msup>" << std::endl;
1672 
1673  break;
1674 
1675  case LOG10:
1676 
1677  out << "<msub>" << std::endl;
1678  out << "<mo>" << "log" << "</mo>" << std::endl;
1679  out << "<mn>" << "10" << "</mn>" << std::endl;
1680 
1681  out << "</msub>" << std::endl;
1682 
1683  if (flag)
1684  out << "<mspace width=\"0.3em\"/>" << std::endl;
1685  else
1686  out << "<mfenced>" << std::endl;
1687 
1688  out << children[0];
1689 
1690  if (!flag) out << "</mfenced>" << std::endl;
1691 
1692  break;
1693 
1694  case CEIL:
1695  case FLOOR:
1696  out << "<mi> " << data << " </mi>" << std::endl;
1697 
1698  out << "<mfenced>" << std::endl;
1699 
1700  out << children[0];
1701 
1702  out << "</mfenced>" << std::endl;
1703 
1704  break;
1705 
1706  case RUNIFORM:
1707  case RNORMAL:
1708  case RGAMMA:
1709  case MAX:
1710  case MIN:
1711  out << "<mrow>" << std::endl;
1712 
1713  out << "<mi>" << mData << "</mi>" << std::endl;
1714  out << "<mrow>" << std::endl;
1715  out << "<mo>(</mo>" << std::endl;
1716  out << "<mrow>" << std::endl;
1717 
1718  out << children[0];
1719 
1720  out << "<mo> , </mo>" << std::endl;
1721 
1722  out << children[1];
1723 
1724  out << "</mrow>" << std::endl;
1725  out << "<mo>) </mo>" << std::endl;
1726 
1727  out << "</mrow>" << std::endl;
1728  out << "</mrow>" << std::endl;
1729  break;
1730 
1731  case RPOISSON:
1732  out << "<mrow>" << std::endl;
1733 
1734  out << "<mi>" << mData << "</mi>" << std::endl;
1735  out << "<mrow>" << std::endl;
1736  out << "<mo>(</mo>" << std::endl;
1737  out << "<mrow>" << std::endl;
1738 
1739  out << children[0];
1740 
1741  out << "</mrow>" << std::endl;
1742  out << "<mo>) </mo>" << std::endl;
1743 
1744  out << "</mrow>" << std::endl;
1745  out << "</mrow>" << std::endl;
1746  break;
1747 
1748  default:
1749 
1750  out << "<mi> " << data << " </mi>" << std::endl;
1751 
1752  if (flag)
1753  out << "<mspace width=\"0.3em\"/>" << std::endl;
1754  else
1755  out << "<mfenced>" << std::endl;
1756 
1757  out << children[0];
1758 
1759  if (!flag) out << "</mfenced>" << std::endl;
1760 
1761  break;
1762  }
1763 
1764  out << "</mrow>" << std::endl;
1765 
1766  return out.str();
1767 }
static C_FLOAT64 factorial(C_FLOAT64 value)
virtual ASTNode * toAST(const CCopasiDataModel *pDataModel) const
CEvaluationNode * copyBranch() const
static C_FLOAT64 sech(C_FLOAT64 value)
static C_FLOAT64 min(const C_FLOAT64 &x1, const C_FLOAT64 &x2)
static C_FLOAT64 coth(C_FLOAT64 value)
CCopasiNode< Data > * getSibling()
Definition: CCopasiNode.h:353
std::string handleNot(const std::string &str) const
static C_FLOAT64 acsch(C_FLOAT64 value)
static C_FLOAT64 arccot(C_FLOAT64 value)
static C_FLOAT64 plus(C_FLOAT64 value)
virtual C_FLOAT64 getRandomNormal(const C_FLOAT64 &mean, const C_FLOAT64 &sd)
Definition: CRandom.cpp:292
CEvaluationNode * copyNode(CEvaluationNode *child1, CEvaluationNode *child2) const
virtual C_FLOAT64 getRandomOO()
Definition: CRandom.cpp:254
static C_FLOAT64 arcsec(C_FLOAT64 value)
static C_FLOAT64 rnormal(const C_FLOAT64 &mean, const C_FLOAT64 &sd)
#define fatalError()
const Type & getType() const
static CEvaluationNode * create(const Type &type, const Data &data)
virtual bool compile(const CEvaluationTree *pTree)
virtual std::string getBerkeleyMadonnaString(const std::vector< std::string > &children) const
static CEvaluationNode * fromAST(const ASTNode *pASTNode, const std::vector< CEvaluationNode * > &children)
C_FLOAT64(* mpFunction2)(const C_FLOAT64 &arg1, const C_FLOAT64 &arg2)
static C_FLOAT64 csch(C_FLOAT64 value)
virtual std::string getDisplayString(const std::vector< std::string > &children) const
static Type type(const Type &type)
static C_FLOAT64 copasiNot(C_FLOAT64 value)
virtual std::string getCCodeString(const std::vector< std::string > &children) const
#define PRECEDENCE_FUNCTION
static CRandom * createGenerator(CRandom::Type type=CRandom::mt19937, unsigned C_INT32 seed=0)
Definition: CRandom.cpp:49
virtual C_FLOAT64 getRandomPoisson(const C_FLOAT64 &mean)
Definition: CRandom.cpp:314
virtual std::string getXPPString(const std::vector< std::string > &children) const
static C_FLOAT64 asech(C_FLOAT64 value)
C_FLOAT64(* mpFunction)(C_FLOAT64 arg1)
static C_FLOAT64 sec(C_FLOAT64 value)
virtual CEvaluationNode * simplifyNode(const std::vector< CEvaluationNode * > &children) const
static C_FLOAT64 runiform(const C_FLOAT64 &lowerBound, const C_FLOAT64 &upperBound)
virtual bool addChild(CCopasiNode< Data > *pChild, CCopasiNode< Data > *pAfter=NULL)
Definition: CCopasiNode.h:156
static C_FLOAT64 csc(C_FLOAT64 value)
static C_FLOAT64 rgamma(const C_FLOAT64 &shape, const C_FLOAT64 &scale)
static C_FLOAT64 rpoisson(const C_FLOAT64 mu)
static C_FLOAT64 arccsc(C_FLOAT64 value)
long int flag
Definition: f2c.h:52
virtual ASTNode * toAST(const CCopasiDataModel *pDataModel) const
static Type subType(const Type &type)
static C_FLOAT64 max(const C_FLOAT64 &x1, const C_FLOAT64 &x2)
class CEvaluationNode::CPrecedence mPrecedence
#define C_FLOAT64
Definition: copasi.h:92
CCopasiNode< Data > * getParent()
Definition: CCopasiNode.h:139
static C_FLOAT64 cot(C_FLOAT64 value)
static C_FLOAT64 acoth(C_FLOAT64 value)
virtual C_FLOAT64 getRandomGamma(C_FLOAT64 shape, C_FLOAT64 scale)
Definition: CRandom.cpp:572
#define PRECEDENCE_NUMBER
virtual std::string getInfix(const std::vector< std::string > &children) const
virtual std::string getMMLString(const std::vector< std::string > &children, bool expand, const std::vector< std::vector< std::string > > &variables) const
static C_FLOAT64 minus(C_FLOAT64 value)
CCopasiNode< Data > * getChild()
Definition: CCopasiNode.h:210
#define min(a, b)
Definition: f2c.h:175
std::string handleSign(const std::string &str) const
#define max(a, b)
Definition: f2c.h:176