32 #ifndef OPM_LOCAL_AD_MATH_HPP
33 #define OPM_LOCAL_AD_MATH_HPP
42 template <
class ValueT,
int numVars,
unsigned staticSize>
46 template <
class ValueType,
int numVars,
unsigned staticSize>
47 Evaluation<ValueType, numVars, staticSize> abs(
const Evaluation<ValueType, numVars, staticSize>& x)
48 {
return (x > 0.0)?x:-x; }
50 template <
class ValueType,
int numVars,
unsigned staticSize>
51 Evaluation<ValueType, numVars, staticSize> min(
const Evaluation<ValueType, numVars, staticSize>& x1,
52 const Evaluation<ValueType, numVars, staticSize>& x2)
53 {
return (x1 < x2)?x1:x2; }
55 template <
class Arg1ValueType,
class ValueType,
int numVars,
unsigned staticSize>
56 Evaluation<ValueType, numVars, staticSize> min(
const Arg1ValueType& x1,
57 const Evaluation<ValueType, numVars, staticSize>& x2)
60 Evaluation<ValueType, numVars, staticSize> ret(x2);
68 template <
class ValueType,
int numVars,
unsigned staticSize,
class Arg2ValueType>
69 Evaluation<ValueType, numVars, staticSize> min(
const Evaluation<ValueType, numVars, staticSize>& x1,
70 const Arg2ValueType& x2)
71 {
return min(x2, x1); }
73 template <
class ValueType,
int numVars,
unsigned staticSize>
74 Evaluation<ValueType, numVars, staticSize> max(
const Evaluation<ValueType, numVars, staticSize>& x1,
75 const Evaluation<ValueType, numVars, staticSize>& x2)
76 {
return (x1 > x2)?x1:x2; }
78 template <
class Arg1ValueType,
class ValueType,
int numVars,
unsigned staticSize>
79 Evaluation<ValueType, numVars, staticSize> max(
const Arg1ValueType& x1,
80 const Evaluation<ValueType, numVars, staticSize>& x2)
83 Evaluation<ValueType, numVars, staticSize> ret(x2);
91 template <
class ValueType,
int numVars,
unsigned staticSize,
class Arg2ValueType>
92 Evaluation<ValueType, numVars, staticSize> max(
const Evaluation<ValueType, numVars, staticSize>& x1,
93 const Arg2ValueType& x2)
94 {
return max(x2, x1); }
96 template <
class ValueType,
int numVars,
unsigned staticSize>
97 Evaluation<ValueType, numVars, staticSize> tan(
const Evaluation<ValueType, numVars, staticSize>& x)
99 typedef MathToolbox<ValueType> ValueTypeToolbox;
101 Evaluation<ValueType, numVars, staticSize> result(x);
103 const ValueType& tmp = ValueTypeToolbox::tan(x.value());
104 result.setValue(tmp);
107 const ValueType& df_dx = 1 + tmp*tmp;
108 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
109 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
114 template <
class ValueType,
int numVars,
unsigned staticSize>
115 Evaluation<ValueType, numVars, staticSize> atan(
const Evaluation<ValueType, numVars, staticSize>& x)
117 typedef MathToolbox<ValueType> ValueTypeToolbox;
119 Evaluation<ValueType, numVars, staticSize> result(x);
121 result.setValue(ValueTypeToolbox::atan(x.value()));
124 const ValueType& df_dx = 1/(1 + x.value()*x.value());
125 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
126 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
131 template <
class ValueType,
int numVars,
unsigned staticSize>
132 Evaluation<ValueType, numVars, staticSize> atan2(
const Evaluation<ValueType, numVars, staticSize>& x,
133 const Evaluation<ValueType, numVars, staticSize>& y)
135 typedef MathToolbox<ValueType> ValueTypeToolbox;
137 Evaluation<ValueType, numVars, staticSize> result(x);
139 result.setValue(ValueTypeToolbox::atan2(x.value(), y.value()));
142 const ValueType& alpha = 1/(1 + (x.value()*x.value())/(y.value()*y.value()));
143 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
144 result.setDerivative(curVarIdx,
145 alpha/(y.value()*y.value())
146 *(x.derivative(curVarIdx)*y.value() - x.value()*y.derivative(curVarIdx)));
152 template <
class ValueType,
int numVars,
unsigned staticSize>
153 Evaluation<ValueType, numVars, staticSize> atan2(
const Evaluation<ValueType, numVars, staticSize>& x,
156 typedef MathToolbox<ValueType> ValueTypeToolbox;
158 Evaluation<ValueType, numVars, staticSize> result(x);
160 result.setValue(ValueTypeToolbox::atan2(x.value(), y));
163 const ValueType& alpha = 1/(1 + (x.value()*x.value())/(y*y));
164 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
165 result.setDerivative(curVarIdx,
167 *(x.derivative(curVarIdx)*y));
173 template <
class ValueType,
int numVars,
unsigned staticSize>
174 Evaluation<ValueType, numVars, staticSize> atan2(
const ValueType& x,
175 const Evaluation<ValueType, numVars, staticSize>& y)
177 typedef MathToolbox<ValueType> ValueTypeToolbox;
179 Evaluation<ValueType, numVars, staticSize> result(y);
181 result.setValue(ValueTypeToolbox::atan2(x, y.value()));
184 const ValueType& alpha = 1/(1 + (x.value()*x.value())/(y.value()*y.value()));
185 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
186 result.setDerivative(curVarIdx,
187 alpha/(y.value()*y.value())
188 *x*y.derivative(curVarIdx));
194 template <
class ValueType,
int numVars,
unsigned staticSize>
195 Evaluation<ValueType, numVars, staticSize> sin(
const Evaluation<ValueType, numVars, staticSize>& x)
197 typedef MathToolbox<ValueType> ValueTypeToolbox;
199 Evaluation<ValueType, numVars, staticSize> result(x);
201 result.setValue(ValueTypeToolbox::sin(x.value()));
204 const ValueType& df_dx = ValueTypeToolbox::cos(x.value());
205 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
206 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
211 template <
class ValueType,
int numVars,
unsigned staticSize>
212 Evaluation<ValueType, numVars, staticSize> asin(
const Evaluation<ValueType, numVars, staticSize>& x)
214 typedef MathToolbox<ValueType> ValueTypeToolbox;
216 Evaluation<ValueType, numVars, staticSize> result(x);
218 result.setValue(ValueTypeToolbox::asin(x.value()));
221 const ValueType& df_dx = 1.0/ValueTypeToolbox::sqrt(1 - x.value()*x.value());
222 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
223 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
228 template <
class ValueType,
int numVars,
unsigned staticSize>
229 Evaluation<ValueType, numVars, staticSize> cos(
const Evaluation<ValueType, numVars, staticSize>& x)
231 typedef MathToolbox<ValueType> ValueTypeToolbox;
233 Evaluation<ValueType, numVars, staticSize> result(x);
235 result.setValue(ValueTypeToolbox::cos(x.value()));
238 const ValueType& df_dx = -ValueTypeToolbox::sin(x.value());
239 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
240 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
245 template <
class ValueType,
int numVars,
unsigned staticSize>
246 Evaluation<ValueType, numVars, staticSize> acos(
const Evaluation<ValueType, numVars, staticSize>& x)
248 typedef MathToolbox<ValueType> ValueTypeToolbox;
250 Evaluation<ValueType, numVars, staticSize> result(x);
252 result.setValue(ValueTypeToolbox::acos(x.value()));
255 const ValueType& df_dx = - 1.0/ValueTypeToolbox::sqrt(1 - x.value()*x.value());
256 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
257 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
262 template <
class ValueType,
int numVars,
unsigned staticSize>
263 Evaluation<ValueType, numVars, staticSize> sqrt(
const Evaluation<ValueType, numVars, staticSize>& x)
265 typedef MathToolbox<ValueType> ValueTypeToolbox;
267 Evaluation<ValueType, numVars, staticSize> result(x);
269 const ValueType& sqrt_x = ValueTypeToolbox::sqrt(x.value());
270 result.setValue(sqrt_x);
273 ValueType df_dx = 0.5/sqrt_x;
274 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
275 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
281 template <
class ValueType,
int numVars,
unsigned staticSize>
282 Evaluation<ValueType, numVars, staticSize> exp(
const Evaluation<ValueType, numVars, staticSize>& x)
284 typedef MathToolbox<ValueType> ValueTypeToolbox;
285 Evaluation<ValueType, numVars, staticSize> result(x);
287 const ValueType& exp_x = ValueTypeToolbox::exp(x.value());
288 result.setValue(exp_x);
291 const ValueType& df_dx = exp_x;
292 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
293 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
299 template <
class ValueType,
int numVars,
unsigned staticSize,
class ExpType>
300 Evaluation<ValueType, numVars, staticSize> pow(
const Evaluation<ValueType, numVars, staticSize>& base,
303 typedef MathToolbox<ValueType> ValueTypeToolbox;
304 Evaluation<ValueType, numVars, staticSize> result(base);
306 const ValueType& pow_x = ValueTypeToolbox::pow(base.value(), exp);
307 result.setValue(pow_x);
316 const ValueType& df_dx = pow_x/base.value()*exp;
317 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
318 result.setDerivative(curVarIdx, df_dx*base.derivative(curVarIdx));
325 template <
class BaseType,
class ValueType,
int numVars,
unsigned staticSize>
326 Evaluation<ValueType, numVars, staticSize> pow(
const BaseType& base,
327 const Evaluation<ValueType, numVars, staticSize>& exp)
329 typedef MathToolbox<ValueType> ValueTypeToolbox;
331 Evaluation<ValueType, numVars, staticSize> result(exp);
339 const ValueType& lnBase = ValueTypeToolbox::log(base);
340 result.setValue(ValueTypeToolbox::exp(lnBase*exp.value()));
343 const ValueType& df_dx = lnBase*result.value();
344 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
345 result.setDerivative(curVarIdx, df_dx*exp.derivative(curVarIdx));
353 template <
class ValueType,
int numVars,
unsigned staticSize>
354 Evaluation<ValueType, numVars, staticSize> pow(
const Evaluation<ValueType, numVars, staticSize>& base,
355 const Evaluation<ValueType, numVars, staticSize>& exp)
357 typedef MathToolbox<ValueType> ValueTypeToolbox;
359 Evaluation<ValueType, numVars, staticSize> result(base);
367 ValueType valuePow = ValueTypeToolbox::pow(base.value(), exp.value());
368 result.setValue(valuePow);
372 const ValueType& f = base.value();
373 const ValueType& g = exp.value();
374 const ValueType& logF = ValueTypeToolbox::log(f);
375 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
376 const ValueType& fPrime = base.derivative(curVarIdx);
377 const ValueType& gPrime = exp.derivative(curVarIdx);
378 result.setDerivative(curVarIdx, (g*fPrime/f + logF*gPrime) * valuePow);
385 template <
class ValueType,
int numVars,
unsigned staticSize>
386 Evaluation<ValueType, numVars, staticSize> log(
const Evaluation<ValueType, numVars, staticSize>& x)
388 typedef MathToolbox<ValueType> ValueTypeToolbox;
390 Evaluation<ValueType, numVars, staticSize> result(x);
392 result.setValue(ValueTypeToolbox::log(x.value()));
395 const ValueType& df_dx = 1/x.value();
396 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
397 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
403 template <
class ValueType,
int numVars,
unsigned staticSize>
404 Evaluation<ValueType, numVars, staticSize> log10(
const Evaluation<ValueType, numVars, staticSize>& x)
406 typedef MathToolbox<ValueType> ValueTypeToolbox;
408 Evaluation<ValueType, numVars, staticSize> result(x);
410 result.setValue(ValueTypeToolbox::log10(x.value()));
413 const ValueType& df_dx = 1/x.value() * ValueTypeToolbox::log10(ValueTypeToolbox::exp(1.0));
414 for (
int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
415 result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
424 template <
class ValueT,
int numVars,
unsigned staticSize>
435 {
return eval.value(); }
441 {
return Evaluation::createBlank(x); }
444 {
return Evaluation::createConstantZero(x); }
447 {
return Evaluation::createConstantOne(x); }
450 {
return Evaluation::createConstant(
value); }
453 {
return Evaluation::createConstant(numDeriv,
value); }
456 {
return Evaluation::createConstant(x,
value); }
459 {
return Evaluation::createVariable(
value, varIdx); }
461 template <
class LhsEval>
462 static typename std::enable_if<std::is_same<Evaluation, LhsEval>::value,
467 template <
class LhsEval>
468 static typename std::enable_if<std::is_same<Evaluation, LhsEval>::value,
473 template <
class LhsEval>
474 static typename std::enable_if<std::is_floating_point<LhsEval>::value,
477 {
return eval.value(); }
485 if (!ValueTypeToolbox::isSame(a.value(), b.value(), tolerance))
489 for (
int curVarIdx = 0; curVarIdx < numVars; ++curVarIdx)
490 if (!ValueTypeToolbox::isSame(a.derivative(curVarIdx), b.derivative(curVarIdx), tolerance))
497 template <
class Arg1Eval,
class Arg2Eval>
498 static Evaluation max(
const Arg1Eval& arg1,
const Arg2Eval& arg2)
499 {
return DenseAd::max(arg1, arg2); }
501 template <
class Arg1Eval,
class Arg2Eval>
502 static Evaluation min(
const Arg1Eval& arg1,
const Arg2Eval& arg2)
503 {
return DenseAd::min(arg1, arg2); }
506 {
return DenseAd::abs(arg); }
509 {
return DenseAd::tan(arg); }
512 {
return DenseAd::atan(arg); }
515 {
return DenseAd::atan2(arg1, arg2); }
517 template <
class Eval2>
519 {
return DenseAd::atan2(arg1, arg2); }
521 template <
class Eval1>
523 {
return DenseAd::atan2(arg1, arg2); }
526 {
return DenseAd::sin(arg); }
529 {
return DenseAd::asin(arg); }
532 {
return DenseAd::cos(arg); }
535 {
return DenseAd::acos(arg); }
538 {
return DenseAd::sqrt(arg); }
541 {
return DenseAd::exp(arg); }
544 {
return DenseAd::log(arg); }
547 {
return DenseAd::log10(arg); }
549 template <
class RhsValueType>
551 {
return DenseAd::pow(arg1, arg2); }
553 template <
class RhsValueType>
555 {
return DenseAd::pow(arg1, arg2); }
558 {
return DenseAd::pow(arg1, arg2); }
565 for (
int i = 0; i < numVars; ++i)
577 for (
int i = 0; i < numVars; ++i)
Representation of an evaluation of a function and its derivatives w.r.t.
Represents a function evaluation and its derivatives w.r.t.
Definition: Evaluation.hpp:59