My Project
Loading...
Searching...
No Matches
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
39namespace Opm {
40namespace DenseAd {
41// forward declaration of the Evaluation template class
42template <class ValueT, int numVars, unsigned staticSize>
43class Evaluation;
44
45// provide some algebraic functions
46template <class ValueType, int numVars, unsigned staticSize>
47Evaluation<ValueType, numVars, staticSize> abs(const Evaluation<ValueType, numVars, staticSize>& x)
48{ return (x > 0.0)?x:-x; }
49
50template <class ValueType, int numVars, unsigned staticSize>
51Evaluation<ValueType, numVars, staticSize> min(const Evaluation<ValueType, numVars, staticSize>& x1,
52 const Evaluation<ValueType, numVars, staticSize>& x2)
53{ return (x1 < x2)?x1:x2; }
54
55template <class Arg1ValueType, class ValueType, int numVars, unsigned staticSize>
56Evaluation<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
68template <class ValueType, int numVars, unsigned staticSize, class Arg2ValueType>
69Evaluation<ValueType, numVars, staticSize> min(const Evaluation<ValueType, numVars, staticSize>& x1,
70 const Arg2ValueType& x2)
71{ return min(x2, x1); }
72
73template <class ValueType, int numVars, unsigned staticSize>
74Evaluation<ValueType, numVars, staticSize> max(const Evaluation<ValueType, numVars, staticSize>& x1,
75 const Evaluation<ValueType, numVars, staticSize>& x2)
76{ return (x1 > x2)?x1:x2; }
77
78template <class Arg1ValueType, class ValueType, int numVars, unsigned staticSize>
79Evaluation<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
91template <class ValueType, int numVars, unsigned staticSize, class Arg2ValueType>
92Evaluation<ValueType, numVars, staticSize> max(const Evaluation<ValueType, numVars, staticSize>& x1,
93 const Arg2ValueType& x2)
94{ return max(x2, x1); }
95
96template <class ValueType, int numVars, unsigned staticSize>
97Evaluation<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
114template <class ValueType, int numVars, unsigned staticSize>
115Evaluation<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
131template <class ValueType, int numVars, unsigned staticSize>
132Evaluation<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
152template <class ValueType, int numVars, unsigned staticSize>
153Evaluation<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
173template <class ValueType, int numVars, unsigned staticSize>
174Evaluation<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
194template <class ValueType, int numVars, unsigned staticSize>
195Evaluation<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
211template <class ValueType, int numVars, unsigned staticSize>
212Evaluation<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
228template <class ValueType, int numVars, unsigned staticSize>
229Evaluation<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
245template <class ValueType, int numVars, unsigned staticSize>
246Evaluation<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
262template <class ValueType, int numVars, unsigned staticSize>
263Evaluation<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
279template <class ValueType, int numVars, unsigned staticSize>
280Evaluation<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
296template <class ValueType, int numVars, unsigned staticSize>
297Evaluation<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
313template <class ValueType, int numVars, unsigned staticSize>
314Evaluation<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
330template <class ValueType, int numVars, unsigned staticSize>
331Evaluation<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
349template <class ValueType, int numVars, unsigned staticSize>
350Evaluation<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
367template <class ValueType, int numVars, unsigned staticSize, class ExpType>
368Evaluation<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
393template <class BaseType, class ValueType, int numVars, unsigned staticSize>
394Evaluation<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.
421template <class ValueType, int numVars, unsigned staticSize>
422Evaluation<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
453template <class ValueType, int numVars, unsigned staticSize>
454Evaluation<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
471template <class ValueType, int numVars, unsigned staticSize>
472Evaluation<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.)
492template <class ValueT, int numVars, unsigned staticSize>
493struct MathToolbox<DenseAd::Evaluation<ValueT, numVars, staticSize> >
494{
495private:
496public:
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:57
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30
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
ScalarT Scalar
The type used to represent "primitive" scalar values.
Definition MathToolbox.hpp:57
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