35 {
return se.derivative(*
this);}
37 {
return se.derivative(*
this);}
43 const regex singleDeriv(R
"(d(.*)/dt)"), 44 higherOrderDeriv(R"(d\^\{(\d*)\}(.*)/dt\^\{(\d*)\})"); 46 if (regex_match(x,m,singleDeriv))
51 else if(regex_match(x,m,higherOrderDeriv) && m[1]==m[3])
54 order=atoi(m[3].
str().c_str());
60 r<<
"d"<<varName<<
"/dt";
62 r<<
"d^{"<<order<<
"}"<<varName<<
"/dt^{"<<order<<
"}";
70 const NodePtr dx=x->derivative(*
this);
85 VariableDAGPtr r(dynamic_pointer_cast<VariableDAG>(makeDAG(tmp->valueId(),tmp->name(),tmp->type())));
88 if (processingDerivative.contains(expr.
name))
89 throw error(
"definition loop detected in processing derivative of %s",expr.
name.c_str());
90 processingDerivative.insert(expr.
name);
92 processingDerivative.erase(expr.
name);
96 auto ii=expressionCache.getIntegralInput(expr.
valueId);
98 throw error(
"integral input %s not defined",expr.
valueId.c_str());
102 derivInputs.emplace_back(r, expr.
valueId);
109 assert(expressionCache.reverseLookup(*r));
120 NodePtr SystemOfEquations::derivative
127 NodePtr SystemOfEquations::derivative<>
131 r->arguments.resize(expr.
arguments.size());
132 for (
size_t i=0; i<expr.
arguments.size(); ++i)
135 assert(expressionCache.reverseLookup(*n));
136 r->arguments[i].push_back(n->derivative(*
this));
137 assert(expressionCache.reverseLookup(*r->arguments[i].back()));
139 assert(expressionCache.reverseLookup(*r));
144 NodePtr SystemOfEquations::derivative
148 r->arguments.resize(expr.
arguments.size());
149 for (
size_t i=0; i<expr.
arguments.size(); ++i)
151 r->arguments[i].push_back(n->derivative(*
this));
152 assert(expressionCache.reverseLookup(*r));
157 NodePtr SystemOfEquations::derivative
161 vector<WeakNodePtr> args;
162 for (
size_t i=0; i<expr.
arguments.size(); ++i)
170 assert(!r->arguments.empty());
172 for (
size_t i=0; i<args.size(); ++i)
175 r->arguments[0].push_back(p);
176 assert(!p->arguments.empty());
177 for (
size_t j=0; j<args.size(); ++j)
179 p->arguments[0].push_back(args[j]);
180 p->arguments[0].push_back(args[i]->derivative(*
this));
181 assert(expressionCache.reverseLookup(*p->arguments[0].back()));
184 assert(expressionCache.reverseLookup(*r));
189 NodePtr SystemOfEquations::derivative
200 assert(!u1->arguments.empty() && !v1->arguments.empty());
206 assert(a && expressionCache.reverseLookup(*a));
212 const Expr u(expressionCache,u1), v(expressionCache,v1);
213 const Expr du(expressionCache, u->derivative(*
this)), dv(expressionCache, v->derivative(*
this));
216 assert(expressionCache.reverseLookup(*r));
227 const Expr x(expressionCache, expressionCache.reverseLookup(*expr.
arguments[0][0]));
229 return x->derivative(*
this)/x;
230 const Expr b(expressionCache, expressionCache.reverseLookup(*expr.
arguments[1][0]));
231 return (
log(x)/
log(b))->derivative(*
this);
236 NodePtr SystemOfEquations::derivative
246 const Expr dx(expressionCache, x->derivative(*
this));
251 return exp(y *
log(x))->derivative(*
this);
255 NodePtr SystemOfEquations::derivative
260 throw error(
"lt is not differentiable");
264 NodePtr SystemOfEquations::derivative
269 throw error(
"le is not differentiable");
273 NodePtr SystemOfEquations::derivative
278 throw error(
"eq is not differentiable");
282 NodePtr SystemOfEquations::derivative
289 NodePtr SystemOfEquations::derivative
296 NodePtr SystemOfEquations::derivative
305 NodePtr SystemOfEquations::derivative
309 auto tmp=make_shared<OperationDAG<OperationType::min>>(expr);
311 tmp->arguments[1].clear();
313 tmp->arguments[0].push_back(i);
315 switch (tmp->arguments[0].size())
320 return tmp->arguments[0][0]->derivative(*
this);
323 const Expr x(expressionCache,tmp->arguments[0].back());
324 tmp->arguments[0].pop_back();
326 return (x<=y)*x->derivative(*
this) +
327 (1-(x<=y))*y->derivative(*
this);
335 NodePtr SystemOfEquations::derivative
339 auto tmp=make_shared<OperationDAG<OperationType::max>>(expr);
341 tmp->arguments[1].clear();
343 tmp->arguments[0].push_back(i);
345 switch (tmp->arguments[0].size())
350 return tmp->arguments[0][0]->derivative(*
this);
353 const Expr x(expressionCache,tmp->arguments[0].back());
354 tmp->arguments[0].pop_back();
356 return (x<=y)*y->derivative(*
this) +
357 (1-(x<=y))*x->derivative(*
this);
363 NodePtr SystemOfEquations::derivative
370 NodePtr SystemOfEquations::derivative
377 NodePtr SystemOfEquations::derivative
384 NodePtr SystemOfEquations::derivative
391 NodePtr SystemOfEquations::derivative
398 NodePtr SystemOfEquations::derivative
405 NodePtr SystemOfEquations::derivative<>
411 return (100*x)->derivative(*
this);
415 NodePtr SystemOfEquations::derivative
419 return expr.
arguments[0][0]->derivative(*
this);
424 NodePtr SystemOfEquations::derivative
427 throw error(
"shouldn't be executed");
431 NodePtr SystemOfEquations::derivative
434 throw error(
"shouldn't be executed");
438 NodePtr SystemOfEquations::derivative
441 throw error(
"cannot differentiate an empirical curve");
445 NodePtr SystemOfEquations::derivative
448 throw error(
"cannot differentiate an empirical curve");
452 NodePtr SystemOfEquations::derivative
458 return chainRule(x, 0.5/
sqrt(x));
462 NodePtr SystemOfEquations::derivative
468 const Expr expx(expressionCache, expressionCache.reverseLookup(expr));
469 return chainRule(x,
exp(x));
473 NodePtr SystemOfEquations::derivative
479 return chainRule(x, 1/x);
483 NodePtr SystemOfEquations::derivative
489 return chainRule(x,
cos(x));
493 NodePtr SystemOfEquations::derivative<>
499 return chainRule(x,-1*
sin(x));
504 NodePtr SystemOfEquations::derivative<>
511 return chainRule(x,secx * secx);
515 NodePtr SystemOfEquations::derivative<>
521 return chainRule(x, 1/
sqrt(1-x*x));
525 NodePtr SystemOfEquations::derivative<>
531 return chainRule(x, -1/
sqrt(1-x*x));
535 NodePtr SystemOfEquations::derivative<>
541 return chainRule(x, 1/(1+x*x));
545 NodePtr SystemOfEquations::derivative<>
551 return chainRule(x,
cosh(x));
555 NodePtr SystemOfEquations::derivative<>
561 return chainRule(x,
sinh(x));
565 NodePtr SystemOfEquations::derivative<>
572 return chainRule(x, sech*sech);
576 NodePtr SystemOfEquations::derivative<>
582 return chainRule(x, (one-2*(x<=zero)));
586 NodePtr SystemOfEquations::derivative<>
592 throw error(
"floor is not differentiable");
596 NodePtr SystemOfEquations::derivative<>
601 throw error(
"frac is not differentiable");
605 NodePtr SystemOfEquations::derivative
615 NodePtr SystemOfEquations::derivative
621 const Expr x(expressionCache, expressionCache.reverseLookup(*expr.
arguments[0][0]));
628 NodePtr SystemOfEquations::derivative
638 NodePtr SystemOfEquations::derivative
640 {
throw error(
"Derivatives of user defined functions not implemented");}
642 #define VECTOR_DERIVATIVE_NOT_IMPLEMENTED(op) \ 644 NodePtr SystemOfEquations::derivative<> \ 645 (const OperationDAG<OperationType::op>& expr) \ 647 throw error("Vector derivatives not implemented"); \
virtual std::shared_ptr< Node > derivative(SystemOfEquations &) const =0
support for the derivative operator.
Expr polygamma(const Expr &x, const Expr &y)
Expr Gamma(const Expr &x)
string differentiateName(const string &x)
creates a new name to represent the derivative of a variable
Creation and access to the minskyTCL_obj object, which has code to record whenever Minsky's state cha...
std::string str(T x)
utility function to create a string representation of a numeric type
weak reference into subexpression cache
std::shared_ptr< Node > NodePtr
vector< vector< WeakNodePtr > > arguments
#define VECTOR_DERIVATIVE_NOT_IMPLEMENTED(op)
shared_ptr< VariableDAG > VariableDAGPtr