bpp-core3  3.0.0
BinaryOperator.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #ifndef BPP_NUMERIC_FUNCTION_OPERATORS_BINARYOPERATOR_H
6 #define BPP_NUMERIC_FUNCTION_OPERATORS_BINARYOPERATOR_H
7 
8 #include <memory>
9 
10 #include "Operator.h"
11 
12 namespace bpp
13 {
20  public Operator
21 {
22 private:
23  char symb_;
24 
25  std::shared_ptr<Operator> left_, right_;
26 
27 public:
28  BinaryOperator(char symb, std::shared_ptr<Operator> left, std::shared_ptr<Operator> right) :
29  symb_(symb), left_(left), right_(right)
30  {}
31 
33  {
34  return new BinaryOperator(*this);
35  }
36 
37  std::shared_ptr<Operator> getLeftSon()
38  {
39  return left_;
40  }
41 
42  std::shared_ptr<Operator> getRightSon()
43  {
44  return right_;
45  }
46 
47  char getSymbol() const
48  {
49  return symb_;
50  }
51 
52  double getValue() const
53  {
54  switch (symb_)
55  {
56  case '+':
57  return left_->getValue() + right_->getValue();
58  case '-':
59  return left_->getValue() - right_->getValue();
60  case '/':
61  if (right_->getValue() == 0)
62  return 0;
63 
64  return left_->getValue() / right_->getValue();
65  case '*':
66  return left_->getValue() * right_->getValue();
67  default:
68  return 0;
69  }
70  }
71 
72  double getFirstOrderDerivative(const std::string& variable) const
73  {
74  double dl = left_->getFirstOrderDerivative(variable);
75  double dr = right_->getFirstOrderDerivative(variable);
76  double l = left_->getValue();
77  double r = right_->getValue();
78 
79  switch (symb_)
80  {
81  case '+':
82  return dl + dr;
83  case '-':
84  return dl - dl;
85  case '/':
86  if (r == 0)
87  return 0;
88 
89  return (dl * r - dr * l ) / (r * r);
90  case '*':
91  return dl * r + dr * l;
92  default:
93  return 0;
94  }
95  return 0;
96  }
97 
98  double getSecondOrderDerivative(const std::string& variable) const
99  {
100  double d2l = left_->getSecondOrderDerivative(variable);
101  double d2r = right_->getSecondOrderDerivative(variable);
102  double l = left_->getValue();
103  double r = right_->getValue();
104  double dl = left_->getFirstOrderDerivative(variable);
105  double dr = right_->getFirstOrderDerivative(variable);
106 
107  double r2 = r * r;
108  double r3 = r * r2;
109 
110  switch (symb_)
111  {
112  case '+':
113  return d2l + d2r;
114  case '-':
115  return d2l - d2r;
116 
117  case '/':
118  if (r == 0)
119  return 0;
120 
121  return (d2l * r - d2r * l ) / r2 - ( 2 * dl * ( dl * r - dr * l) ) / r3;
122 
123  case '*':
124  return d2l * r + d2r * l + 2 * dr * dl;
125  default:
126  return 0;
127  }
128  }
129 
130  std::string output() const
131  {
132  return "(" + left_->output() + " " + symb_ + " " + right_->output() + ")";
133  }
134 };
135 } // end of namespace bpp.
136 #endif // BPP_NUMERIC_FUNCTION_OPERATORS_BINARYOPERATOR_H
Binary arithmetic operator for numerical computation.
std::shared_ptr< Operator > getRightSon()
std::shared_ptr< Operator > right_
BinaryOperator * clone() const
Create a copy of this object and send a pointer to it.
double getValue() const
std::shared_ptr< Operator > getLeftSon()
std::string output() const
BinaryOperator(char symb, std::shared_ptr< Operator > left, std::shared_ptr< Operator > right)
double getSecondOrderDerivative(const std::string &variable) const
std::shared_ptr< Operator > left_
char getSymbol() const
double getFirstOrderDerivative(const std::string &variable) const
Interface of operator for numerical computation.
Definition: Operator.h:19