33 #ifndef SACADO_ELRFAD_GENERALFAD_HPP
34 #define SACADO_ELRFAD_GENERALFAD_HPP
53 template <
typename T,
typename Storage>
88 Storage(sz, x, zero_out) {}
112 template <
typename S>
116 const int sz = x.size();
120 if (x.hasFastAccess())
121 for(
int i=0;
i<sz; ++
i)
124 for(
int i=0;
i<sz; ++
i)
129 if (x.hasFastAccess()) {
131 FastLocalAccumOp< Expr<S> > op(x);
134 for(op.i=0; op.i<sz; ++op.i) {
150 for(op.i=0; op.i<sz; ++op.i) {
167 this->
val() = x.val();
182 void diff(
const int ith,
const int n) {
183 if (this->size() != n)
204 template <
typename S>
208 if (x.size() != this->size())
return false;
209 bool eq = IE::eval(x.val(), this->
val());
210 for (
int i=0;
i<this->size();
i++)
211 eq = eq && IE::eval(x.dx(
i), this->
dx(
i));
240 if (is_const && this->size()!=0)
252 template <
typename S>
256 if (this->size()) this->resize(0);
265 Storage::operator=(x);
270 template <
typename S>
273 const int xsz = x.size();
274 if (xsz != this->size())
275 this->resizeAndZero(xsz);
277 const int sz = this->size();
286 if (Expr<S>::is_linear) {
287 if (x.hasFastAccess())
288 for(
int i=0;
i<sz; ++
i)
291 for(
int i=0;
i<sz; ++
i)
296 if (x.hasFastAccess()) {
298 FastLocalAccumOp< Expr<S> > op(x);
301 for(op.i=0; op.i<sz; ++op.i) {
314 SlowLocalAccumOp< Expr<S> > op(x);
317 for(op.i=0; op.i<sz; ++op.i) {
332 this->
val() = x.val();
345 template <
typename S>
353 template <
typename S>
361 template <
typename S>
364 const int sz = this->size();
366 for (
int i=0;
i<sz; ++
i)
372 template <
typename S>
375 const int sz = this->size();
377 for (
int i=0;
i<sz; ++
i)
385 const int xsz = x.size(), sz = this->size();
387 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
388 if ((xsz != sz) && (xsz != 0) && (sz != 0))
389 throw "Fad Error: Attempt to assign with incompatible sizes";
394 for (
int i=0;
i<sz; ++
i)
398 this->resizeAndZero(xsz);
399 for (
int i=0;
i<xsz; ++
i)
404 this->
val() += x.val();
412 const int xsz = x.size(), sz = this->size();
414 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
415 if ((xsz != sz) && (xsz != 0) && (sz != 0))
416 throw "Fad Error: Attempt to assign with incompatible sizes";
421 for(
int i=0;
i<sz; ++
i)
425 this->resizeAndZero(xsz);
426 for(
int i=0;
i<xsz; ++
i)
431 this->
val() -= x.val();
440 const int xsz = x.size(), sz = this->size();
444 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
445 if ((xsz != sz) && (xsz != 0) && (sz != 0))
446 throw "Fad Error: Attempt to assign with incompatible sizes";
451 for(
int i=0;
i<sz; ++
i)
455 this->resizeAndZero(xsz);
456 for(
int i=0;
i<xsz; ++
i)
462 for (
int i=0;
i<sz; ++
i)
475 const int xsz = x.size(), sz = this->size();
479 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
480 if ((xsz != sz) && (xsz != 0) && (sz != 0))
481 throw "Fad Error: Attempt to assign with incompatible sizes";
486 for(
int i=0;
i<sz; ++
i)
488 ( this->
fastAccessDx(
i)*xval - v*x.fastAccessDx(
i) )/ (xval*xval);
491 this->resizeAndZero(xsz);
492 for(
int i=0;
i<xsz; ++
i)
498 for (
int i=0;
i<sz; ++
i)
509 template <
typename S>
512 const int xsz = x.size(), sz = this->size();
514 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
515 if ((xsz != sz) && (xsz != 0) && (sz != 0))
516 throw "Fad Error: Attempt to assign with incompatible sizes";
519 if (Expr<S>::is_linear) {
522 if (x.hasFastAccess())
523 for (
int i=0;
i<sz; ++
i)
526 for (
int i=0;
i<sz; ++
i)
530 this->resizeAndZero(xsz);
531 if (x.hasFastAccess())
532 for (
int i=0;
i<xsz; ++
i)
535 for (
int i=0;
i<xsz; ++
i)
545 this->resizeAndZero(xsz);
547 if (x.hasFastAccess()) {
549 FastLocalAccumOp< Expr<S> > op(x);
552 for(op.i=0; op.i<xsz; ++op.i) {
565 SlowLocalAccumOp< Expr<S> > op(x);
568 for(op.i=0; op.i<xsz; ++op.i) {
585 this->
val() += x.val();
591 template <
typename S>
594 const int xsz = x.size(), sz = this->size();
596 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
597 if ((xsz != sz) && (xsz != 0) && (sz != 0))
598 throw "Fad Error: Attempt to assign with incompatible sizes";
601 if (Expr<S>::is_linear) {
604 if (x.hasFastAccess())
605 for(
int i=0;
i<sz; ++
i)
608 for (
int i=0;
i<sz; ++
i)
612 this->resizeAndZero(xsz);
613 if (x.hasFastAccess())
614 for(
int i=0;
i<xsz; ++
i)
617 for (
int i=0;
i<xsz; ++
i)
627 this->resizeAndZero(xsz);
629 if (x.hasFastAccess()) {
631 FastLocalAccumOp< Expr<S> > op(x);
634 for(op.i=0; op.i<xsz; ++op.i) {
647 SlowLocalAccumOp< Expr<S> > op(x);
650 for(op.i=0; op.i<xsz; ++op.i) {
665 this->
val() -= x.val();
671 template <
typename S>
674 const int xsz = x.size(), sz = this->size();
678 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
679 if ((xsz != sz) && (xsz != 0) && (sz != 0))
680 throw "Fad Error: Attempt to assign with incompatible sizes";
683 if (Expr<S>::is_linear) {
686 if (x.hasFastAccess())
687 for(
int i=0;
i<sz; ++
i)
690 for (
int i=0;
i<sz; ++
i)
694 this->resizeAndZero(xsz);
695 if (x.hasFastAccess())
696 for(
int i=0;
i<xsz; ++
i)
699 for (
int i=0;
i<xsz; ++
i)
705 for (
int i=0;
i<sz; ++
i)
716 if (x.hasFastAccess()) {
718 FastLocalAccumOp< Expr<S> > op(x);
721 for(op.i=0; op.i<xsz; ++op.i) {
735 SlowLocalAccumOp< Expr<S> > op(x);
738 for(op.i=0; op.i<xsz; ++op.i) {
755 this->resizeAndZero(xsz);
757 if (x.hasFastAccess()) {
759 FastLocalAccumOp< Expr<S> > op(x);
762 for(op.i=0; op.i<xsz; ++op.i) {
775 SlowLocalAccumOp< Expr<S> > op(x);
778 for(op.i=0; op.i<xsz; ++op.i) {
797 for (
int i=0;
i<sz; ++
i)
811 template <
typename S>
814 const int xsz = x.size(), sz = this->size();
818 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
819 if ((xsz != sz) && (xsz != 0) && (sz != 0))
820 throw "Fad Error: Attempt to assign with incompatible sizes";
823 if (Expr<S>::is_linear) {
826 if (x.hasFastAccess())
827 for(
int i=0;
i<sz; ++
i)
830 for (
int i=0;
i<sz; ++
i)
834 this->resizeAndZero(xsz);
835 if (x.hasFastAccess())
836 for(
int i=0;
i<xsz; ++
i)
839 for (
int i=0;
i<xsz; ++
i)
845 for (
int i=0;
i<sz; ++
i)
858 if (x.hasFastAccess()) {
860 FastLocalAccumOp< Expr<S> > op(x);
863 for(op.i=0; op.i<xsz; ++op.i) {
877 SlowLocalAccumOp< Expr<S> > op(x);
880 for(op.i=0; op.i<xsz; ++op.i) {
897 this->resizeAndZero(xsz);
899 if (x.hasFastAccess()) {
901 FastLocalAccumOp< Expr<S> > op(x);
904 for(op.i=0; op.i<xsz; ++op.i) {
917 SlowLocalAccumOp< Expr<S> > op(x);
920 for(op.i=0; op.i<xsz; ++op.i) {
939 for (
int i=0;
i<sz; ++
i)
963 template <
typename ExprT>
964 struct FastLocalAccumOp {
965 typedef typename ExprT::value_type
value_type;
966 static const int N = ExprT::num_args;
972 FastLocalAccumOp(
const ExprT&
x_) : x(x_) {
975 template <
typename ArgT>
977 void operator () (ArgT arg)
const {
979 t += partials[Arg] * x.template getTangent<Arg>(
i);
983 template <
typename ExprT>
987 FastLocalAccumOp<ExprT>(x_) {}
988 template <
typename ArgT>
992 if (this->x.template isActive<Arg>())
993 this->t += this->partials[Arg] * this->x.template getTangent<Arg>(this->
i);
1000 template <
typename T,
typename Storage>
1003 os << x.val() <<
" [";
1005 for (
int i=0;
i< x.size();
i++) {
1006 os <<
" " << x.dx(
i);
1017 #endif // SACADO_ELRFAD_GENERALFAD_HPP
RemoveConst< T >::type value_type
Typename of values.
SACADO_INLINE_FUNCTION bool updateValue() const
Return whether this Fad object has an updated value.
SACADO_INLINE_FUNCTION SlowLocalAccumOp(const ExprT &x_)
SACADO_INLINE_FUNCTION ~GeneralFad()
Destructor.
SACADO_INLINE_FUNCTION GeneralFad(const Storage &s)
Constructor with supplied storage s.
#define SACADO_ENABLE_VALUE_CTOR_DECL
SACADO_INLINE_FUNCTION void setUpdateValue(bool update_val)
Set whether this Fad object should update values.
#define SACADO_ENABLE_EXPR_CTOR_DECL
SACADO_INLINE_FUNCTION GeneralFad(const Expr< S > &x, SACADO_ENABLE_EXPR_CTOR_DECL)
Copy constructor from any Expression object.
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 SACADO_ENABLE_VALUE_FUNC(GeneralFad &) operator
Assignment operator with constant right-hand-side.
SACADO_INLINE_FUNCTION void setIsConstant(bool is_const)
Set whether variable is constant.
SACADO_INLINE_FUNCTION GeneralFad(const int sz, const int i, const T &x)
Constructor with size sz, index i, and value x.
SACADO_INLINE_FUNCTION GeneralFad(const GeneralFad &x)
Copy constructor.
Base template specification for testing equivalence.
SACADO_INLINE_FUNCTION bool hasFastAccess() const
Returns true if derivative array is not empty.
Do not initialize the derivative array.
std::ostream & operator<<(std::ostream &os, const GeneralFad< T, Storage > &x)
SACADO_INLINE_FUNCTION bool isPassive() const
Returns true if derivative array is empty.
SACADO_INLINE_FUNCTION void diff(const int ith, const int n)
Set GeneralFad object as the ith independent variable.
SACADO_INLINE_FUNCTION void cache() const
Cache values.
DerivInit
Enum use to signal whether the derivative array should be initialized in AD object constructors...
Forward-mode AD class templated on the storage for the derivative array.
Wrapper for a generic expression template.
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.
Initialize the derivative array.
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 int availableSize() const
Returns number of derivative components that can be stored without reallocation.
#define SACADO_INLINE_FUNCTION
SACADO_INLINE_FUNCTION GeneralFad()
Default constructor.
ScalarType< value_type >::type scalar_type
Typename of scalar's (which may be different from T)
SACADO_INLINE_FUNCTION void operator()(ArgT arg) const