Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Sacado_CacheFad_GeneralFad.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Sacado Package
4 //
5 // Copyright 2006 NTESS and the Sacado contributors.
6 // SPDX-License-Identifier: LGPL-2.1-or-later
7 //
8 // ***********************************************************************
9 //
10 // The forward-mode AD classes in Sacado are a derivative work of the
11 // expression template classes in the Fad package by Nicolas Di Cesare.
12 // The following banner is included in the original Fad source code:
13 //
14 // ************ DO NOT REMOVE THIS BANNER ****************
15 //
16 // Nicolas Di Cesare <Nicolas.Dicesare@ann.jussieu.fr>
17 // http://www.ann.jussieu.fr/~dicesare
18 //
19 // CEMRACS 98 : C++ courses,
20 // templates : new C++ techniques
21 // for scientific computing
22 //
23 //********************************************************
24 //
25 // A short implementation ( not all operators and
26 // functions are overloaded ) of 1st order Automatic
27 // Differentiation in forward mode (FAD) using
28 // EXPRESSION TEMPLATES.
29 //
30 //********************************************************
31 // @HEADER
32 
33 #ifndef SACADO_CACHEFAD_GENERALFAD_HPP
34 #define SACADO_CACHEFAD_GENERALFAD_HPP
35 
37 
38 namespace Sacado {
39 
41  namespace CacheFad {
42 
44 
55  template <typename T, typename Storage>
56  class GeneralFad : public Storage {
57 
58  public:
59 
61  typedef typename RemoveConst<T>::type value_type;
62 
65 
70 
73  GeneralFad() : Storage(T(0.)) {}
74 
76 
79  template <typename S>
82  Storage(x) {}
83 
85 
89  GeneralFad(const int sz, const T & x, const DerivInit zero_out = InitDerivArray) :
90  Storage(sz, x, zero_out) {}
91 
93 
99  GeneralFad(const int sz, const int i, const T & x) :
100  Storage(sz, x, InitDerivArray) {
101  this->fastAccessDx(i)=1.;
102  }
103 
106  GeneralFad(const Storage& s) : Storage(s) {}
107 
111  Storage(x) {}
112 
114  template <typename S>
117  Storage(x.size(), T(0.), NoInitDerivArray) {
118  x.cache();
119 
120  const int sz = x.size();
121 
122  this->val() = x.val();
123 
124  if (sz) {
125  if (x.hasFastAccess())
126  for(int i=0; i<sz; ++i)
127  this->fastAccessDx(i) = x.fastAccessDx(i);
128  else
129  for(int i=0; i<sz; ++i)
130  this->fastAccessDx(i) = x.dx(i);
131  }
132  }
133 
137 
139 
146  void diff(const int ith, const int n) {
147  if (this->size() != n)
148  this->resize(n);
149 
150  this->zero();
151  this->fastAccessDx(ith) = T(1.);
152  }
153 
156  void setUpdateValue(bool update_val) { }
157 
160  bool updateValue() const { return true; }
161 
164  void cache() const {}
165 
167  template <typename S>
169  SACADO_ENABLE_EXPR_FUNC(bool) isEqualTo(const Expr<S>& x) const {
170  typedef IsEqual<value_type> IE;
171  if (x.size() != this->size()) return false;
172  bool eq = IE::eval(x.val(), this->val());
173  for (int i=0; i<this->size(); i++)
174  eq = eq && IE::eval(x.dx(i), this->dx(i));
175  return eq;
176  }
177 
179 
184 
190  int availableSize() const { return this->length(); }
191 
194  bool hasFastAccess() const { return this->size()!=0;}
195 
198  bool isPassive() const { return this->size()==0;}
199 
202  void setIsConstant(bool is_const) {
203  if (is_const && this->size()!=0)
204  this->resize(0);
205  }
206 
208 
213 
215  template <typename S>
217  SACADO_ENABLE_VALUE_FUNC(GeneralFad&) operator=(const S& v) {
218  this->val() = v;
219  if (this->size()) this->resize(0);
220  return *this;
221  }
222 
225  GeneralFad&
226  operator=(const GeneralFad& x) {
227  // Copy val_ and dx_
228  Storage::operator=(x);
229  return *this;
230  }
231 
233  template <typename S>
235  SACADO_ENABLE_EXPR_FUNC(GeneralFad&) operator=(const Expr<S>& x) {
236  x.cache();
237 
238  const int xsz = x.size();
239 
240  if (xsz != this->size())
241  this->resizeAndZero(xsz);
242 
243  const int sz = this->size();
244 
245  // For ViewStorage, the resize above may not in fact resize the
246  // derivative array, so it is possible that sz != xsz at this point.
247  // The only valid use case here is sz > xsz == 0, so we use sz in the
248  // assignment below
249 
250  if (sz) {
251  if (x.hasFastAccess())
252  for(int i=0; i<sz; ++i)
253  this->fastAccessDx(i) = x.fastAccessDx(i);
254  else
255  for(int i=0; i<sz; ++i)
256  this->fastAccessDx(i) = x.dx(i);
257  }
258 
259  this->val() = x.val();
260 
261  return *this;
262  }
263 
265 
270 
272  template <typename S>
274  SACADO_ENABLE_VALUE_FUNC(GeneralFad&) operator += (const S& v) {
275  this->val() += v;
276  return *this;
277  }
278 
280  template <typename S>
282  SACADO_ENABLE_VALUE_FUNC(GeneralFad&) operator -= (const S& v) {
283  this->val() -= v;
284  return *this;
285  }
286 
288  template <typename S>
290  SACADO_ENABLE_VALUE_FUNC(GeneralFad&) operator *= (const S& v) {
291  const int sz = this->size();
292  this->val() *= v;
293  for (int i=0; i<sz; ++i)
294  this->fastAccessDx(i) *= v;
295  return *this;
296  }
297 
299  template <typename S>
301  SACADO_ENABLE_VALUE_FUNC(GeneralFad&) operator /= (const S& v) {
302  const int sz = this->size();
303  this->val() /= v;
304  for (int i=0; i<sz; ++i)
305  this->fastAccessDx(i) /= v;
306  return *this;
307  }
308 
311  GeneralFad& operator += (const GeneralFad& x) {
312  const int xsz = x.size(), sz = this->size();
313 
314 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
315  if ((xsz != sz) && (xsz != 0) && (sz != 0))
316  throw "Fad Error: Attempt to assign with incompatible sizes";
317 #endif
318 
319  if (xsz) {
320  if (sz) {
321  for (int i=0; i<sz; ++i)
322  this->fastAccessDx(i) += x.fastAccessDx(i);
323  }
324  else {
325  this->resizeAndZero(xsz);
326  for (int i=0; i<xsz; ++i)
327  this->fastAccessDx(i) = x.fastAccessDx(i);
328  }
329  }
330 
331  this->val() += x.val();
332 
333  return *this;
334  }
335 
338  GeneralFad& operator -= (const GeneralFad& x) {
339  const int xsz = x.size(), sz = this->size();
340 
341 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
342  if ((xsz != sz) && (xsz != 0) && (sz != 0))
343  throw "Fad Error: Attempt to assign with incompatible sizes";
344 #endif
345 
346  if (xsz) {
347  if (sz) {
348  for(int i=0; i<sz; ++i)
349  this->fastAccessDx(i) -= x.fastAccessDx(i);
350  }
351  else {
352  this->resizeAndZero(xsz);
353  for(int i=0; i<xsz; ++i)
354  this->fastAccessDx(i) = -x.fastAccessDx(i);
355  }
356  }
357 
358  this->val() -= x.val();
359 
360 
361  return *this;
362  }
363 
366  GeneralFad& operator *= (const GeneralFad& x) {
367  const int xsz = x.size(), sz = this->size();
368  T xval = x.val();
369  T v = this->val();
370 
371 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
372  if ((xsz != sz) && (xsz != 0) && (sz != 0))
373  throw "Fad Error: Attempt to assign with incompatible sizes";
374 #endif
375 
376  if (xsz) {
377  if (sz) {
378  for(int i=0; i<sz; ++i)
379  this->fastAccessDx(i) = v*x.fastAccessDx(i) + this->fastAccessDx(i)*xval;
380  }
381  else {
382  this->resizeAndZero(xsz);
383  for(int i=0; i<xsz; ++i)
384  this->fastAccessDx(i) = v*x.fastAccessDx(i);
385  }
386  }
387  else {
388  if (sz) {
389  for (int i=0; i<sz; ++i)
390  this->fastAccessDx(i) *= xval;
391  }
392  }
393 
394  this->val() *= xval;
395 
396  return *this;
397  }
398 
401  GeneralFad& operator /= (const GeneralFad& x) {
402  const int xsz = x.size(), sz = this->size();
403  T xval = x.val();
404  T v = this->val();
405 
406 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
407  if ((xsz != sz) && (xsz != 0) && (sz != 0))
408  throw "Fad Error: Attempt to assign with incompatible sizes";
409 #endif
410 
411  if (xsz) {
412  if (sz) {
413  for(int i=0; i<sz; ++i)
414  this->fastAccessDx(i) =
415  ( this->fastAccessDx(i)*xval - v*x.fastAccessDx(i) )/ (xval*xval);
416  }
417  else {
418  this->resizeAndZero(xsz);
419  for(int i=0; i<xsz; ++i)
420  this->fastAccessDx(i) = - v*x.fastAccessDx(i) / (xval*xval);
421  }
422  }
423  else {
424  if (sz) {
425  for (int i=0; i<sz; ++i)
426  this->fastAccessDx(i) /= xval;
427  }
428  }
429 
430  this->val() /= xval;
431 
432  return *this;
433  }
434 
436  template <typename S>
438  SACADO_ENABLE_EXPR_FUNC(GeneralFad&) operator += (const Expr<S>& x) {
439  x.cache();
440 
441  const int xsz = x.size(), sz = this->size();
442 
443 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
444  if ((xsz != sz) && (xsz != 0) && (sz != 0))
445  throw "Fad Error: Attempt to assign with incompatible sizes";
446 #endif
447 
448  if (xsz) {
449  if (sz) {
450  if (x.hasFastAccess())
451  for (int i=0; i<sz; ++i)
452  this->fastAccessDx(i) += x.fastAccessDx(i);
453  else
454  for (int i=0; i<sz; ++i)
455  this->fastAccessDx(i) += x.dx(i);
456  }
457  else {
458  this->resizeAndZero(xsz);
459  if (x.hasFastAccess())
460  for (int i=0; i<xsz; ++i)
461  this->fastAccessDx(i) = x.fastAccessDx(i);
462  else
463  for (int i=0; i<xsz; ++i)
464  this->fastAccessDx(i) = x.dx(i);
465  }
466  }
467 
468  this->val() += x.val();
469 
470  return *this;
471  }
472 
474  template <typename S>
476  SACADO_ENABLE_EXPR_FUNC(GeneralFad&) operator -= (const Expr<S>& x) {
477  x.cache();
478 
479  const int xsz = x.size(), sz = this->size();
480 
481 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
482  if ((xsz != sz) && (xsz != 0) && (sz != 0))
483  throw "Fad Error: Attempt to assign with incompatible sizes";
484 #endif
485 
486  if (xsz) {
487  if (sz) {
488  if (x.hasFastAccess())
489  for(int i=0; i<sz; ++i)
490  this->fastAccessDx(i) -= x.fastAccessDx(i);
491  else
492  for (int i=0; i<sz; ++i)
493  this->fastAccessDx(i) -= x.dx(i);
494  }
495  else {
496  this->resizeAndZero(xsz);
497  if (x.hasFastAccess())
498  for(int i=0; i<xsz; ++i)
499  this->fastAccessDx(i) = -x.fastAccessDx(i);
500  else
501  for (int i=0; i<xsz; ++i)
502  this->fastAccessDx(i) = -x.dx(i);
503  }
504  }
505 
506  this->val() -= x.val();
507 
508 
509  return *this;
510  }
511 
513  template <typename S>
515  SACADO_ENABLE_EXPR_FUNC(GeneralFad&) operator *= (const Expr<S>& x) {
516  x.cache();
517 
518  const int xsz = x.size(), sz = this->size();
519  T xval = x.val();
520 
521 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
522  if ((xsz != sz) && (xsz != 0) && (sz != 0))
523  throw "Fad Error: Attempt to assign with incompatible sizes";
524 #endif
525 
526  if (xsz) {
527  if (sz) {
528  if (x.hasFastAccess())
529  for(int i=0; i<sz; ++i)
530  this->fastAccessDx(i) = this->val() * x.fastAccessDx(i) + this->fastAccessDx(i) * xval;
531  else
532  for (int i=0; i<sz; ++i)
533  this->fastAccessDx(i) = this->val() * x.dx(i) + this->fastAccessDx(i) * xval;
534  }
535  else {
536  this->resizeAndZero(xsz);
537  if (x.hasFastAccess())
538  for(int i=0; i<xsz; ++i)
539  this->fastAccessDx(i) = this->val() * x.fastAccessDx(i);
540  else
541  for (int i=0; i<xsz; ++i)
542  this->fastAccessDx(i) = this->val() * x.dx(i);
543  }
544  }
545  else {
546  if (sz) {
547  for (int i=0; i<sz; ++i)
548  this->fastAccessDx(i) *= xval;
549  }
550  }
551 
552  this->val() *= xval;
553 
554  return *this;
555  }
556 
558  template <typename S>
560  SACADO_ENABLE_EXPR_FUNC(GeneralFad&) operator /= (const Expr<S>& x) {
561  x.cache();
562 
563  const int xsz = x.size(), sz = this->size();
564  T xval = x.val();
565 
566 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
567  if ((xsz != sz) && (xsz != 0) && (sz != 0))
568  throw "Fad Error: Attempt to assign with incompatible sizes";
569 #endif
570 
571  if (xsz) {
572  if (sz) {
573  if (x.hasFastAccess())
574  for(int i=0; i<sz; ++i)
575  this->fastAccessDx(i) = ( this->fastAccessDx(i)*xval - this->val()*x.fastAccessDx(i) )/ (xval*xval);
576  else
577  for (int i=0; i<sz; ++i)
578  this->fastAccessDx(i) = ( this->fastAccessDx(i)*xval - this->val()*x.dx(i) )/ (xval*xval);
579  }
580  else {
581  this->resizeAndZero(xsz);
582  if (x.hasFastAccess())
583  for(int i=0; i<xsz; ++i)
584  this->fastAccessDx(i) = - this->val()*x.fastAccessDx(i) / (xval*xval);
585  else
586  for (int i=0; i<xsz; ++i)
587  this->fastAccessDx(i) = -this->val() * x.dx(i) / (xval*xval);
588  }
589  }
590  else {
591  if (sz) {
592  for (int i=0; i<sz; ++i)
593  this->fastAccessDx(i) /= xval;
594  }
595  }
596 
597  this->val() /= xval;
598 
599  return *this;
600  }
601 
603 
604  }; // class GeneralFad
605 
606  } // namespace CacheFad
607 
608 } // namespace Sacado
609 
610 #endif // SACADO_CACHEFAD_GENERALFAD_HPP
SACADO_INLINE_FUNCTION void cache() const
Cache values.
expr expr dx(i)
Forward-mode AD class templated on the storage for the derivative array.
SACADO_INLINE_FUNCTION void setUpdateValue(bool update_val)
Set whether this Fad object should update values.
#define SACADO_ENABLE_VALUE_CTOR_DECL
SACADO_INLINE_FUNCTION GeneralFad(const int sz, const int i, const T &x)
Constructor with size sz, index i, and value x.
RemoveConst< T >::type value_type
Typename of values.
SACADO_INLINE_FUNCTION GeneralFad(const int sz, const T &x, const DerivInit zero_out=InitDerivArray)
Constructor with size sz and value x.
SACADO_INLINE_FUNCTION void setIsConstant(bool is_const)
Set whether variable is constant.
SACADO_INLINE_FUNCTION GeneralFad()
Default constructor.
#define SACADO_ENABLE_EXPR_CTOR_DECL
expr val()
#define T
Definition: Sacado_rad.hpp:553
#define SACADO_ENABLE_VALUE_FUNC(RETURN_TYPE)
SACADO_INLINE_FUNCTION bool updateValue() const
Return whether this Fad object has an updated value.
ScalarType< value_type >::type scalar_type
Typename of scalar&#39;s (which may be different from T)
Base template specification for testing equivalence.
SACADO_INLINE_FUNCTION int availableSize() const
Returns number of derivative components that can be stored without reallocation.
SACADO_INLINE_FUNCTION GeneralFad(const Storage &s)
Constructor with supplied storage s.
Do not initialize the derivative array.
SACADO_INLINE_FUNCTION GeneralFad(const GeneralFad &x)
Copy constructor.
SACADO_INLINE_FUNCTION ~GeneralFad()
Destructor.
DerivInit
Enum use to signal whether the derivative array should be initialized in AD object constructors...
SACADO_INLINE_FUNCTION GeneralFad(const Expr< S > &x, SACADO_ENABLE_EXPR_CTOR_DECL)
Copy constructor from any Expression object.
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
SACADO_INLINE_FUNCTION GeneralFad(const S &x, SACADO_ENABLE_VALUE_CTOR_DECL)
Constructor with supplied value x.
SACADO_INLINE_FUNCTION bool isPassive() const
Returns true if derivative array is empty.
Initialize the derivative array.
SACADO_INLINE_FUNCTION bool hasFastAccess() const
Returns true if derivative array is not empty.
#define SACADO_INLINE_FUNCTION
SACADO_INLINE_FUNCTION SACADO_ENABLE_EXPR_FUNC(bool) isEqualTo(const Expr< S > &x) const
Returns whether two Fad objects have the same values.
SACADO_INLINE_FUNCTION void diff(const int ith, const int n)
Set GeneralFad object as the ith independent variable.
Wrapper for a generic expression template.