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 //
4 // Sacado Package
5 // Copyright (2006) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // This library is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as
12 // published by the Free Software Foundation; either version 2.1 of the
13 // License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 // USA
24 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
25 // (etphipp@sandia.gov).
26 //
27 // ***********************************************************************
28 //
29 // The forward-mode AD classes in Sacado are a derivative work of the
30 // expression template classes in the Fad package by Nicolas Di Cesare.
31 // The following banner is included in the original Fad source code:
32 //
33 // ************ DO NOT REMOVE THIS BANNER ****************
34 //
35 // Nicolas Di Cesare <Nicolas.Dicesare@ann.jussieu.fr>
36 // http://www.ann.jussieu.fr/~dicesare
37 //
38 // CEMRACS 98 : C++ courses,
39 // templates : new C++ techniques
40 // for scientific computing
41 //
42 //********************************************************
43 //
44 // A short implementation ( not all operators and
45 // functions are overloaded ) of 1st order Automatic
46 // Differentiation in forward mode (FAD) using
47 // EXPRESSION TEMPLATES.
48 //
49 //********************************************************
50 // @HEADER
51 
52 #ifndef SACADO_FAD_SFAD_MP_VECTOR_HPP
53 #define SACADO_FAD_SFAD_MP_VECTOR_HPP
54 
55 #include "Sacado_Fad_SFad.hpp"
57 
58 namespace Stokhos {
59  template <typename Ord, typename Val, int Num, typename Dev>
60  class StaticFixedStorage;
61 }
62 
63 namespace Sacado {
64 
65  namespace MP {
66  template <typename S> class Vector;
67  }
68 
69  namespace Fad {
70 
71  template <typename Ord, typename Val, int VecNum, typename Dev, int Num>
72  struct ExprSpec< SFadExprTag< Sacado::MP::Vector< Stokhos::StaticFixedStorage<Ord,Val,VecNum,Dev> >, Num > > {
74  };
75  template <typename Ord, typename Val, int VecNum, typename Dev, int Num>
76  struct ExprSpec< SFad< Sacado::MP::Vector< Stokhos::StaticFixedStorage<Ord,Val,VecNum,Dev> >, Num > > {
78  };
79 
87  template <typename Ord, typename Val, int VecNum, typename Dev, int Num>
88  class Expr< SFadExprTag< Sacado::MP::Vector< Stokhos::StaticFixedStorage<Ord,Val,VecNum,Dev> >,Num >,ExprSpecMPVector > {
89 
90  public:
91 
93 
95  typedef typename RemoveConst<T>::type value_type;
96 
98  typedef typename ScalarType<value_type>::type scalar_type;
99 
101  typedef SFad<value_type,Num> base_expr_type;
102 
104 
109 
111  KOKKOS_INLINE_FUNCTION
112  Expr() : val_( T(0.)) {
113  ss_array<T>::zero(dx_, Num); }
114 
116 
119  template <typename S>
120  KOKKOS_INLINE_FUNCTION
121  Expr(const S & x, SACADO_ENABLE_VALUE_CTOR_DECL) :
122  val_(x) {
123  ss_array<T>::zero(dx_, Num);
124  }
125 
127 
130  KOKKOS_INLINE_FUNCTION
131  Expr(const int sz, const T & x, const DerivInit zero_out = InitDerivArray) : val_(x) {
132 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
133  if (sz != Num)
134  throw "SFad::SFad() Error: Supplied derivative dimension does not match compile time length.";
135 #endif
136  if (zero_out == InitDerivArray)
137  ss_array<T>::zero(dx_, Num);
138  }
139 
141 
146  KOKKOS_INLINE_FUNCTION
147  Expr(const int sz, const int i, const T & x) :
148  val_(x) {
149 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
150  if (sz != Num)
151  throw "SFad::SFad() Error: Supplied derivative dimension does not match compile time length.";
152  if (i >= Num)
153  throw "SFad::SFad() Error: Invalid derivative index.";
154 #endif
155 
156  ss_array<T>::zero(dx_, Num);
157  dx_[i]=1.;
158  }
159 
161  KOKKOS_INLINE_FUNCTION
162  Expr(const Expr& x) :
163  val_(x.val()) {
164  for (int i=0; i<Num; i++)
165  dx_[i] = x.dx_[i];
166  }
167 
169  template <typename S>
170  KOKKOS_INLINE_FUNCTION
171  Expr(const Expr<S>& x, SACADO_ENABLE_EXPR_CTOR_DECL) {
172 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
173  if (x.size() != Num)
174  throw "SFad::SFad() Error: Attempt to assign with incompatible sizes";
175 #endif
176 
177  for(int i=0; i<Num; ++i) {
178  for (int j=0; j<VecNum; ++j)
179  dx_[i].fastAccessCoeff(j) = x.fastAccessDx(i,j);
180  }
181 
182  for (int j=0; j<VecNum; ++j)
183  this->val(j) = x.val(j);
184  }
185 
187  KOKKOS_INLINE_FUNCTION
188  ~Expr() {}
189 
191 
197  KOKKOS_INLINE_FUNCTION
198  void diff(const int ith, const int n) {
199 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
200  if (n != Num)
201  throw "SFad::diff() Error: Supplied derivative dimension does not match compile time length.";
202 #endif
203 
204  ss_array<T>::zero(dx_, Num);
205  dx_[ith] = T(1.);
206  }
207 
209 
213  KOKKOS_INLINE_FUNCTION
214  void resize(int sz) {
215 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
216  if (sz != Num)
217  throw "SFad::resize() Error: Cannot resize fixed derivative array dimension";
218 #endif
219  }
220 
222 
226  KOKKOS_INLINE_FUNCTION
227  void expand(int sz) { resize(sz); }
228 
230  KOKKOS_INLINE_FUNCTION
231  void zero() { ss_array<T>::zero(dx_, Num); }
232 
234  KOKKOS_INLINE_FUNCTION
235  void setUpdateValue(bool update_val) { }
236 
238  KOKKOS_INLINE_FUNCTION
239  bool updateValue() const { return true; }
240 
242  template <typename S>
243  KOKKOS_INLINE_FUNCTION
244  SACADO_ENABLE_EXPR_FUNC(bool) isEqualTo(const Expr<S>& x) const {
245  typedef IsEqual<value_type> IE;
246  if (x.size() != this->size()) return false;
247  bool eq = IE::eval(x.val(), this->val());
248  for (int i=0; i<this->size(); i++)
249  eq = eq && IE::eval(x.dx(i), this->dx(i));
250  return eq;
251  }
252 
254 
259 
261  KOKKOS_INLINE_FUNCTION
262  const T& val() const { return val_;}
263 
265  KOKKOS_INLINE_FUNCTION
266  T& val() { return val_;}
267 
269  KOKKOS_INLINE_FUNCTION
270  const val_type& val(int j) const { return val_.fastAccessCoeff(j);}
271 
273  KOKKOS_INLINE_FUNCTION
274  val_type& val(int j) { return val_.fastAccessCoeff(j);}
275 
277 
282 
284  KOKKOS_INLINE_FUNCTION
285  int size() const { return Num;}
286 
291  KOKKOS_INLINE_FUNCTION
292  int availableSize() const { return Num; }
293 
295  KOKKOS_INLINE_FUNCTION
296  bool hasFastAccess() const { return true; }
297 
299  KOKKOS_INLINE_FUNCTION
300  bool isPassive() const { return false; }
301 
303  KOKKOS_INLINE_FUNCTION
304  void setIsConstant(bool is_const) {}
305 
307  KOKKOS_INLINE_FUNCTION
308  const T* dx() const { return &(dx_[0]);}
309 
311  KOKKOS_INLINE_FUNCTION
312  const T& dx(int i) const { return dx_[i]; }
313 
315  KOKKOS_INLINE_FUNCTION
316  T& fastAccessDx(int i) { return dx_[i];}
317 
319  KOKKOS_INLINE_FUNCTION
320  const T& fastAccessDx(int i) const { return dx_[i];}
321 
323  KOKKOS_INLINE_FUNCTION
324  const val_type& dx(int i, int j) const { return dx_[i].fastAccessCoeff(j); }
325 
327  KOKKOS_INLINE_FUNCTION
328  val_type& fastAccessDx(int i, int j) { return dx_[i].fastAccessCoeff(j);}
329 
331  KOKKOS_INLINE_FUNCTION
332  const val_type& fastAccessDx(int i, int j) const { return dx_[i].fastAccessCoeff(j);}
333 
335 
340 
342  template <typename S>
343  KOKKOS_INLINE_FUNCTION
344  SACADO_ENABLE_VALUE_FUNC(Expr&) operator=(const S& v) {
345  val_ = v;
346  ss_array<T>::zero(dx_, Num);
347  return *this;
348  }
349 
351  KOKKOS_INLINE_FUNCTION
352  Expr& operator=(const Expr& x) {
353  if (this != &x) {
354  // Copy value
355  val_ = x.val_;
356 
357  // Copy dx_
358  for (int i=0; i<Num; i++)
359  dx_[i] = x.dx_[i];
360  }
361  return *this;
362  }
363 
365  template <typename S>
366  KOKKOS_INLINE_FUNCTION
367  SACADO_ENABLE_EXPR_FUNC(Expr&) operator=(const Expr<S>& x) {
368 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
369  if (x.size() != Num)
370  throw "SFad::operator=() Error: Attempt to assign with incompatible sizes";
371 #endif
372 
373  for(int i=0; i<Num; ++i) {
374  for (int j=0; j<VecNum; ++j)
375  dx_[i].fastAccessCoeff(j) = x.fastAccessDx(i,j);
376  }
377 
378  for (int j=0; j<VecNum; ++j)
379  this->val(j) = x.val(j);
380 
381  return *this;
382  }
383 
385 
390 
392  template <typename S>
393  KOKKOS_INLINE_FUNCTION
394  SACADO_ENABLE_VALUE_FUNC(Expr&) operator += (const S& v) {
395  this->val() += v;
396  return *this;
397  }
398 
400  template <typename S>
401  KOKKOS_INLINE_FUNCTION
402  SACADO_ENABLE_VALUE_FUNC(Expr&) operator -= (const S& v) {
403  this->val() -= v;
404  return *this;
405  }
406 
408  template <typename S>
409  KOKKOS_INLINE_FUNCTION
410  SACADO_ENABLE_VALUE_FUNC(Expr&) operator *= (const S& v) {
411  this->val() *= v;
412  for (int i=0; i<Num; ++i)
413  dx_[i] *= v;
414  return *this;
415  }
416 
418  template <typename S>
419  KOKKOS_INLINE_FUNCTION
420  SACADO_ENABLE_VALUE_FUNC(Expr&) operator /= (const S& v) {
421  this->val() /= v;
422  for (int i=0; i<Num; ++i)
423  dx_[i] /= v;
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 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
452  if (x.size() != Num)
453  throw "SFad::operator-=() Error: Attempt to assign with incompatible sizes";
454 #endif
455 
456  for(int i=0; i<Num; ++i) {
457  for (int j=0; j<VecNum; ++j)
458  dx_[i].fastAccessCoeff(j) -= x.fastAccessDx(i,j);
459  }
460 
461  for (int j=0; j<VecNum; ++j)
462  this->val(j) -= x.val(j);
463 
464  return *this;
465  }
466 
468  template <typename S>
469  KOKKOS_INLINE_FUNCTION
470  SACADO_ENABLE_EXPR_FUNC(Expr&) operator *= (const Expr<S>& x) {
471  T xval;
472  for (int j=0; j<VecNum; ++j)
473  xval.fastAccessCoeff(j) = x.val(j);
474 
475 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
476  if (x.size() != Num)
477  throw "SFad::operator*=() Error: Attempt to assign with incompatible sizes";
478 #endif
479 
480  for(int i=0; i<Num; ++i)
481  for (int j=0; j<VecNum; ++j)
482  dx_[i].fastAccessCoeff(j) = val_.fastAccessCoeff(j) * x.fastAccessDx(i,j) + dx_[i] * xval.fastAccessCoeff(j);
483 
484  val_ *= xval;
485 
486  return *this;
487  }
488 
490  template <typename S>
491  KOKKOS_INLINE_FUNCTION
492  SACADO_ENABLE_EXPR_FUNC(Expr&) operator /= (const Expr<S>& x) {
493  T xval;
494  for (int j=0; j<VecNum; ++j)
495  xval.fastAccessCoeff(j) = x.val(j);
496  T xval2 = xval*xval;
497 
498 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
499  if (x.size() != Num)
500  throw "SFad::operator/=() Error: Attempt to assign with incompatible sizes";
501 #endif
502 
503  for(int i=0; i<Num; ++i)
504  for (int j=0; j<VecNum; ++j)
505  dx_[i].fastAccessCoeff(j) = ( dx_[i].fastAccessCoeff(j)*xval.fastAccessCoeff(j) - val_.fastAccessCoeff(j)*x.fastAccessDx(i,j) )/ (xval2.fastAccessCoeff(j));
506 
507  val_ /= xval;
508 
509  return *this;
510  }
511 
513 
514  protected:
515 
517  T dx_[Num];
518 
521 
522  }; // class Expr<SFadExprTag>
523 
524  } // namespace Fad
525 
526 } // namespace Sacado
527 
529 
530 #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.