33 #ifndef SACADO_ELRCACHEFAD_GENERALFAD_HPP
34 #define SACADO_ELRCACHEFAD_GENERALFAD_HPP
43 namespace ELRCacheFad {
51 template <
typename T,
typename Storage>
86 Storage(sz, x, zero_out) {}
110 template <
typename S>
116 const int sz = x.size();
119 this->
val() = x.val();
124 if (x.hasFastAccess())
125 for(
int i=0;
i<sz; ++
i)
128 for(
int i=0;
i<sz; ++
i)
133 if (x.hasFastAccess()) {
135 FastLocalAccumOp< Expr<S> > op(x);
138 for(op.i=0; op.i<sz; ++op.i) {
154 for(op.i=0; op.i<sz; ++op.i) {
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>
275 const int xsz = x.size();
277 if (xsz != this->size())
278 this->resizeAndZero(xsz);
280 const int sz = this->size();
289 if (Expr<S>::is_linear) {
290 if (x.hasFastAccess())
291 for(
int i=0;
i<sz; ++
i)
294 for(
int i=0;
i<sz; ++
i)
299 if (x.hasFastAccess()) {
301 FastLocalAccumOp< Expr<S> > op(x);
304 for(op.i=0; op.i<sz; ++op.i) {
317 SlowLocalAccumOp< Expr<S> > op(x);
320 for(op.i=0; op.i<sz; ++op.i) {
336 this->
val() = x.val();
349 template <
typename S>
357 template <
typename S>
365 template <
typename S>
368 const int sz = this->size();
370 for (
int i=0;
i<sz; ++
i)
376 template <
typename S>
379 const int sz = this->size();
381 for (
int i=0;
i<sz; ++
i)
389 const int xsz = x.size(), sz = this->size();
391 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
392 if ((xsz != sz) && (xsz != 0) && (sz != 0))
393 throw "Fad Error: Attempt to assign with incompatible sizes";
398 for (
int i=0;
i<sz; ++
i)
402 this->resizeAndZero(xsz);
403 for (
int i=0;
i<xsz; ++
i)
408 this->
val() += x.val();
416 const int xsz = x.size(), sz = this->size();
418 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
419 if ((xsz != sz) && (xsz != 0) && (sz != 0))
420 throw "Fad Error: Attempt to assign with incompatible sizes";
425 for(
int i=0;
i<sz; ++
i)
429 this->resizeAndZero(xsz);
430 for(
int i=0;
i<xsz; ++
i)
435 this->
val() -= x.val();
444 const int xsz = x.size(), sz = this->size();
448 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
449 if ((xsz != sz) && (xsz != 0) && (sz != 0))
450 throw "Fad Error: Attempt to assign with incompatible sizes";
455 for(
int i=0;
i<sz; ++
i)
459 this->resizeAndZero(xsz);
460 for(
int i=0;
i<xsz; ++
i)
466 for (
int i=0;
i<sz; ++
i)
479 const int xsz = x.size(), sz = this->size();
483 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
484 if ((xsz != sz) && (xsz != 0) && (sz != 0))
485 throw "Fad Error: Attempt to assign with incompatible sizes";
490 for(
int i=0;
i<sz; ++
i)
492 ( this->
fastAccessDx(
i)*xval - v*x.fastAccessDx(
i) )/ (xval*xval);
495 this->resizeAndZero(xsz);
496 for(
int i=0;
i<xsz; ++
i)
502 for (
int i=0;
i<sz; ++
i)
513 template <
typename S>
518 const int xsz = x.size(), sz = this->size();
520 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
521 if ((xsz != sz) && (xsz != 0) && (sz != 0))
522 throw "Fad Error: Attempt to assign with incompatible sizes";
525 if (Expr<S>::is_linear) {
528 if (x.hasFastAccess())
529 for (
int i=0;
i<sz; ++
i)
532 for (
int i=0;
i<sz; ++
i)
536 this->resizeAndZero(xsz);
537 if (x.hasFastAccess())
538 for (
int i=0;
i<xsz; ++
i)
541 for (
int i=0;
i<xsz; ++
i)
551 this->resizeAndZero(xsz);
553 if (x.hasFastAccess()) {
555 FastLocalAccumOp< Expr<S> > op(x);
558 for(op.i=0; op.i<xsz; ++op.i) {
571 SlowLocalAccumOp< Expr<S> > op(x);
574 for(op.i=0; op.i<xsz; ++op.i) {
590 this->
val() += x.val();
596 template <
typename S>
601 const int xsz = x.size(), sz = this->size();
603 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
604 if ((xsz != sz) && (xsz != 0) && (sz != 0))
605 throw "Fad Error: Attempt to assign with incompatible sizes";
608 if (Expr<S>::is_linear) {
611 if (x.hasFastAccess())
612 for(
int i=0;
i<sz; ++
i)
615 for (
int i=0;
i<sz; ++
i)
619 this->resizeAndZero(xsz);
620 if (x.hasFastAccess())
621 for(
int i=0;
i<xsz; ++
i)
624 for (
int i=0;
i<xsz; ++
i)
634 this->resizeAndZero(xsz);
636 if (x.hasFastAccess()) {
638 FastLocalAccumOp< Expr<S> > op(x);
641 for(op.i=0; op.i<xsz; ++op.i) {
654 SlowLocalAccumOp< Expr<S> > op(x);
657 for(op.i=0; op.i<xsz; ++op.i) {
673 this->
val() -= x.val();
679 template <
typename S>
684 const int xsz = x.size(), sz = this->size();
688 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
689 if ((xsz != sz) && (xsz != 0) && (sz != 0))
690 throw "Fad Error: Attempt to assign with incompatible sizes";
693 if (Expr<S>::is_linear) {
696 if (x.hasFastAccess())
697 for(
int i=0;
i<sz; ++
i)
700 for (
int i=0;
i<sz; ++
i)
704 this->resizeAndZero(xsz);
705 if (x.hasFastAccess())
706 for(
int i=0;
i<xsz; ++
i)
709 for (
int i=0;
i<xsz; ++
i)
715 for (
int i=0;
i<sz; ++
i)
726 if (x.hasFastAccess()) {
728 FastLocalAccumOp< Expr<S> > op(x);
731 for(op.i=0; op.i<xsz; ++op.i) {
745 SlowLocalAccumOp< Expr<S> > op(x);
748 for(op.i=0; op.i<xsz; ++op.i) {
765 this->resizeAndZero(xsz);
767 if (x.hasFastAccess()) {
769 FastLocalAccumOp< Expr<S> > op(x);
772 for(op.i=0; op.i<xsz; ++op.i) {
785 SlowLocalAccumOp< Expr<S> > op(x);
788 for(op.i=0; op.i<xsz; ++op.i) {
807 for (
int i=0;
i<sz; ++
i)
821 template <
typename S>
826 const int xsz = x.size(), sz = this->size();
830 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
831 if ((xsz != sz) && (xsz != 0) && (sz != 0))
832 throw "Fad Error: Attempt to assign with incompatible sizes";
835 if (Expr<S>::is_linear) {
838 if (x.hasFastAccess())
839 for(
int i=0;
i<sz; ++
i)
842 for (
int i=0;
i<sz; ++
i)
846 this->resizeAndZero(xsz);
847 if (x.hasFastAccess())
848 for(
int i=0;
i<xsz; ++
i)
851 for (
int i=0;
i<xsz; ++
i)
857 for (
int i=0;
i<sz; ++
i)
870 if (x.hasFastAccess()) {
872 FastLocalAccumOp< Expr<S> > op(x);
875 for(op.i=0; op.i<xsz; ++op.i) {
889 SlowLocalAccumOp< Expr<S> > op(x);
892 for(op.i=0; op.i<xsz; ++op.i) {
909 this->resizeAndZero(xsz);
911 if (x.hasFastAccess()) {
913 FastLocalAccumOp< Expr<S> > op(x);
916 for(op.i=0; op.i<xsz; ++op.i) {
929 SlowLocalAccumOp< Expr<S> > op(x);
932 for(op.i=0; op.i<xsz; ++op.i) {
951 for (
int i=0;
i<sz; ++
i)
975 template <
typename ExprT>
976 struct FastLocalAccumOp {
977 typedef typename ExprT::value_type
value_type;
978 static const int N = ExprT::num_args;
984 FastLocalAccumOp(
const ExprT&
x_) : x(x_) {
987 template <
typename ArgT>
989 void operator () (ArgT arg)
const {
991 t += partials[Arg] * x.template getTangent<Arg>(
i);
995 template <
typename ExprT>
999 FastLocalAccumOp<ExprT>(x_) {}
1000 template <
typename ArgT>
1004 if (this->x.template isActive<Arg>())
1005 this->t += this->partials[Arg] * this->x.template getTangent<Arg>(this->
i);
1012 template <
typename T,
typename Storage>
1015 os << x.val() <<
" [";
1017 for (
int i=0;
i< x.size();
i++) {
1018 os <<
" " << x.dx(
i);
1029 #endif // SACADO_ELRCACHEFAD_GENERALFAD_HPP
SACADO_INLINE_FUNCTION bool updateValue() const
Return whether this Fad object has an updated value.
SACADO_INLINE_FUNCTION GeneralFad(const Storage &s)
Constructor with supplied storage s.
#define SACADO_ENABLE_VALUE_CTOR_DECL
RemoveConst< T >::type value_type
Typename of values.
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()
Default constructor.
SACADO_INLINE_FUNCTION void cache() const
Cache 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 SACADO_ENABLE_VALUE_FUNC(GeneralFad &) operator
Assignment operator with constant right-hand-side.
Base template specification for testing equivalence.
SACADO_INLINE_FUNCTION bool isPassive() const
Returns true if derivative array is empty.
SACADO_INLINE_FUNCTION ~GeneralFad()
Destructor.
Wrapper for a generic expression template.
SACADO_INLINE_FUNCTION GeneralFad(const GeneralFad &x)
Copy constructor.
SACADO_INLINE_FUNCTION void operator()(ArgT arg) const
Do not initialize the derivative array.
DerivInit
Enum use to signal whether the derivative array should be initialized in AD object constructors...
SACADO_INLINE_FUNCTION SACADO_ENABLE_EXPR_FUNC(bool) isEqualTo(const Expr< S > &x) const
Returns whether two Fad objects have the same values.
std::ostream & operator<<(std::ostream &os, const GeneralFad< T, Storage > &x)
ScalarType< value_type >::type scalar_type
Typename of scalar's (which may be different from T)
SACADO_INLINE_FUNCTION void setIsConstant(bool is_const)
Set whether variable is constant.
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
SACADO_INLINE_FUNCTION GeneralFad(const Expr< S > &x, SACADO_ENABLE_EXPR_CTOR_DECL)
Copy constructor from any Expression object.
Forward-mode AD class templated on the storage for the derivative array.
SACADO_INLINE_FUNCTION int availableSize() const
Returns number of derivative components that can be stored without reallocation.
SACADO_INLINE_FUNCTION GeneralFad(const S &x, SACADO_ENABLE_VALUE_CTOR_DECL)
Constructor with supplied value x.
Initialize the derivative array.
SACADO_INLINE_FUNCTION bool hasFastAccess() const
Returns true if derivative array is not empty.
SACADO_INLINE_FUNCTION SlowLocalAccumOp(const ExprT &x_)
SACADO_INLINE_FUNCTION GeneralFad(const int sz, const int i, const T &x)
Constructor with size sz, index i, and value x.
#define SACADO_INLINE_FUNCTION
SACADO_INLINE_FUNCTION void diff(const int ith, const int n)
Set GeneralFad object as the ith independent variable.