1 #include "expression.hpp"
2 
3 
binary_helper(std::shared_ptr<ExpressionBase> n1,std::shared_ptr<ExpressionBase> n2,std::shared_ptr<BinaryOperator> oper)4 std::shared_ptr<ExpressionBase> binary_helper(std::shared_ptr<ExpressionBase> n1, std::shared_ptr<ExpressionBase> n2, std::shared_ptr<BinaryOperator> oper)
5 {
6   std::shared_ptr<Expression> expr = std::make_shared<Expression>();
7   if (n1->is_leaf() && n2->is_leaf())
8     {
9       oper->operand1 = n1;
10       oper->operand2 = n2;
11     }
12   else if (n1->is_leaf())
13     {
14       oper->operand1 = n1;
15       std::shared_ptr<Expression> n2_expr = std::dynamic_pointer_cast<Expression>(n2);
16       oper->operand2 = n2_expr->operators->back();
17       if (n2_expr->operators->size() == n2_expr->n_operators)
18 	{
19 	  expr->operators = n2_expr->operators;
20 	}
21       else
22 	{
23 	  for (unsigned int i=0; i<n2_expr->n_operators; ++i)
24 	    {
25 	      expr->operators->push_back(n2_expr->operators->at(i));
26 	    }
27 	}
28     }
29   else if (n2->is_leaf())
30     {
31       std::shared_ptr<Expression> n1_expr = std::dynamic_pointer_cast<Expression>(n1);
32       oper->operand1 = n1_expr->operators->back();
33       oper->operand2 = n2;
34       if (n1_expr->operators->size() == n1_expr->n_operators)
35 	{
36 	  expr->operators = n1_expr->operators;
37 	}
38       else
39 	{
40 	  for (unsigned int i=0; i<n1_expr->n_operators; ++i)
41 	    {
42 	      expr->operators->push_back(n1_expr->operators->at(i));
43 	    }
44 	}
45     }
46   else
47     {
48       std::shared_ptr<Expression> n1_expr = std::dynamic_pointer_cast<Expression>(n1);
49       std::shared_ptr<Expression> n2_expr = std::dynamic_pointer_cast<Expression>(n2);
50       oper->operand1 = n1_expr->operators->back();
51       oper->operand2 = n2_expr->operators->back();
52       if (n1_expr->operators->size() == n1_expr->n_operators)
53 	{
54 	  expr->operators = n1_expr->operators;
55 	}
56       else
57 	{
58 	  for (unsigned int i=0; i<n1_expr->n_operators; ++i)
59 	    {
60 	      expr->operators->push_back(n1_expr->operators->at(i));
61 	    }
62 	}
63       for (unsigned int i=0; i<n2_expr->n_operators; ++i)
64 	{
65 	  expr->operators->push_back(n2_expr->operators->at(i));
66 	}
67     }
68   expr->operators->push_back(oper);
69   expr->n_operators = expr->operators->size();
70   return expr;
71 }
72 
73 
unary_helper(std::shared_ptr<ExpressionBase> n1,std::shared_ptr<UnaryOperator> oper)74 std::shared_ptr<ExpressionBase> unary_helper(std::shared_ptr<ExpressionBase> n1, std::shared_ptr<UnaryOperator> oper)
75 {
76   std::shared_ptr<Expression> expr = std::make_shared<Expression>();
77   if (n1->is_leaf())
78     {
79       oper->operand = n1;
80     }
81   else
82     {
83       std::shared_ptr<Expression> n1_expr = std::dynamic_pointer_cast<Expression>(n1);
84       oper->operand = n1_expr->operators->back();
85       if (n1_expr->operators->size() == n1_expr->n_operators)
86 	{
87 	  expr->operators = n1_expr->operators;
88 	}
89       else
90 	{
91 	  for (unsigned int i=0; i<n1_expr->n_operators; ++i)
92 	    {
93 	      expr->operators->push_back(n1_expr->operators->at(i));
94 	    }
95 	}
96     }
97   expr->operators->push_back(oper);
98   expr->n_operators = expr->operators->size();
99   return expr;
100 }
101 
102 
operator +(ExpressionBase & other)103 std::shared_ptr<ExpressionBase> ExpressionBase::operator+(ExpressionBase& other)
104 {
105   if (other.is_constant_type() && other.evaluate() == 0.0)
106     {
107       return shared_from_this();
108     }
109   else if (is_constant_type() && evaluate() == 0.0)
110     {
111       return other.shared_from_this();
112     }
113   else
114     {
115       std::shared_ptr<AddOperator> oper = std::make_shared<AddOperator>();
116       return binary_helper(shared_from_this(), other.shared_from_this(), oper);
117     }
118 }
119 
120 
operator -(ExpressionBase & other)121 std::shared_ptr<ExpressionBase> ExpressionBase::operator-(ExpressionBase& other)
122 {
123   if (other.is_constant_type() && other.evaluate() == 0.0)
124     {
125       return shared_from_this();
126     }
127   else if (is_constant_type() && evaluate() == 0.0)
128     {
129       return -other;
130     }
131   else
132     {
133       std::shared_ptr<SubtractOperator> oper = std::make_shared<SubtractOperator>();
134       return binary_helper(shared_from_this(), other.shared_from_this(), oper);
135     }
136 }
137 
138 
operator *(ExpressionBase & other)139 std::shared_ptr<ExpressionBase> ExpressionBase::operator*(ExpressionBase& other)
140 {
141   if (other.is_constant_type() && other.evaluate() == 1.0)
142     {
143       return shared_from_this();
144     }
145   else if (other.is_constant_type() && other.evaluate() == 0.0)
146     {
147       return other.shared_from_this();
148     }
149   else if (is_constant_type() && evaluate() == 1.0)
150     {
151       return other.shared_from_this();
152     }
153   else if (is_constant_type() && evaluate() == 0.0)
154     {
155       return shared_from_this();
156     }
157   else
158     {
159       std::shared_ptr<MultiplyOperator> oper = std::make_shared<MultiplyOperator>();
160       return binary_helper(shared_from_this(), other.shared_from_this(), oper);
161     }
162 }
163 
164 
operator /(ExpressionBase & other)165 std::shared_ptr<ExpressionBase> ExpressionBase::operator/(ExpressionBase& other)
166 {
167   if (other.is_constant_type() && other.evaluate() == 1.0)
168     {
169       return shared_from_this();
170     }
171   else if (other.is_constant_type() && other.evaluate() == 0.0)
172     {
173       assert (false);
174     }
175   else if (is_constant_type() && evaluate() == 0.0)
176     {
177       return shared_from_this();
178     }
179   std::shared_ptr<DivideOperator> oper = std::make_shared<DivideOperator>();
180   return binary_helper(shared_from_this(), other.shared_from_this(), oper);
181 }
182 
183 
__pow__(ExpressionBase & other)184 std::shared_ptr<ExpressionBase> ExpressionBase::__pow__(ExpressionBase& other)
185 {
186   if (other.is_constant_type() && other.evaluate() == 1.0)
187     {
188       return shared_from_this();
189     }
190   else if (other.is_constant_type() && other.evaluate() == 0.0)
191     {
192       return std::make_shared<Constant>(1.0);
193     }
194   else if (is_constant_type() && evaluate() == 1.0)
195     {
196       return shared_from_this();
197     }
198   else if (is_constant_type() && evaluate() == 0.0)
199     {
200       return shared_from_this();
201     }
202   else
203     {
204       std::shared_ptr<PowerOperator> oper = std::make_shared<PowerOperator>();
205       return binary_helper(shared_from_this(), other.shared_from_this(), oper);
206     }
207 }
208 
209 
operator -()210 std::shared_ptr<ExpressionBase> ExpressionBase::operator-()
211 {
212   if (is_constant_type())
213     {
214       return std::make_shared<Constant>(-evaluate());
215     }
216   else
217     {
218       std::shared_ptr<NegationOperator> oper = std::make_shared<NegationOperator>();
219       return unary_helper(shared_from_this(), oper);
220     }
221 }
222 
223 
appsi_exp(std::shared_ptr<ExpressionBase> n)224 std::shared_ptr<ExpressionBase> appsi_exp(std::shared_ptr<ExpressionBase> n)
225 {
226   if (n->is_constant_type())
227     {
228       return std::make_shared<Constant>(std::exp(n->evaluate()));
229     }
230   else
231     {
232       std::shared_ptr<ExpOperator> oper = std::make_shared<ExpOperator>();
233       return unary_helper(n->shared_from_this(), oper);
234     }
235 }
236 
237 
appsi_log(std::shared_ptr<ExpressionBase> n)238 std::shared_ptr<ExpressionBase> appsi_log(std::shared_ptr<ExpressionBase> n)
239 {
240   if (n->is_constant_type())
241     {
242       return std::make_shared<Constant>(std::log(n->evaluate()));
243     }
244   else
245     {
246       std::shared_ptr<LogOperator> oper = std::make_shared<LogOperator>();
247       return unary_helper(n->shared_from_this(), oper);
248     }
249 }
250 
251 
operator +(double other)252 std::shared_ptr<ExpressionBase> ExpressionBase::operator+(double other)
253 {
254   std::shared_ptr<Constant> other_const = std::make_shared<Constant>(other);
255   return (*this) + (*other_const);
256 }
257 
258 
operator *(double other)259 std::shared_ptr<ExpressionBase> ExpressionBase::operator*(double other)
260 {
261   std::shared_ptr<Constant> other_const = std::make_shared<Constant>(other);
262   return (*this) * (*other_const);
263 }
264 
265 
operator -(double other)266 std::shared_ptr<ExpressionBase> ExpressionBase::operator-(double other)
267 {
268   std::shared_ptr<Constant> other_const = std::make_shared<Constant>(other);
269   return (*this) - (*other_const);
270 }
271 
272 
operator /(double other)273 std::shared_ptr<ExpressionBase> ExpressionBase::operator/(double other)
274 {
275   std::shared_ptr<Constant> other_const = std::make_shared<Constant>(other);
276   return (*this) / (*other_const);
277 }
278 
279 
__pow__(double other)280 std::shared_ptr<ExpressionBase> ExpressionBase::__pow__(double other)
281 {
282   std::shared_ptr<Constant> other_const = std::make_shared<Constant>(other);
283   return this->__pow__(*other_const);
284 }
285 
286 
__radd__(double other)287 std::shared_ptr<ExpressionBase> ExpressionBase::__radd__(double other)
288 {
289   std::shared_ptr<Constant> other_const = std::make_shared<Constant>(other);
290   return (*other_const) + (*this);
291 }
292 
293 
__rmul__(double other)294 std::shared_ptr<ExpressionBase> ExpressionBase::__rmul__(double other)
295 {
296   std::shared_ptr<Constant> other_const = std::make_shared<Constant>(other);
297   return (*other_const) * (*this);
298 }
299 
300 
__rsub__(double other)301 std::shared_ptr<ExpressionBase> ExpressionBase::__rsub__(double other)
302 {
303   std::shared_ptr<Constant> other_const = std::make_shared<Constant>(other);
304   return (*other_const) - (*this);
305 }
306 
307 
__rdiv__(double other)308 std::shared_ptr<ExpressionBase> ExpressionBase::__rdiv__(double other)
309 {
310   std::shared_ptr<Constant> other_const = std::make_shared<Constant>(other);
311   return (*other_const) / (*this);
312 }
313 
314 
__rtruediv__(double other)315 std::shared_ptr<ExpressionBase> ExpressionBase::__rtruediv__(double other)
316 {
317   std::shared_ptr<Constant> other_const = std::make_shared<Constant>(other);
318   return (*other_const) / (*this);
319 }
320 
321 
__rpow__(double other)322 std::shared_ptr<ExpressionBase> ExpressionBase::__rpow__(double other)
323 {
324   std::shared_ptr<Constant> other_const = std::make_shared<Constant>(other);
325   return other_const->__pow__(*this);
326 }
327 
328 
is_leaf()329 bool Leaf::is_leaf()
330 {
331   return true;
332 }
333 
334 
is_variable_type()335 bool Var::is_variable_type()
336 {
337   return true;
338 }
339 
340 
is_param_type()341 bool Param::is_param_type()
342 {
343   return true;
344 }
345 
346 
is_constant_type()347 bool Constant::is_constant_type()
348 {
349   return true;
350 }
351 
352 
is_expression_type()353 bool Expression::is_expression_type()
354 {
355   return true;
356 }
357 
358 
evaluate()359 double Leaf::evaluate()
360 {
361   return value;
362 }
363 
364 
is_operator_type()365 bool Operator::is_operator_type()
366 {
367   return true;
368 }
369 
370 
get_value_from_array(double * val_array)371 double Leaf::get_value_from_array(double* val_array)
372 {
373   der = 0.0;
374   return value;
375 }
376 
377 
get_value_from_array(double * val_array)378 double Expression::get_value_from_array(double* val_array)
379 {
380   return val_array[n_operators-1];
381 }
382 
383 
get_value_from_array(double * val_array)384 double Operator::get_value_from_array(double* val_array)
385 {
386   return val_array[index];
387 }
388 
389 
evaluate(double * values)390 void MultiplyOperator::evaluate(double* values)
391 {
392   values[index] = operand1->get_value_from_array(values) * operand2->get_value_from_array(values);
393 }
394 
395 
evaluate(double * values)396 void AddOperator::evaluate(double* values)
397 {
398   values[index] = operand1->get_value_from_array(values) + operand2->get_value_from_array(values);
399 }
400 
401 
evaluate(double * values)402 void SubtractOperator::evaluate(double* values)
403 {
404   values[index] = operand1->get_value_from_array(values) - operand2->get_value_from_array(values);
405 }
406 
407 
evaluate(double * values)408 void DivideOperator::evaluate(double* values)
409 {
410   values[index] = operand1->get_value_from_array(values) / operand2->get_value_from_array(values);
411 }
412 
413 
evaluate(double * values)414 void PowerOperator::evaluate(double* values)
415 {
416   values[index] = std::pow(operand1->get_value_from_array(values), operand2->get_value_from_array(values));
417 }
418 
419 
evaluate(double * values)420 void NegationOperator::evaluate(double* values)
421 {
422   values[index] = -operand->get_value_from_array(values);
423 }
424 
425 
evaluate(double * values)426 void ExpOperator::evaluate(double* values)
427 {
428   values[index] = std::exp(operand->get_value_from_array(values));
429 }
430 
431 
evaluate(double * values)432 void LogOperator::evaluate(double* values)
433 {
434   values[index] = std::log(operand->get_value_from_array(values));
435 }
436 
437 
evaluate()438 double Expression::evaluate()
439 {
440   double* values = new double[n_operators];
441   for (unsigned int i=0; i<n_operators; ++i)
442     {
443       operators->at(i)->index = i;
444       operators->at(i)->evaluate(values);
445     }
446   double res = get_value_from_array(values);
447   delete[] values;
448   return res;
449 }
450 
451 
identify_variables(std::set<std::shared_ptr<Node>> & var_set)452 void UnaryOperator::identify_variables(std::set<std::shared_ptr<Node> > &var_set)
453 {
454   if (operand->is_variable_type())
455     {
456       var_set.insert(operand);
457     }
458 }
459 
460 
identify_variables(std::set<std::shared_ptr<Node>> & var_set)461 void BinaryOperator::identify_variables(std::set<std::shared_ptr<Node> > &var_set)
462 {
463   if (operand1->is_variable_type())
464     {
465       var_set.insert(operand1);
466     }
467   if (operand2->is_variable_type())
468     {
469       var_set.insert(operand2);
470     }
471 }
472 
473 
identify_variables()474 std::shared_ptr<std::vector<std::shared_ptr<Var> > > Expression::identify_variables()
475 {
476   std::set<std::shared_ptr<Node> > var_set;
477   for (unsigned int i=0; i<n_operators; ++i)
478     {
479       operators->at(i)->identify_variables(var_set);
480     }
481   std::shared_ptr<std::vector<std::shared_ptr<Var> > > res = std::make_shared<std::vector<std::shared_ptr<Var> > >();
482   for (std::shared_ptr<Node> v : var_set)
483     {
484       res->push_back(std::dynamic_pointer_cast<Var>(v));
485     }
486   return res;
487 }
488 
489 
identify_variables()490 std::shared_ptr<std::vector<std::shared_ptr<Var> > > Var::identify_variables()
491 {
492   std::shared_ptr<std::vector<std::shared_ptr<Var> > > res = std::make_shared<std::vector<std::shared_ptr<Var> > >();
493   res->push_back(shared_from_this());
494   return res;
495 }
496 
497 
identify_variables()498 std::shared_ptr<std::vector<std::shared_ptr<Var> > > Constant::identify_variables()
499 {
500   std::shared_ptr<std::vector<std::shared_ptr<Var> > > res = std::make_shared<std::vector<std::shared_ptr<Var> > >();
501   return res;
502 }
503 
504 
identify_variables()505 std::shared_ptr<std::vector<std::shared_ptr<Var> > > Param::identify_variables()
506 {
507   std::shared_ptr<std::vector<std::shared_ptr<Var> > > res = std::make_shared<std::vector<std::shared_ptr<Var> > >();
508   return res;
509 }
510 
511 
get_degree_from_array(int * degree_array)512 int Var::get_degree_from_array(int* degree_array)
513 {
514   return 1;
515 }
516 
517 
get_degree_from_array(int * degree_array)518 int Param::get_degree_from_array(int* degree_array)
519 {
520   return 0;
521 }
522 
523 
get_degree_from_array(int * degree_array)524 int Constant::get_degree_from_array(int* degree_array)
525 {
526   return 0;
527 }
528 
529 
get_degree_from_array(int * degree_array)530 int Expression::get_degree_from_array(int* degree_array)
531 {
532   return degree_array[n_operators-1];
533 }
534 
535 
get_degree_from_array(int * degree_array)536 int Operator::get_degree_from_array(int* degree_array)
537 {
538   return degree_array[index];
539 }
540 
541 
propagate_degree_forward(int * degrees,double * values)542 void MultiplyOperator::propagate_degree_forward(int* degrees, double* values)
543 {
544   degrees[index] = operand1->get_degree_from_array(degrees) + operand2->get_degree_from_array(degrees);
545 }
546 
547 
propagate_degree_forward(int * degrees,double * values)548 void AddOperator::propagate_degree_forward(int* degrees, double* values)
549 {
550   degrees[index] = std::max(operand1->get_degree_from_array(degrees), operand2->get_degree_from_array(degrees));
551 }
552 
553 
propagate_degree_forward(int * degrees,double * values)554 void SubtractOperator::propagate_degree_forward(int* degrees, double* values)
555 {
556   degrees[index] = std::max(operand1->get_degree_from_array(degrees), operand2->get_degree_from_array(degrees));
557 }
558 
559 
propagate_degree_forward(int * degrees,double * values)560 void DivideOperator::propagate_degree_forward(int* degrees, double* values)
561 {
562   // anything larger than 2 is nonlinear
563   degrees[index] = std::max(operand1->get_degree_from_array(degrees), 3*(operand2->get_degree_from_array(degrees)));
564 }
565 
566 
propagate_degree_forward(int * degrees,double * values)567 void PowerOperator::propagate_degree_forward(int* degrees, double* values)
568 {
569   if (operand2->get_degree_from_array(degrees) != 0)
570     {
571       degrees[index] = 3;
572     }
573   else
574     {
575       double val2 = operand2->get_value_from_array(values);
576       double intpart;
577       if (std::modf(val2, &intpart) == 0.0)
578 	{
579 	  degrees[index] = operand1->get_degree_from_array(degrees) * (int)val2;
580 	}
581       else
582 	{
583 	  degrees[index] = 3;
584 	}
585     }
586 }
587 
588 
propagate_degree_forward(int * degrees,double * values)589 void NegationOperator::propagate_degree_forward(int* degrees, double* values)
590 {
591   degrees[index] = operand->get_degree_from_array(degrees);
592 }
593 
594 
propagate_degree_forward(int * degrees,double * values)595 void ExpOperator::propagate_degree_forward(int* degrees, double* values)
596 {
597   if (operand->get_degree_from_array(degrees) == 0)
598     {
599       degrees[index] = 0;
600     }
601   else
602     {
603       degrees[index] = 3;
604     }
605 }
606 
607 
propagate_degree_forward(int * degrees,double * values)608 void LogOperator::propagate_degree_forward(int* degrees, double* values)
609 {
610   if (operand->get_degree_from_array(degrees) == 0)
611     {
612       degrees[index] = 0;
613     }
614   else
615     {
616       degrees[index] = 3;
617     }
618 }
619 
620 
__str__()621 std::string Var::__str__()
622 {
623   return name;
624 }
625 
626 
__str__()627 std::string Param::__str__()
628 {
629   return name;
630 }
631 
632 
__str__()633 std::string Constant::__str__()
634 {
635   return std::to_string(value);
636 }
637 
638 
__str__()639 std::string Expression::__str__()
640 {
641   std::string* string_array = new std::string[n_operators];
642   std::shared_ptr<Operator> oper;
643   for (unsigned int i=0; i<n_operators; ++i)
644     {
645       oper = operators->at(i);
646       oper->index = i;
647       oper->print(string_array);
648     }
649   std::string res = string_array[n_operators-1];
650   delete[] string_array;
651   return res;
652 }
653 
654 
get_string_from_array(std::string * string_array)655 std::string Leaf::get_string_from_array(std::string* string_array)
656 {
657   return __str__();
658 }
659 
660 
get_string_from_array(std::string * string_array)661 std::string Expression::get_string_from_array(std::string* string_array)
662 {
663   return string_array[n_operators-1];
664 }
665 
666 
get_string_from_array(std::string * string_array)667 std::string Operator::get_string_from_array(std::string* string_array)
668 {
669   return string_array[index];
670 }
671 
672 
print(std::string * string_array)673 void AddOperator::print(std::string* string_array)
674 {
675   string_array[index] = ("(" +
676 			 operand1->get_string_from_array(string_array) +
677 			 " + " +
678 			 operand2->get_string_from_array(string_array) +
679 			 ")");
680 }
681 
682 
print(std::string * string_array)683 void SubtractOperator::print(std::string* string_array)
684 {
685   string_array[index] = ("(" +
686 			 operand1->get_string_from_array(string_array) +
687 			 " - " +
688 			 operand2->get_string_from_array(string_array) +
689 			 ")");
690 }
691 
692 
print(std::string * string_array)693 void MultiplyOperator::print(std::string* string_array)
694 {
695   string_array[index] = ("(" +
696 			 operand1->get_string_from_array(string_array) +
697 			 "*" +
698 			 operand2->get_string_from_array(string_array) +
699 			 ")");
700 }
701 
702 
print(std::string * string_array)703 void DivideOperator::print(std::string* string_array)
704 {
705   string_array[index] = ("(" +
706 			 operand1->get_string_from_array(string_array) +
707 			 "/" +
708 			 operand2->get_string_from_array(string_array) +
709 			 ")");
710 }
711 
712 
print(std::string * string_array)713 void PowerOperator::print(std::string* string_array)
714 {
715   string_array[index] = ("(" +
716 			 operand1->get_string_from_array(string_array) +
717 			 "**" +
718 			 operand2->get_string_from_array(string_array) +
719 			 ")");
720 }
721 
722 
print(std::string * string_array)723 void NegationOperator::print(std::string* string_array)
724 {
725   string_array[index] = ("(-" +
726 			 operand->get_string_from_array(string_array) +
727 			 ")");
728 }
729 
730 
print(std::string * string_array)731 void ExpOperator::print(std::string* string_array)
732 {
733   string_array[index] = ("exp(" +
734 			 operand->get_string_from_array(string_array) +
735 			 ")");
736 }
737 
738 
print(std::string * string_array)739 void LogOperator::print(std::string* string_array)
740 {
741   string_array[index] = ("log(" +
742 			 operand->get_string_from_array(string_array) +
743 			 ")");
744 }
745 
746 
get_prefix_notation()747 std::shared_ptr<std::vector<std::shared_ptr<Node> > > Leaf::get_prefix_notation()
748 {
749   std::shared_ptr<std::vector<std::shared_ptr<Node> > > res = std::make_shared<std::vector<std::shared_ptr<Node> > >();
750   res->push_back(shared_from_this());
751   return res;
752 }
753 
754 
get_prefix_notation()755 std::shared_ptr<std::vector<std::shared_ptr<Node> > > Expression::get_prefix_notation()
756 {
757   std::shared_ptr<std::vector<std::shared_ptr<Node> > > res = std::make_shared<std::vector<std::shared_ptr<Node> > >();
758   std::shared_ptr<std::vector<std::shared_ptr<Node> > > stack = std::make_shared<std::vector<std::shared_ptr<Node> > >();
759   std::shared_ptr<Node> node;
760   stack->push_back(operators->at(n_operators - 1));
761   while (stack->size() > 0)
762     {
763       node = stack->back();
764       stack->pop_back();
765       res->push_back(node);
766       node->fill_prefix_notation_stack(stack);
767     }
768 
769   return res;
770 }
771 
772 
fill_prefix_notation_stack(std::shared_ptr<std::vector<std::shared_ptr<Node>>> stack)773 void BinaryOperator::fill_prefix_notation_stack(std::shared_ptr<std::vector<std::shared_ptr<Node> > > stack)
774 {
775   stack->push_back(operand2);
776   stack->push_back(operand1);
777 }
778 
779 
fill_prefix_notation_stack(std::shared_ptr<std::vector<std::shared_ptr<Node>>> stack)780 void UnaryOperator::fill_prefix_notation_stack(std::shared_ptr<std::vector<std::shared_ptr<Node> > > stack)
781 {
782   stack->push_back(operand);
783 }
784 
785 
write_nl_string(std::ofstream & f)786 void Var::write_nl_string(std::ofstream& f)
787 {
788   f << "v" << index << "\n";
789 }
790 
791 
write_nl_string(std::ofstream & f)792 void Param::write_nl_string(std::ofstream& f)
793 {
794   f << "n" << value << "\n";
795 }
796 
797 
write_nl_string(std::ofstream & f)798 void Constant::write_nl_string(std::ofstream& f)
799 {
800   f << "n" << value << "\n";
801 }
802 
803 
write_nl_string(std::ofstream & f)804 void Expression::write_nl_string(std::ofstream& f)
805 {
806   assert (false);
807 }
808 
809 
write_nl_string(std::ofstream & f)810 void MultiplyOperator::write_nl_string(std::ofstream& f)
811 {
812   f << "o2\n";
813 }
814 
815 
write_nl_string(std::ofstream & f)816 void AddOperator::write_nl_string(std::ofstream& f)
817 {
818   f << "o0\n";
819 }
820 
821 
write_nl_string(std::ofstream & f)822 void SubtractOperator::write_nl_string(std::ofstream& f)
823 {
824   f << "o1\n";
825 }
826 
827 
write_nl_string(std::ofstream & f)828 void DivideOperator::write_nl_string(std::ofstream& f)
829 {
830   f << "o3\n";
831 }
832 
833 
write_nl_string(std::ofstream & f)834 void PowerOperator::write_nl_string(std::ofstream& f)
835 {
836   f << "o5\n";
837 }
838 
839 
write_nl_string(std::ofstream & f)840 void NegationOperator::write_nl_string(std::ofstream& f)
841 {
842   f << "o16\n";
843 }
844 
845 
write_nl_string(std::ofstream & f)846 void ExpOperator::write_nl_string(std::ofstream& f)
847 {
848   f << "o44\n";
849 }
850 
851 
write_nl_string(std::ofstream & f)852 void LogOperator::write_nl_string(std::ofstream& f)
853 {
854   f << "o43\n";
855 }
856 
857 
create_vars(int n_vars)858 std::vector<std::shared_ptr<Var> > create_vars(int n_vars)
859 {
860   std::vector<std::shared_ptr<Var> > res;
861   for (int i=0; i<n_vars; ++i)
862     {
863       res.push_back(std::make_shared<Var>());
864     }
865   return res;
866 }
867 
868 
create_params(int n_params)869 std::vector<std::shared_ptr<Param> > create_params(int n_params)
870 {
871   std::vector<std::shared_ptr<Param> > res;
872   for (int i=0; i<n_params; ++i)
873     {
874       res.push_back(std::make_shared<Param>());
875     }
876   return res;
877 }
878 
879 
create_constants(int n_constants)880 std::vector<std::shared_ptr<Constant> > create_constants(int n_constants)
881 {
882   std::vector<std::shared_ptr<Constant> > res;
883   for (int i=0; i<n_constants; ++i)
884     {
885       res.push_back(std::make_shared<Constant>());
886     }
887   return res;
888 }
889 
890 
891 /*
892 int main()
893 {
894   std::shared_ptr<Param> a = std::make_shared<Param>();
895   a->value = 2.0;
896   std::shared_ptr<Var> x = std::make_shared<Var>();
897   x->value = 3.0;
898   std::shared_ptr<ExpressionBase> expr;
899   double val;
900   std::shared_ptr<Repn> repn;
901   clock_t t0 = clock();
902   expr = (*a)*(*x);
903   for (int i=0; i<999; ++i)
904     {
905       expr = *expr + *((*a)*(*x));
906     }
907   clock_t t1 = clock();
908   for (int i=0; i<1000; ++i)
909     {
910       val = expr->evaluate();
911     }
912   clock_t t2 = clock();
913   std::shared_ptr<Expression> expr2 = std::dynamic_pointer_cast<Expression>(expr);
914   for (int i=0; i<1000; ++i)
915     {
916       repn = expr2->generate_repn();
917     }
918   clock_t t3 = clock();
919   std::cout << ((float)(t1-t0))/CLOCKS_PER_SEC << std::endl;
920   std::cout << ((float)(t2-t1))/CLOCKS_PER_SEC << std::endl;
921   std::cout << ((float)(t3-t2))/CLOCKS_PER_SEC << std::endl;
922   return 0;
923   }
924 */
925