Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Sacado_Fad_SFad_MP_Vector.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 // The forward-mode AD classes in Sacado are a derivative work of the
10 // expression template classes in the Fad package by Nicolas Di Cesare.
11 // The following banner is included in the original Fad source code:
12 //
13 // ************ DO NOT REMOVE THIS BANNER ****************
14 //
15 // Nicolas Di Cesare <Nicolas.Dicesare@ann.jussieu.fr>
16 // http://www.ann.jussieu.fr/~dicesare
17 //
18 // CEMRACS 98 : C++ courses,
19 // templates : new C++ techniques
20 // for scientific computing
21 //
22 //********************************************************
23 //
24 // A short implementation ( not all operators and
25 // functions are overloaded ) of 1st order Automatic
26 // Differentiation in forward mode (FAD) using
27 // EXPRESSION TEMPLATES.
28 //
29 //********************************************************
30 // @HEADER
31 
32 #ifndef SACADO_FAD_SFAD_MP_VECTOR_HPP
33 #define SACADO_FAD_SFAD_MP_VECTOR_HPP
34 
35 #include "Sacado_Fad_SFad.hpp"
37 
38 namespace Stokhos {
39  template <typename Ord, typename Val, int Num, typename Dev>
40  class StaticFixedStorage;
41 }
42 
43 namespace Sacado {
44 
45  namespace MP {
46  template <typename S> class Vector;
47  }
48 
49  namespace Fad {
50 
51  template <typename Ord, typename Val, int VecNum, typename Dev, int Num>
52  struct ExprSpec< SFadExprTag< Sacado::MP::Vector< Stokhos::StaticFixedStorage<Ord,Val,VecNum,Dev> >, Num > > {
54  };
55  template <typename Ord, typename Val, int VecNum, typename Dev, int Num>
56  struct ExprSpec< SFad< Sacado::MP::Vector< Stokhos::StaticFixedStorage<Ord,Val,VecNum,Dev> >, Num > > {
58  };
59 
67  template <typename Ord, typename Val, int VecNum, typename Dev, int Num>
68  class Expr< SFadExprTag< Sacado::MP::Vector< Stokhos::StaticFixedStorage<Ord,Val,VecNum,Dev> >,Num >,ExprSpecMPVector > {
69 
70  public:
71 
73 
75  typedef typename RemoveConst<T>::type value_type;
76 
78  typedef typename ScalarType<value_type>::type scalar_type;
79 
81  typedef SFad<value_type,Num> base_expr_type;
82 
83  typedef typename value_type::value_type val_type;
84 
89 
91  KOKKOS_INLINE_FUNCTION
92  Expr() : val_( T(0.)) {
93  ss_array<T>::zero(dx_, Num); }
94 
96 
99  template <typename S>
100  KOKKOS_INLINE_FUNCTION
101  Expr(const S & x, SACADO_ENABLE_VALUE_CTOR_DECL) :
102  val_(x) {
103  ss_array<T>::zero(dx_, Num);
104  }
105 
107 
110  KOKKOS_INLINE_FUNCTION
111  Expr(const int sz, const T & x, const DerivInit zero_out = InitDerivArray) : val_(x) {
112 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
113  if (sz != Num)
114  throw "SFad::SFad() Error: Supplied derivative dimension does not match compile time length.";
115 #endif
116  if (zero_out == InitDerivArray)
117  ss_array<T>::zero(dx_, Num);
118  }
119 
121 
126  KOKKOS_INLINE_FUNCTION
127  Expr(const int sz, const int i, const T & x) :
128  val_(x) {
129 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
130  if (sz != Num)
131  throw "SFad::SFad() Error: Supplied derivative dimension does not match compile time length.";
132  if (i >= Num)
133  throw "SFad::SFad() Error: Invalid derivative index.";
134 #endif
135 
136  ss_array<T>::zero(dx_, Num);
137  dx_[i]=1.;
138  }
139 
141  KOKKOS_INLINE_FUNCTION
142  Expr(const Expr& x) :
143  val_(x.val()) {
144  for (int i=0; i<Num; i++)
145  dx_[i] = x.dx_[i];
146  }
147 
149  template <typename S>
150  KOKKOS_INLINE_FUNCTION
151  Expr(const Expr<S>& x, SACADO_ENABLE_EXPR_CTOR_DECL) {
152 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
153  if (x.size() != Num)
154  throw "SFad::SFad() Error: Attempt to assign with incompatible sizes";
155 #endif
156 
157  for(int i=0; i<Num; ++i) {
158  for (int j=0; j<VecNum; ++j)
159  dx_[i].fastAccessCoeff(j) = x.fastAccessDx(i,j);
160  }
161 
162  for (int j=0; j<VecNum; ++j)
163  this->val(j) = x.val(j);
164  }
165 
167  KOKKOS_INLINE_FUNCTION
168  ~Expr() {}
169 
171 
177  KOKKOS_INLINE_FUNCTION
178  void diff(const int ith, const int n) {
179 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
180  if (n != Num)
181  throw "SFad::diff() Error: Supplied derivative dimension does not match compile time length.";
182 #endif
183 
184  ss_array<T>::zero(dx_, Num);
185  dx_[ith] = T(1.);
186  }
187 
189 
193  KOKKOS_INLINE_FUNCTION
194  void resize(int sz) {
195 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
196  if (sz != Num)
197  throw "SFad::resize() Error: Cannot resize fixed derivative array dimension";
198 #endif
199  }
200 
202 
206  KOKKOS_INLINE_FUNCTION
207  void expand(int sz) { resize(sz); }
208 
210  KOKKOS_INLINE_FUNCTION
211  void zero() { ss_array<T>::zero(dx_, Num); }
212 
214  KOKKOS_INLINE_FUNCTION
215  void setUpdateValue(bool update_val) { }
216 
218  KOKKOS_INLINE_FUNCTION
219  bool updateValue() const { return true; }
220 
222  template <typename S>
223  KOKKOS_INLINE_FUNCTION
224  SACADO_ENABLE_EXPR_FUNC(bool) isEqualTo(const Expr<S>& x) const {
225  typedef IsEqual<value_type> IE;
226  if (x.size() != this->size()) return false;
227  bool eq = IE::eval(x.val(), this->val());
228  for (int i=0; i<this->size(); i++)
229  eq = eq && IE::eval(x.dx(i), this->dx(i));
230  return eq;
231  }
232 
234 
239 
241  KOKKOS_INLINE_FUNCTION
242  const T& val() const { return val_;}
243 
245  KOKKOS_INLINE_FUNCTION
246  T& val() { return val_;}
247 
249  KOKKOS_INLINE_FUNCTION
250  const val_type& val(int j) const { return val_.fastAccessCoeff(j);}
251 
253  KOKKOS_INLINE_FUNCTION
254  val_type& val(int j) { return val_.fastAccessCoeff(j);}
255 
257 
262 
264  KOKKOS_INLINE_FUNCTION
265  int size() const { return Num;}
266 
271  KOKKOS_INLINE_FUNCTION
272  int availableSize() const { return Num; }
273 
275  KOKKOS_INLINE_FUNCTION
276  bool hasFastAccess() const { return true; }
277 
279  KOKKOS_INLINE_FUNCTION
280  bool isPassive() const { return false; }
281 
283  KOKKOS_INLINE_FUNCTION
284  void setIsConstant(bool is_const) {}
285 
287  KOKKOS_INLINE_FUNCTION
288  const T* dx() const { return &(dx_[0]);}
289 
291  KOKKOS_INLINE_FUNCTION
292  const T& dx(int i) const { return dx_[i]; }
293 
295  KOKKOS_INLINE_FUNCTION
296  T& fastAccessDx(int i) { return dx_[i];}
297 
299  KOKKOS_INLINE_FUNCTION
300  const T& fastAccessDx(int i) const { return dx_[i];}
301 
303  KOKKOS_INLINE_FUNCTION
304  const val_type& dx(int i, int j) const { return dx_[i].fastAccessCoeff(j); }
305 
307  KOKKOS_INLINE_FUNCTION
308  val_type& fastAccessDx(int i, int j) { return dx_[i].fastAccessCoeff(j);}
309 
311  KOKKOS_INLINE_FUNCTION
312  const val_type& fastAccessDx(int i, int j) const { return dx_[i].fastAccessCoeff(j);}
313 
315 
320 
322  template <typename S>
323  KOKKOS_INLINE_FUNCTION
324  SACADO_ENABLE_VALUE_FUNC(Expr&) operator=(const S& v) {
325  val_ = v;
326  ss_array<T>::zero(dx_, Num);
327  return *this;
328  }
329 
331  KOKKOS_INLINE_FUNCTION
332  Expr& operator=(const Expr& x) {
333  if (this != &x) {
334  // Copy value
335  val_ = x.val_;
336 
337  // Copy dx_
338  for (int i=0; i<Num; i++)
339  dx_[i] = x.dx_[i];
340  }
341  return *this;
342  }
343 
345  template <typename S>
346  KOKKOS_INLINE_FUNCTION
347  SACADO_ENABLE_EXPR_FUNC(Expr&) operator=(const Expr<S>& x) {
348 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
349  if (x.size() != Num)
350  throw "SFad::operator=() Error: Attempt to assign with incompatible sizes";
351 #endif
352 
353  for(int i=0; i<Num; ++i) {
354  for (int j=0; j<VecNum; ++j)
355  dx_[i].fastAccessCoeff(j) = x.fastAccessDx(i,j);
356  }
357 
358  for (int j=0; j<VecNum; ++j)
359  this->val(j) = x.val(j);
360 
361  return *this;
362  }
363 
365 
370 
372  template <typename S>
373  KOKKOS_INLINE_FUNCTION
374  SACADO_ENABLE_VALUE_FUNC(Expr&) operator += (const S& v) {
375  this->val() += v;
376  return *this;
377  }
378 
380  template <typename S>
381  KOKKOS_INLINE_FUNCTION
382  SACADO_ENABLE_VALUE_FUNC(Expr&) operator -= (const S& v) {
383  this->val() -= v;
384  return *this;
385  }
386 
388  template <typename S>
389  KOKKOS_INLINE_FUNCTION
390  SACADO_ENABLE_VALUE_FUNC(Expr&) operator *= (const S& v) {
391  this->val() *= v;
392  for (int i=0; i<Num; ++i)
393  dx_[i] *= v;
394  return *this;
395  }
396 
398  template <typename S>
399  KOKKOS_INLINE_FUNCTION
400  SACADO_ENABLE_VALUE_FUNC(Expr&) operator /= (const S& v) {
401  this->val() /= v;
402  for (int i=0; i<Num; ++i)
403  dx_[i] /= v;
404  return *this;
405  }
406 
408  template <typename S>
409  KOKKOS_INLINE_FUNCTION
410  SACADO_ENABLE_EXPR_FUNC(Expr&) operator += (const Expr<S>& x) {
411 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
412  if (x.size() != Num)
413  throw "SFad::operator+=() Error: Attempt to assign with incompatible sizes";
414 #endif
415 
416  for(int i=0; i<Num; ++i) {
417  for (int j=0; j<VecNum; ++j)
418  dx_[i].fastAccessCoeff(j) += x.fastAccessDx(i,j);
419  }
420 
421  for (int j=0; j<VecNum; ++j)
422  this->val(j) += x.val(j);
423 
424  return *this;
425  }
426 
428  template <typename S>
429  KOKKOS_INLINE_FUNCTION
430  SACADO_ENABLE_EXPR_FUNC(Expr&) operator -= (const Expr<S>& x) {
431 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
432  if (x.size() != Num)
433  throw "SFad::operator-=() Error: Attempt to assign with incompatible sizes";
434 #endif
435 
436  for(int i=0; i<Num; ++i) {
437  for (int j=0; j<VecNum; ++j)
438  dx_[i].fastAccessCoeff(j) -= x.fastAccessDx(i,j);
439  }
440 
441  for (int j=0; j<VecNum; ++j)
442  this->val(j) -= x.val(j);
443 
444  return *this;
445  }
446 
448  template <typename S>
449  KOKKOS_INLINE_FUNCTION
450  SACADO_ENABLE_EXPR_FUNC(Expr&) operator *= (const Expr<S>& x) {
451  T xval;
452  for (int j=0; j<VecNum; ++j)
453  xval.fastAccessCoeff(j) = x.val(j);
454 
455 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
456  if (x.size() != Num)
457  throw "SFad::operator*=() Error: Attempt to assign with incompatible sizes";
458 #endif
459 
460  for(int i=0; i<Num; ++i)
461  for (int j=0; j<VecNum; ++j)
462  dx_[i].fastAccessCoeff(j) = val_.fastAccessCoeff(j) * x.fastAccessDx(i,j) + dx_[i] * xval.fastAccessCoeff(j);
463 
464  val_ *= xval;
465 
466  return *this;
467  }
468 
470  template <typename S>
471  KOKKOS_INLINE_FUNCTION
472  SACADO_ENABLE_EXPR_FUNC(Expr&) operator /= (const Expr<S>& x) {
473  T xval;
474  for (int j=0; j<VecNum; ++j)
475  xval.fastAccessCoeff(j) = x.val(j);
476  T xval2 = xval*xval;
477 
478 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
479  if (x.size() != Num)
480  throw "SFad::operator/=() Error: Attempt to assign with incompatible sizes";
481 #endif
482 
483  for(int i=0; i<Num; ++i)
484  for (int j=0; j<VecNum; ++j)
485  dx_[i].fastAccessCoeff(j) = ( dx_[i].fastAccessCoeff(j)*xval.fastAccessCoeff(j) - val_.fastAccessCoeff(j)*x.fastAccessDx(i,j) )/ (xval2.fastAccessCoeff(j));
486 
487  val_ /= xval;
488 
489  return *this;
490  }
491 
493 
494  protected:
495 
497  T dx_[Num];
498 
501 
502  }; // class Expr<SFadExprTag>
503 
504  } // namespace Fad
505 
506 } // namespace Sacado
507 
509 
510 #endif // SACADO_FAD_SFAD_MP_VECTOR_HPP
KOKKOS_INLINE_FUNCTION val_type & fastAccessDx(int i, int j)
Returns derivative component i without bounds checking.
KOKKOS_INLINE_FUNCTION const val_type & fastAccessDx(int i, int j) const
Returns derivative component i without bounds checking.
KOKKOS_INLINE_FUNCTION Expr(const Expr< S > &x, SACADO_ENABLE_EXPR_CTOR_DECL)
Copy constructor from any Expression object.
KOKKOS_INLINE_FUNCTION const T & fastAccessDx(int i) const
Returns derivative component i without bounds checking.
KOKKOS_INLINE_FUNCTION int availableSize() const
Returns number of derivative components that can be stored without reallocation.
KOKKOS_INLINE_FUNCTION const T & dx(int i) const
Returns derivative component i with bounds checking.
KOKKOS_INLINE_FUNCTION SACADO_ENABLE_EXPR_FUNC(bool) isEqualTo(const Expr< S > &x) const
Returns whether two Fad objects have the same values.
KOKKOS_INLINE_FUNCTION Expr(const S &x, SACADO_ENABLE_VALUE_CTOR_DECL)
Constructor with supplied value x.
expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 c fastAccessCoeff(j)-expr2.val(j)
expr expr expr dx(i, j)
KOKKOS_INLINE_FUNCTION void diff(const int ith, const int n)
Set Fad object as the ith independent variable.
expr val()
KOKKOS_INLINE_FUNCTION Expr(const int sz, const T &x, const DerivInit zero_out=InitDerivArray)
Constructor with size sz and value x.
KOKKOS_INLINE_FUNCTION Expr(const int sz, const int i, const T &x)
Constructor with size sz, index i, and value x.
KOKKOS_INLINE_FUNCTION const val_type & dx(int i, int j) const
Returns derivative component i with bounds checking.