My Project
Math.hpp
Go to the documentation of this file.
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 /*
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 2 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 
19  Consult the COPYING file in the top-level source directory of this
20  module for the precise wording of the license and the list of
21  copyright holders.
22 */
32 #ifndef OPM_LOCAL_AD_MATH_HPP
33 #define OPM_LOCAL_AD_MATH_HPP
34 
35 #include "Evaluation.hpp"
36 
38 
39 namespace Opm {
40 namespace DenseAd {
41 // forward declaration of the Evaluation template class
42 template <class ValueT, int numVars, unsigned staticSize>
43 class Evaluation;
44 
45 // provide some algebraic functions
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; }
49 
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; }
54 
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)
58 {
59  if (x1 < x2) {
60  Evaluation<ValueType, numVars, staticSize> ret(x2);
61  ret = x1;
62  return ret;
63  }
64  else
65  return x2;
66 }
67 
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); }
72 
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; }
77 
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)
81 {
82  if (x1 > x2) {
83  Evaluation<ValueType, numVars, staticSize> ret(x2);
84  ret = x1;
85  return ret;
86  }
87  else
88  return x2;
89 }
90 
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); }
95 
96 template <class ValueType, int numVars, unsigned staticSize>
97 Evaluation<ValueType, numVars, staticSize> tan(const Evaluation<ValueType, numVars, staticSize>& x)
98 {
99  typedef MathToolbox<ValueType> ValueTypeToolbox;
100 
101  Evaluation<ValueType, numVars, staticSize> result(x);
102 
103  const ValueType& tmp = ValueTypeToolbox::tan(x.value());
104  result.setValue(tmp);
105 
106  // derivatives use the chain rule
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));
110 
111  return result;
112 }
113 
114 template <class ValueType, int numVars, unsigned staticSize>
115 Evaluation<ValueType, numVars, staticSize> atan(const Evaluation<ValueType, numVars, staticSize>& x)
116 {
117  typedef MathToolbox<ValueType> ValueTypeToolbox;
118 
119  Evaluation<ValueType, numVars, staticSize> result(x);
120 
121  result.setValue(ValueTypeToolbox::atan(x.value()));
122 
123  // derivatives use the chain rule
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));
127 
128  return result;
129 }
130 
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)
134 {
135  typedef MathToolbox<ValueType> ValueTypeToolbox;
136 
137  Evaluation<ValueType, numVars, staticSize> result(x);
138 
139  result.setValue(ValueTypeToolbox::atan2(x.value(), y.value()));
140 
141  // derivatives use the chain rule
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)));
147  }
148 
149  return result;
150 }
151 
152 template <class ValueType, int numVars, unsigned staticSize>
153 Evaluation<ValueType, numVars, staticSize> atan2(const Evaluation<ValueType, numVars, staticSize>& x,
154  const ValueType& y)
155 {
156  typedef MathToolbox<ValueType> ValueTypeToolbox;
157 
158  Evaluation<ValueType, numVars, staticSize> result(x);
159 
160  result.setValue(ValueTypeToolbox::atan2(x.value(), y));
161 
162  // derivatives use the chain rule
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,
166  alpha/(y*y)
167  *(x.derivative(curVarIdx)*y));
168  }
169 
170  return result;
171 }
172 
173 template <class ValueType, int numVars, unsigned staticSize>
174 Evaluation<ValueType, numVars, staticSize> atan2(const ValueType& x,
175  const Evaluation<ValueType, numVars, staticSize>& y)
176 {
177  typedef MathToolbox<ValueType> ValueTypeToolbox;
178 
179  Evaluation<ValueType, numVars, staticSize> result(y);
180 
181  result.setValue(ValueTypeToolbox::atan2(x, y.value()));
182 
183  // derivatives use the chain rule
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));
189  }
190 
191  return result;
192 }
193 
194 template <class ValueType, int numVars, unsigned staticSize>
195 Evaluation<ValueType, numVars, staticSize> sin(const Evaluation<ValueType, numVars, staticSize>& x)
196 {
197  typedef MathToolbox<ValueType> ValueTypeToolbox;
198 
199  Evaluation<ValueType, numVars, staticSize> result(x);
200 
201  result.setValue(ValueTypeToolbox::sin(x.value()));
202 
203  // derivatives use the chain rule
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));
207 
208  return result;
209 }
210 
211 template <class ValueType, int numVars, unsigned staticSize>
212 Evaluation<ValueType, numVars, staticSize> asin(const Evaluation<ValueType, numVars, staticSize>& x)
213 {
214  typedef MathToolbox<ValueType> ValueTypeToolbox;
215 
216  Evaluation<ValueType, numVars, staticSize> result(x);
217 
218  result.setValue(ValueTypeToolbox::asin(x.value()));
219 
220  // derivatives use the chain rule
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));
224 
225  return result;
226 }
227 
228 template <class ValueType, int numVars, unsigned staticSize>
229 Evaluation<ValueType, numVars, staticSize> sinh(const Evaluation<ValueType, numVars, staticSize>& x)
230 {
231  typedef MathToolbox<ValueType> ValueTypeToolbox;
232 
233  Evaluation<ValueType, numVars, staticSize> result(x);
234 
235  result.setValue(ValueTypeToolbox::sinh(x.value()));
236 
237  // derivatives use the chain rule
238  const ValueType& df_dx = ValueTypeToolbox::cosh(x.value());
239  for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
240  result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
241 
242  return result;
243 }
244 
245 template <class ValueType, int numVars, unsigned staticSize>
246 Evaluation<ValueType, numVars, staticSize> asinh(const Evaluation<ValueType, numVars, staticSize>& x)
247 {
248  typedef MathToolbox<ValueType> ValueTypeToolbox;
249 
250  Evaluation<ValueType, numVars, staticSize> result(x);
251 
252  result.setValue(ValueTypeToolbox::asinh(x.value()));
253 
254  // derivatives use the chain rule
255  const ValueType& df_dx = 1.0/ValueTypeToolbox::sqrt(x.value()*x.value() + 1);
256  for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
257  result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
258 
259  return result;
260 }
261 
262 template <class ValueType, int numVars, unsigned staticSize>
263 Evaluation<ValueType, numVars, staticSize> cos(const Evaluation<ValueType, numVars, staticSize>& x)
264 {
265  typedef MathToolbox<ValueType> ValueTypeToolbox;
266 
267  Evaluation<ValueType, numVars, staticSize> result(x);
268 
269  result.setValue(ValueTypeToolbox::cos(x.value()));
270 
271  // derivatives use the chain rule
272  const ValueType& df_dx = -ValueTypeToolbox::sin(x.value());
273  for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
274  result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
275 
276  return result;
277 }
278 
279 template <class ValueType, int numVars, unsigned staticSize>
280 Evaluation<ValueType, numVars, staticSize> acos(const Evaluation<ValueType, numVars, staticSize>& x)
281 {
282  typedef MathToolbox<ValueType> ValueTypeToolbox;
283 
284  Evaluation<ValueType, numVars, staticSize> result(x);
285 
286  result.setValue(ValueTypeToolbox::acos(x.value()));
287 
288  // derivatives use the chain rule
289  const ValueType& df_dx = - 1.0/ValueTypeToolbox::sqrt(1 - x.value()*x.value());
290  for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
291  result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
292 
293  return result;
294 }
295 
296 template <class ValueType, int numVars, unsigned staticSize>
297 Evaluation<ValueType, numVars, staticSize> cosh(const Evaluation<ValueType, numVars, staticSize>& x)
298 {
299  typedef MathToolbox<ValueType> ValueTypeToolbox;
300 
301  Evaluation<ValueType, numVars, staticSize> result(x);
302 
303  result.setValue(ValueTypeToolbox::cosh(x.value()));
304 
305  // derivatives use the chain rule
306  const ValueType& df_dx = ValueTypeToolbox::sinh(x.value());
307  for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
308  result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
309 
310  return result;
311 }
312 
313 template <class ValueType, int numVars, unsigned staticSize>
314 Evaluation<ValueType, numVars, staticSize> acosh(const Evaluation<ValueType, numVars, staticSize>& x)
315 {
316  typedef MathToolbox<ValueType> ValueTypeToolbox;
317 
318  Evaluation<ValueType, numVars, staticSize> result(x);
319 
320  result.setValue(ValueTypeToolbox::acosh(x.value()));
321 
322  // derivatives use the chain rule
323  const ValueType& df_dx = 1.0/ValueTypeToolbox::sqrt(x.value()*x.value() - 1);
324  for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
325  result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
326 
327  return result;
328 }
329 
330 template <class ValueType, int numVars, unsigned staticSize>
331 Evaluation<ValueType, numVars, staticSize> sqrt(const Evaluation<ValueType, numVars, staticSize>& x)
332 {
333  typedef MathToolbox<ValueType> ValueTypeToolbox;
334 
335  Evaluation<ValueType, numVars, staticSize> result(x);
336 
337  const ValueType& sqrt_x = ValueTypeToolbox::sqrt(x.value());
338  result.setValue(sqrt_x);
339 
340  // derivatives use the chain rule
341  ValueType df_dx = 0.5/sqrt_x;
342  for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
343  result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
344  }
345 
346  return result;
347 }
348 
349 template <class ValueType, int numVars, unsigned staticSize>
350 Evaluation<ValueType, numVars, staticSize> exp(const Evaluation<ValueType, numVars, staticSize>& x)
351 {
352  typedef MathToolbox<ValueType> ValueTypeToolbox;
353  Evaluation<ValueType, numVars, staticSize> result(x);
354 
355  const ValueType& exp_x = ValueTypeToolbox::exp(x.value());
356  result.setValue(exp_x);
357 
358  // derivatives use the chain rule
359  const ValueType& df_dx = exp_x;
360  for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
361  result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
362 
363  return result;
364 }
365 
366 // exponentiation of arbitrary base with a fixed constant
367 template <class ValueType, int numVars, unsigned staticSize, class ExpType>
368 Evaluation<ValueType, numVars, staticSize> pow(const Evaluation<ValueType, numVars, staticSize>& base,
369  const ExpType& exp)
370 {
371  typedef MathToolbox<ValueType> ValueTypeToolbox;
372  Evaluation<ValueType, numVars, staticSize> result(base);
373 
374  const ValueType& pow_x = ValueTypeToolbox::pow(base.value(), exp);
375  result.setValue(pow_x);
376 
377  if (base == 0.0) {
378  // we special case the base 0 case because 0.0 is in the valid range of the
379  // base but the generic code leads to NaNs.
380  result = 0.0;
381  }
382  else {
383  // derivatives use the chain rule
384  const ValueType& df_dx = pow_x/base.value()*exp;
385  for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
386  result.setDerivative(curVarIdx, df_dx*base.derivative(curVarIdx));
387  }
388 
389  return result;
390 }
391 
392 // exponentiation of constant base with an arbitrary exponent
393 template <class BaseType, class ValueType, int numVars, unsigned staticSize>
394 Evaluation<ValueType, numVars, staticSize> pow(const BaseType& base,
395  const Evaluation<ValueType, numVars, staticSize>& exp)
396 {
397  typedef MathToolbox<ValueType> ValueTypeToolbox;
398 
399  Evaluation<ValueType, numVars, staticSize> result(exp);
400 
401  if (base == 0.0) {
402  // we special case the base 0 case because 0.0 is in the valid range of the
403  // base but the generic code leads to NaNs.
404  result = 0.0;
405  }
406  else {
407  const ValueType& lnBase = ValueTypeToolbox::log(base);
408  result.setValue(ValueTypeToolbox::exp(lnBase*exp.value()));
409 
410  // derivatives use the chain rule
411  const ValueType& df_dx = lnBase*result.value();
412  for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
413  result.setDerivative(curVarIdx, df_dx*exp.derivative(curVarIdx));
414  }
415 
416  return result;
417 }
418 
419 // this is the most expensive power function. Computationally it is pretty expensive, so
420 // one of the above two variants above should be preferred if possible.
421 template <class ValueType, int numVars, unsigned staticSize>
422 Evaluation<ValueType, numVars, staticSize> pow(const Evaluation<ValueType, numVars, staticSize>& base,
423  const Evaluation<ValueType, numVars, staticSize>& exp)
424 {
425  typedef MathToolbox<ValueType> ValueTypeToolbox;
426 
427  Evaluation<ValueType, numVars, staticSize> result(base);
428 
429  if (base == 0.0) {
430  // we special case the base 0 case because 0.0 is in the valid range of the
431  // base but the generic code leads to NaNs.
432  result = 0.0;
433  }
434  else {
435  ValueType valuePow = ValueTypeToolbox::pow(base.value(), exp.value());
436  result.setValue(valuePow);
437 
438  // use the chain rule for the derivatives. since both, the base and the exponent can
439  // potentially depend on the variable set, calculating these is quite elaborate...
440  const ValueType& f = base.value();
441  const ValueType& g = exp.value();
442  const ValueType& logF = ValueTypeToolbox::log(f);
443  for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx) {
444  const ValueType& fPrime = base.derivative(curVarIdx);
445  const ValueType& gPrime = exp.derivative(curVarIdx);
446  result.setDerivative(curVarIdx, (g*fPrime/f + logF*gPrime) * valuePow);
447  }
448  }
449 
450  return result;
451 }
452 
453 template <class ValueType, int numVars, unsigned staticSize>
454 Evaluation<ValueType, numVars, staticSize> log(const Evaluation<ValueType, numVars, staticSize>& x)
455 {
456  typedef MathToolbox<ValueType> ValueTypeToolbox;
457 
458  Evaluation<ValueType, numVars, staticSize> result(x);
459 
460  result.setValue(ValueTypeToolbox::log(x.value()));
461 
462  // derivatives use the chain rule
463  const ValueType& df_dx = 1/x.value();
464  for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
465  result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
466 
467  return result;
468 }
469 
470 
471 template <class ValueType, int numVars, unsigned staticSize>
472 Evaluation<ValueType, numVars, staticSize> log10(const Evaluation<ValueType, numVars, staticSize>& x)
473 {
474  typedef MathToolbox<ValueType> ValueTypeToolbox;
475 
476  Evaluation<ValueType, numVars, staticSize> result(x);
477 
478  result.setValue(ValueTypeToolbox::log10(x.value()));
479 
480  // derivatives use the chain rule
481  const ValueType& df_dx = 1/x.value() * ValueTypeToolbox::log10(ValueTypeToolbox::exp(1.0));
482  for (int curVarIdx = 0; curVarIdx < result.size(); ++curVarIdx)
483  result.setDerivative(curVarIdx, df_dx*x.derivative(curVarIdx));
484 
485  return result;
486 }
487 
488 } // namespace DenseAd
489 
490 // a kind of traits class for the automatic differentiation case. (The toolbox for the
491 // scalar case is provided by the MathToolbox.hpp header file.)
492 template <class ValueT, int numVars, unsigned staticSize>
493 struct MathToolbox<DenseAd::Evaluation<ValueT, numVars, staticSize> >
494 {
495 private:
496 public:
497  typedef ValueT ValueType;
499  typedef typename InnerToolbox::Scalar Scalar;
501 
502  static ValueType value(const Evaluation& eval)
503  { return eval.value(); }
504 
505  static decltype(InnerToolbox::scalarValue(0.0)) scalarValue(const Evaluation& eval)
506  { return InnerToolbox::scalarValue(eval.value()); }
507 
508  static Evaluation createBlank(const Evaluation& x)
509  { return Evaluation::createBlank(x); }
510 
511  static Evaluation createConstantZero(const Evaluation& x)
512  { return Evaluation::createConstantZero(x); }
513 
514  static Evaluation createConstantOne(const Evaluation& x)
515  { return Evaluation::createConstantOne(x); }
516 
517  static Evaluation createConstant(ValueType value)
518  { return Evaluation::createConstant(value); }
519 
520  static Evaluation createConstant(unsigned numDeriv, const ValueType value)
521  { return Evaluation::createConstant(numDeriv, value); }
522 
523  static Evaluation createConstant(const Evaluation& x, const ValueType value)
524  { return Evaluation::createConstant(x, value); }
525 
526  static Evaluation createVariable(ValueType value, int varIdx)
527  { return Evaluation::createVariable(value, varIdx); }
528 
529  template <class LhsEval>
530  static typename std::enable_if<std::is_same<Evaluation, LhsEval>::value,
531  LhsEval>::type
532  decay(const Evaluation& eval)
533  { return eval; }
534 
535  template <class LhsEval>
536  static typename std::enable_if<std::is_same<Evaluation, LhsEval>::value,
537  LhsEval>::type
538  decay(const Evaluation&& eval)
539  { return eval; }
540 
541  template <class LhsEval>
542  static typename std::enable_if<std::is_floating_point<LhsEval>::value,
543  LhsEval>::type
544  decay(const Evaluation& eval)
545  { return eval.value(); }
546 
547  // comparison
548  static bool isSame(const Evaluation& a, const Evaluation& b, Scalar tolerance)
549  {
550  typedef MathToolbox<ValueType> ValueTypeToolbox;
551 
552  // make sure that the value of the evaluation is identical
553  if (!ValueTypeToolbox::isSame(a.value(), b.value(), tolerance))
554  return false;
555 
556  // make sure that the derivatives are identical
557  for (int curVarIdx = 0; curVarIdx < numVars; ++curVarIdx)
558  if (!ValueTypeToolbox::isSame(a.derivative(curVarIdx), b.derivative(curVarIdx), tolerance))
559  return false;
560 
561  return true;
562  }
563 
564  // arithmetic functions
565  template <class Arg1Eval, class Arg2Eval>
566  static Evaluation max(const Arg1Eval& arg1, const Arg2Eval& arg2)
567  { return DenseAd::max(arg1, arg2); }
568 
569  template <class Arg1Eval, class Arg2Eval>
570  static Evaluation min(const Arg1Eval& arg1, const Arg2Eval& arg2)
571  { return DenseAd::min(arg1, arg2); }
572 
573  static Evaluation abs(const Evaluation& arg)
574  { return DenseAd::abs(arg); }
575 
576  static Evaluation tan(const Evaluation& arg)
577  { return DenseAd::tan(arg); }
578 
579  static Evaluation atan(const Evaluation& arg)
580  { return DenseAd::atan(arg); }
581 
582  static Evaluation atan2(const Evaluation& arg1, const Evaluation& arg2)
583  { return DenseAd::atan2(arg1, arg2); }
584 
585  template <class Eval2>
586  static Evaluation atan2(const Evaluation& arg1, const Eval2& arg2)
587  { return DenseAd::atan2(arg1, arg2); }
588 
589  template <class Eval1>
590  static Evaluation atan2(const Eval1& arg1, const Evaluation& arg2)
591  { return DenseAd::atan2(arg1, arg2); }
592 
593  static Evaluation sin(const Evaluation& arg)
594  { return DenseAd::sin(arg); }
595 
596  static Evaluation asin(const Evaluation& arg)
597  { return DenseAd::asin(arg); }
598 
599  static Evaluation cos(const Evaluation& arg)
600  { return DenseAd::cos(arg); }
601 
602  static Evaluation acos(const Evaluation& arg)
603  { return DenseAd::acos(arg); }
604 
605  static Evaluation sqrt(const Evaluation& arg)
606  { return DenseAd::sqrt(arg); }
607 
608  static Evaluation exp(const Evaluation& arg)
609  { return DenseAd::exp(arg); }
610 
611  static Evaluation log(const Evaluation& arg)
612  { return DenseAd::log(arg); }
613 
614  static Evaluation log10(const Evaluation& arg)
615  { return DenseAd::log10(arg); }
616 
617  template <class RhsValueType>
618  static Evaluation pow(const Evaluation& arg1, const RhsValueType& arg2)
619  { return DenseAd::pow(arg1, arg2); }
620 
621  template <class RhsValueType>
622  static Evaluation pow(const RhsValueType& arg1, const Evaluation& arg2)
623  { return DenseAd::pow(arg1, arg2); }
624 
625  static Evaluation pow(const Evaluation& arg1, const Evaluation& arg2)
626  { return DenseAd::pow(arg1, arg2); }
627 
628  static bool isfinite(const Evaluation& arg)
629  {
630  if (!InnerToolbox::isfinite(arg.value()))
631  return false;
632 
633  for (int i = 0; i < numVars; ++i)
634  if (!InnerToolbox::isfinite(arg.derivative(i)))
635  return false;
636 
637  return true;
638  }
639 
640  static bool isnan(const Evaluation& arg)
641  {
642  if (InnerToolbox::isnan(arg.value()))
643  return true;
644 
645  for (int i = 0; i < numVars; ++i)
646  if (InnerToolbox::isnan(arg.derivative(i)))
647  return true;
648 
649  return false;
650  }
651 };
652 
653 }
654 
655 #endif
Representation of an evaluation of a function and its derivatives w.r.t.
A traits class which provides basic mathematical functions for arbitrary scalar floating point values...
Represents a function evaluation and its derivatives w.r.t.
Definition: Evaluation.hpp:59
Definition: MathToolbox.hpp:50
static LhsEval decay(Scalar value)
Given a function evaluation, constrain it to its value (if necessary).
Definition: MathToolbox.hpp:173
static bool isSame(Scalar a, Scalar b, Scalar tolerance)
Returns true if two values are identical up to a specified tolerance.
Definition: MathToolbox.hpp:184
static Scalar min(Scalar arg1, Scalar arg2)
The minimum of two arguments.
Definition: MathToolbox.hpp:201
static Scalar createBlank(Scalar)
Given a scalar value, return a "compatible" object.
Definition: MathToolbox.hpp:101
static Scalar value(Scalar value)
Return the value of the function at a given evaluation point.
Definition: MathToolbox.hpp:83
ScalarT Scalar
The type used to represent "primitive" scalar values.
Definition: MathToolbox.hpp:52
static Scalar atan2(Scalar arg1, Scalar arg2)
The arcus tangens of a value.
Definition: MathToolbox.hpp:217
static Scalar cos(Scalar arg)
The cosine of a value.
Definition: MathToolbox.hpp:237
static Scalar tan(Scalar arg)
The tangens of a value.
Definition: MathToolbox.hpp:209
static bool isfinite(Scalar arg)
Return true iff the argument's value and all its derivatives are finite values.
Definition: MathToolbox.hpp:273
static Scalar exp(Scalar arg)
The natural exponentiation of a value.
Definition: MathToolbox.hpp:257
static Scalar acos(Scalar arg)
The arcus cosine of a value.
Definition: MathToolbox.hpp:241
static Scalar sqrt(Scalar arg)
The square root of a value.
Definition: MathToolbox.hpp:253
static Scalar sin(Scalar arg)
The sine of a value.
Definition: MathToolbox.hpp:221
static Scalar pow(Scalar base, Scalar exp)
Exponentiation to an arbitrary base.
Definition: MathToolbox.hpp:269
ScalarT ValueType
The type used to represent values.
Definition: MathToolbox.hpp:66
static Scalar abs(Scalar arg)
The absolute value.
Definition: MathToolbox.hpp:205
MathToolbox< Scalar > InnerToolbox
The toolbox for the type of value objects.
Definition: MathToolbox.hpp:75
static Scalar log10(Scalar arg)
The 10 logarithm of a value.
Definition: MathToolbox.hpp:261
static Scalar createVariable(Scalar, unsigned)
Given a scalar value, return an evaluation of a linear function.
Definition: MathToolbox.hpp:147
static Scalar log(Scalar arg)
The natural logarithm of a value.
Definition: MathToolbox.hpp:265
static Scalar createConstant(Scalar value)
Given a scalar value, return an evaluation of a constant function.
Definition: MathToolbox.hpp:111
static Scalar atan(Scalar arg)
The arcus tangens of a value.
Definition: MathToolbox.hpp:213
static Scalar scalarValue(Scalar value)
Return the primitive scalar value of a value object.
Definition: MathToolbox.hpp:92
static Scalar asin(Scalar arg)
The arcus sine of a value.
Definition: MathToolbox.hpp:225
static Scalar max(Scalar arg1, Scalar arg2)
The maximum of two arguments.
Definition: MathToolbox.hpp:197
static bool isnan(Scalar arg)
Return true iff the argument's value or any of its derivatives are NaN values.
Definition: MathToolbox.hpp:277