1 
2 /* -------------------------------------------------------------------------- *
3  *                                   Lepton                                   *
4  * -------------------------------------------------------------------------- *
5  * This is part of the Lepton expression parser originating from              *
6  * Simbios, the NIH National Center for Physics-Based Simulation of           *
7  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
8  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
9  *                                                                            *
10  * Portions Copyright (c) 2005-2017 Stanford University and the Authors.      *
11  * Authors: Peter Eastman                                                     *
12  * Contributors:                                                              *
13  *                                                                            *
14  * Permission is hereby granted, free of charge, to any person obtaining a    *
15  * copy of this software and associated documentation files (the "Software"), *
16  * to deal in the Software without restriction, including without limitation  *
17  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
18  * and/or sell copies of the Software, and to permit persons to whom the      *
19  * Software is furnished to do so, subject to the following conditions:       *
20  *                                                                            *
21  * The above copyright notice and this permission notice shall be included in *
22  * all copies or substantial portions of the Software.                        *
23  *                                                                            *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
25  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
26  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
27  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
28  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
29  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
30  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
31  * -------------------------------------------------------------------------- */
32 
33 #include "lepton/Operation.h"
34 #include "lepton/ExpressionTreeNode.h"
35 #include "MSVC_erfc.h"
36 
37 using namespace Lepton;
38 using namespace std;
39 
evaluate(double * args,const map<string,double> & variables) const40 double Operation::Erf::evaluate(double* args, const map<string, double>& variables) const {
41     return erf(args[0]);
42 }
43 
evaluate(double * args,const map<string,double> & variables) const44 double Operation::Erfc::evaluate(double* args, const map<string, double>& variables) const {
45     return erfc(args[0]);
46 }
47 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const48 ExpressionTreeNode Operation::Constant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
49     return ExpressionTreeNode(new Operation::Constant(0.0));
50 }
51 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const52 ExpressionTreeNode Operation::Variable::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
53     if (variable == name)
54         return ExpressionTreeNode(new Operation::Constant(1.0));
55     return ExpressionTreeNode(new Operation::Constant(0.0));
56 }
57 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const58 ExpressionTreeNode Operation::Custom::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
59     if (function->getNumArguments() == 0)
60         return ExpressionTreeNode(new Operation::Constant(0.0));
61     ExpressionTreeNode result = ExpressionTreeNode(new Operation::Multiply(), ExpressionTreeNode(new Operation::Custom(*this, 0), children), childDerivs[0]);
62     for (int i = 1; i < getNumArguments(); i++) {
63         result = ExpressionTreeNode(new Operation::Add(),
64                                     result,
65                                     ExpressionTreeNode(new Operation::Multiply(), ExpressionTreeNode(new Operation::Custom(*this, i), children), childDerivs[i]));
66     }
67     return result;
68 }
69 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const70 ExpressionTreeNode Operation::Add::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
71     return ExpressionTreeNode(new Operation::Add(), childDerivs[0], childDerivs[1]);
72 }
73 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const74 ExpressionTreeNode Operation::Subtract::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
75     return ExpressionTreeNode(new Operation::Subtract(), childDerivs[0], childDerivs[1]);
76 }
77 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const78 ExpressionTreeNode Operation::Multiply::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
79     return ExpressionTreeNode(new Operation::Add(),
80                               ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1]),
81                               ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]));
82 }
83 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const84 ExpressionTreeNode Operation::Divide::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
85     return ExpressionTreeNode(new Operation::Divide(),
86                               ExpressionTreeNode(new Operation::Subtract(),
87                                                  ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]),
88                                                  ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1])),
89                               ExpressionTreeNode(new Operation::Square(), children[1]));
90 }
91 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const92 ExpressionTreeNode Operation::Power::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
93     return ExpressionTreeNode(new Operation::Add(),
94                               ExpressionTreeNode(new Operation::Multiply(),
95                                                  ExpressionTreeNode(new Operation::Multiply(),
96                                                                     children[1],
97                                                                     ExpressionTreeNode(new Operation::Power(),
98                                                                                        children[0], ExpressionTreeNode(new Operation::AddConstant(-1.0), children[1]))),
99                                                  childDerivs[0]),
100                               ExpressionTreeNode(new Operation::Multiply(),
101                                                  ExpressionTreeNode(new Operation::Multiply(),
102                                                                     ExpressionTreeNode(new Operation::Log(), children[0]),
103                                                                     ExpressionTreeNode(new Operation::Power(), children[0], children[1])),
104                                                  childDerivs[1]));
105 }
106 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const107 ExpressionTreeNode Operation::Negate::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
108     return ExpressionTreeNode(new Operation::Negate(), childDerivs[0]);
109 }
110 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const111 ExpressionTreeNode Operation::Sqrt::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
112     return ExpressionTreeNode(new Operation::Multiply(),
113                               ExpressionTreeNode(new Operation::MultiplyConstant(0.5),
114                                                  ExpressionTreeNode(new Operation::Reciprocal(),
115                                                                     ExpressionTreeNode(new Operation::Sqrt(), children[0]))),
116                               childDerivs[0]);
117 }
118 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const119 ExpressionTreeNode Operation::Exp::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
120     return ExpressionTreeNode(new Operation::Multiply(),
121                               ExpressionTreeNode(new Operation::Exp(), children[0]),
122                               childDerivs[0]);
123 }
124 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const125 ExpressionTreeNode Operation::Log::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
126     return ExpressionTreeNode(new Operation::Multiply(),
127                               ExpressionTreeNode(new Operation::Reciprocal(), children[0]),
128                               childDerivs[0]);
129 }
130 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const131 ExpressionTreeNode Operation::Sin::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
132     return ExpressionTreeNode(new Operation::Multiply(),
133                               ExpressionTreeNode(new Operation::Cos(), children[0]),
134                               childDerivs[0]);
135 }
136 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const137 ExpressionTreeNode Operation::Cos::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
138     return ExpressionTreeNode(new Operation::Multiply(),
139                               ExpressionTreeNode(new Operation::Negate(),
140                                                  ExpressionTreeNode(new Operation::Sin(), children[0])),
141                               childDerivs[0]);
142 }
143 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const144 ExpressionTreeNode Operation::Sec::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
145     return ExpressionTreeNode(new Operation::Multiply(),
146                               ExpressionTreeNode(new Operation::Multiply(),
147                                                  ExpressionTreeNode(new Operation::Sec(), children[0]),
148                                                  ExpressionTreeNode(new Operation::Tan(), children[0])),
149                               childDerivs[0]);
150 }
151 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const152 ExpressionTreeNode Operation::Csc::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
153     return ExpressionTreeNode(new Operation::Multiply(),
154                               ExpressionTreeNode(new Operation::Negate(),
155                                                  ExpressionTreeNode(new Operation::Multiply(),
156                                                                     ExpressionTreeNode(new Operation::Csc(), children[0]),
157                                                                     ExpressionTreeNode(new Operation::Cot(), children[0]))),
158                               childDerivs[0]);
159 }
160 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const161 ExpressionTreeNode Operation::Tan::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
162     return ExpressionTreeNode(new Operation::Multiply(),
163                               ExpressionTreeNode(new Operation::Square(),
164                                                  ExpressionTreeNode(new Operation::Sec(), children[0])),
165                               childDerivs[0]);
166 }
167 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const168 ExpressionTreeNode Operation::Cot::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
169     return ExpressionTreeNode(new Operation::Multiply(),
170                               ExpressionTreeNode(new Operation::Negate(),
171                                                  ExpressionTreeNode(new Operation::Square(),
172                                                                     ExpressionTreeNode(new Operation::Csc(), children[0]))),
173                               childDerivs[0]);
174 }
175 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const176 ExpressionTreeNode Operation::Asin::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
177     return ExpressionTreeNode(new Operation::Multiply(),
178                               ExpressionTreeNode(new Operation::Reciprocal(),
179                                                  ExpressionTreeNode(new Operation::Sqrt(),
180                                                                     ExpressionTreeNode(new Operation::Subtract(),
181                                                                                        ExpressionTreeNode(new Operation::Constant(1.0)),
182                                                                                        ExpressionTreeNode(new Operation::Square(), children[0])))),
183                               childDerivs[0]);
184 }
185 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const186 ExpressionTreeNode Operation::Acos::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
187     return ExpressionTreeNode(new Operation::Multiply(),
188                               ExpressionTreeNode(new Operation::Negate(),
189                                                  ExpressionTreeNode(new Operation::Reciprocal(),
190                                                                     ExpressionTreeNode(new Operation::Sqrt(),
191                                                                                        ExpressionTreeNode(new Operation::Subtract(),
192                                                                                                           ExpressionTreeNode(new Operation::Constant(1.0)),
193                                                                                                           ExpressionTreeNode(new Operation::Square(), children[0]))))),
194                               childDerivs[0]);
195 }
196 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const197 ExpressionTreeNode Operation::Atan::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
198     return ExpressionTreeNode(new Operation::Multiply(),
199                               ExpressionTreeNode(new Operation::Reciprocal(),
200                                                  ExpressionTreeNode(new Operation::AddConstant(1.0),
201                                                                     ExpressionTreeNode(new Operation::Square(), children[0]))),
202                               childDerivs[0]);
203 }
204 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const205 ExpressionTreeNode Operation::Sinh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
206     return ExpressionTreeNode(new Operation::Multiply(),
207                               ExpressionTreeNode(new Operation::Cosh(),
208                                                  children[0]),
209                               childDerivs[0]);
210 }
211 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const212 ExpressionTreeNode Operation::Cosh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
213     return ExpressionTreeNode(new Operation::Multiply(),
214                               ExpressionTreeNode(new Operation::Sinh(),
215                                                  children[0]),
216                               childDerivs[0]);
217 }
218 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const219 ExpressionTreeNode Operation::Tanh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
220     return ExpressionTreeNode(new Operation::Multiply(),
221                               ExpressionTreeNode(new Operation::Subtract(),
222                                                  ExpressionTreeNode(new Operation::Constant(1.0)),
223                                                  ExpressionTreeNode(new Operation::Square(),
224                                                                     ExpressionTreeNode(new Operation::Tanh(), children[0]))),
225                               childDerivs[0]);
226 }
227 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const228 ExpressionTreeNode Operation::Erf::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
229     return ExpressionTreeNode(new Operation::Multiply(),
230                               ExpressionTreeNode(new Operation::Multiply(),
231                                                  ExpressionTreeNode(new Operation::Constant(2.0/sqrt(M_PI))),
232                                                  ExpressionTreeNode(new Operation::Exp(),
233                                                                     ExpressionTreeNode(new Operation::Negate(),
234                                                                                        ExpressionTreeNode(new Operation::Square(), children[0])))),
235                               childDerivs[0]);
236 }
237 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const238 ExpressionTreeNode Operation::Erfc::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
239     return ExpressionTreeNode(new Operation::Multiply(),
240                               ExpressionTreeNode(new Operation::Multiply(),
241                                                  ExpressionTreeNode(new Operation::Constant(-2.0/sqrt(M_PI))),
242                                                  ExpressionTreeNode(new Operation::Exp(),
243                                                                     ExpressionTreeNode(new Operation::Negate(),
244                                                                                        ExpressionTreeNode(new Operation::Square(), children[0])))),
245                               childDerivs[0]);
246 }
247 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const248 ExpressionTreeNode Operation::Step::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
249     return ExpressionTreeNode(new Operation::Constant(0.0));
250 }
251 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const252 ExpressionTreeNode Operation::Delta::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
253     return ExpressionTreeNode(new Operation::Constant(0.0));
254 }
255 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const256 ExpressionTreeNode Operation::Square::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
257     return ExpressionTreeNode(new Operation::Multiply(),
258                               ExpressionTreeNode(new Operation::MultiplyConstant(2.0),
259                                                  children[0]),
260                               childDerivs[0]);
261 }
262 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const263 ExpressionTreeNode Operation::Cube::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
264     return ExpressionTreeNode(new Operation::Multiply(),
265                               ExpressionTreeNode(new Operation::MultiplyConstant(3.0),
266                                                  ExpressionTreeNode(new Operation::Square(), children[0])),
267                               childDerivs[0]);
268 }
269 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const270 ExpressionTreeNode Operation::Reciprocal::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
271     return ExpressionTreeNode(new Operation::Multiply(),
272                               ExpressionTreeNode(new Operation::Negate(),
273                                                  ExpressionTreeNode(new Operation::Reciprocal(),
274                                                                     ExpressionTreeNode(new Operation::Square(), children[0]))),
275                               childDerivs[0]);
276 }
277 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const278 ExpressionTreeNode Operation::AddConstant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
279     return childDerivs[0];
280 }
281 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const282 ExpressionTreeNode Operation::MultiplyConstant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
283     return ExpressionTreeNode(new Operation::MultiplyConstant(value),
284                               childDerivs[0]);
285 }
286 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const287 ExpressionTreeNode Operation::PowerConstant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
288     return ExpressionTreeNode(new Operation::Multiply(),
289                               ExpressionTreeNode(new Operation::MultiplyConstant(value),
290                                                  ExpressionTreeNode(new Operation::PowerConstant(value-1),
291                                                                     children[0])),
292                               childDerivs[0]);
293 }
294 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const295 ExpressionTreeNode Operation::Min::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
296     ExpressionTreeNode step(new Operation::Step(),
297                             ExpressionTreeNode(new Operation::Subtract(), children[0], children[1]));
298     return ExpressionTreeNode(new Operation::Subtract(),
299                               ExpressionTreeNode(new Operation::Multiply(), childDerivs[1], step),
300                               ExpressionTreeNode(new Operation::Multiply(), childDerivs[0],
301                                                  ExpressionTreeNode(new Operation::AddConstant(-1), step)));
302 }
303 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const304 ExpressionTreeNode Operation::Max::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
305     ExpressionTreeNode step(new Operation::Step(),
306                             ExpressionTreeNode(new Operation::Subtract(), children[0], children[1]));
307     return ExpressionTreeNode(new Operation::Subtract(),
308                               ExpressionTreeNode(new Operation::Multiply(), childDerivs[0], step),
309                               ExpressionTreeNode(new Operation::Multiply(), childDerivs[1],
310                                                  ExpressionTreeNode(new Operation::AddConstant(-1), step)));
311 }
312 
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const313 ExpressionTreeNode Operation::Abs::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
314     ExpressionTreeNode step(new Operation::Step(), children[0]);
315     return ExpressionTreeNode(new Operation::Multiply(),
316                               childDerivs[0],
317                               ExpressionTreeNode(new Operation::AddConstant(-1),
318                                                  ExpressionTreeNode(new Operation::MultiplyConstant(2), step)));
319 }
320