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) 2009-2019 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::Atan2::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
206 return ExpressionTreeNode(new Operation::Divide(),
207 ExpressionTreeNode(new Operation::Subtract(),
208 ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]),
209 ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1])),
210 ExpressionTreeNode(new Operation::Add(),
211 ExpressionTreeNode(new Operation::Square(), children[0]),
212 ExpressionTreeNode(new Operation::Square(), children[1])));
213 }
214
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const215 ExpressionTreeNode Operation::Sinh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
216 return ExpressionTreeNode(new Operation::Multiply(),
217 ExpressionTreeNode(new Operation::Cosh(),
218 children[0]),
219 childDerivs[0]);
220 }
221
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const222 ExpressionTreeNode Operation::Cosh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
223 return ExpressionTreeNode(new Operation::Multiply(),
224 ExpressionTreeNode(new Operation::Sinh(),
225 children[0]),
226 childDerivs[0]);
227 }
228
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const229 ExpressionTreeNode Operation::Tanh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
230 return ExpressionTreeNode(new Operation::Multiply(),
231 ExpressionTreeNode(new Operation::Subtract(),
232 ExpressionTreeNode(new Operation::Constant(1.0)),
233 ExpressionTreeNode(new Operation::Square(),
234 ExpressionTreeNode(new Operation::Tanh(), 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::Erf::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::Erfc::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
249 return ExpressionTreeNode(new Operation::Multiply(),
250 ExpressionTreeNode(new Operation::Multiply(),
251 ExpressionTreeNode(new Operation::Constant(-2.0/sqrt(M_PI))),
252 ExpressionTreeNode(new Operation::Exp(),
253 ExpressionTreeNode(new Operation::Negate(),
254 ExpressionTreeNode(new Operation::Square(), children[0])))),
255 childDerivs[0]);
256 }
257
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const258 ExpressionTreeNode Operation::Step::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
259 return ExpressionTreeNode(new Operation::Constant(0.0));
260 }
261
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const262 ExpressionTreeNode Operation::Delta::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
263 return ExpressionTreeNode(new Operation::Constant(0.0));
264 }
265
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const266 ExpressionTreeNode Operation::Square::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
267 return ExpressionTreeNode(new Operation::Multiply(),
268 ExpressionTreeNode(new Operation::MultiplyConstant(2.0),
269 children[0]),
270 childDerivs[0]);
271 }
272
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const273 ExpressionTreeNode Operation::Cube::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
274 return ExpressionTreeNode(new Operation::Multiply(),
275 ExpressionTreeNode(new Operation::MultiplyConstant(3.0),
276 ExpressionTreeNode(new Operation::Square(), children[0])),
277 childDerivs[0]);
278 }
279
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const280 ExpressionTreeNode Operation::Reciprocal::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
281 return ExpressionTreeNode(new Operation::Multiply(),
282 ExpressionTreeNode(new Operation::Negate(),
283 ExpressionTreeNode(new Operation::Reciprocal(),
284 ExpressionTreeNode(new Operation::Square(), children[0]))),
285 childDerivs[0]);
286 }
287
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const288 ExpressionTreeNode Operation::AddConstant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
289 return childDerivs[0];
290 }
291
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const292 ExpressionTreeNode Operation::MultiplyConstant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
293 return ExpressionTreeNode(new Operation::MultiplyConstant(value),
294 childDerivs[0]);
295 }
296
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const297 ExpressionTreeNode Operation::PowerConstant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
298 return ExpressionTreeNode(new Operation::Multiply(),
299 ExpressionTreeNode(new Operation::MultiplyConstant(value),
300 ExpressionTreeNode(new Operation::PowerConstant(value-1),
301 children[0])),
302 childDerivs[0]);
303 }
304
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const305 ExpressionTreeNode Operation::Min::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
306 ExpressionTreeNode step(new Operation::Step(),
307 ExpressionTreeNode(new Operation::Subtract(), children[0], children[1]));
308 return ExpressionTreeNode(new Operation::Subtract(),
309 ExpressionTreeNode(new Operation::Multiply(), childDerivs[1], step),
310 ExpressionTreeNode(new Operation::Multiply(), childDerivs[0],
311 ExpressionTreeNode(new Operation::AddConstant(-1), step)));
312 }
313
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const314 ExpressionTreeNode Operation::Max::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
315 ExpressionTreeNode step(new Operation::Step(),
316 ExpressionTreeNode(new Operation::Subtract(), children[0], children[1]));
317 return ExpressionTreeNode(new Operation::Subtract(),
318 ExpressionTreeNode(new Operation::Multiply(), childDerivs[0], step),
319 ExpressionTreeNode(new Operation::Multiply(), childDerivs[1],
320 ExpressionTreeNode(new Operation::AddConstant(-1), step)));
321 }
322
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const323 ExpressionTreeNode Operation::Abs::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
324 ExpressionTreeNode step(new Operation::Step(), children[0]);
325 return ExpressionTreeNode(new Operation::Multiply(),
326 childDerivs[0],
327 ExpressionTreeNode(new Operation::AddConstant(-1),
328 ExpressionTreeNode(new Operation::MultiplyConstant(2), step)));
329 }
330
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const331 ExpressionTreeNode Operation::Floor::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
332 return ExpressionTreeNode(new Operation::Constant(0.0));
333 }
334
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const335 ExpressionTreeNode Operation::Ceil::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
336 return ExpressionTreeNode(new Operation::Constant(0.0));
337 }
338
differentiate(const std::vector<ExpressionTreeNode> & children,const std::vector<ExpressionTreeNode> & childDerivs,const std::string & variable) const339 ExpressionTreeNode Operation::Select::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
340 vector<ExpressionTreeNode> derivChildren;
341 derivChildren.push_back(children[0]);
342 derivChildren.push_back(childDerivs[1]);
343 derivChildren.push_back(childDerivs[2]);
344 return ExpressionTreeNode(new Operation::Select(), derivChildren);
345 }
346