Exemplo n.º 1
0
inline Sacado::ELRFad::Expr< Sacado::ELRFad::SFadExprTag<T,Num> >& 
Sacado::ELRFad::Expr< Sacado::ELRFad::SFadExprTag<T,Num> >::
operator -= (const Sacado::ELRFad::Expr<S>& x)
{
#ifdef SACADO_DEBUG
  if (x.size() != Num)
    throw "SELRFad::operator-=() Error:  Attempt to assign with incompatible sizes";
#endif

  // Number of arguments
  const int N = Expr<S>::num_args;

  // Compute partials
  LocalAccumOp< Expr<S> > op(x);

  // Compute each tangent direction
  for(int i=0; i<Num; ++i) {
    op.t = T(0.);
    op.i = i;
	
    // Automatically unrolled loop that computes
    // for (int j=0; j<N; j++)
    //   op.t += op.partials[j] * x.getTangent<j>(i);
    Sacado::mpl::for_each< mpl::range_c< int, 0, N > > f(op);
	
    dx_[i] -= op.t;
  }

  // Compute value
  update_val_ = x.updateValue();
  if (update_val_)
    val_ -= x.val();

  return *this;
}
inline Sacado::ELRFad::GeneralFad<T,Storage>& 
Sacado::ELRFad::GeneralFad<T,Storage>::operator /= (
					     const Sacado::ELRFad::Expr<S>& x)
{
  int xsz = x.size(), sz = this->size();
  T xval = x.val();
  T v = this->val();

#ifdef SACADO_DEBUG
  if ((xsz != sz) && (xsz != 0) && (sz != 0))
    throw "Fad Error:  Attempt to assign with incompatible sizes";
#endif

  if (Expr<S>::is_linear) {
    if (xsz) {
      if (sz) {
	if (x.hasFastAccess())
	  for(int i=0; i<sz; ++i)
	    this->fastAccessDx(i) = ( this->fastAccessDx(i)*xval - v*x.fastAccessDx(i) )/ (xval*xval);
	else
	  for (int i=0; i<sz; ++i)
	    this->fastAccessDx(i) = ( this->fastAccessDx(i)*xval - v*x.dx(i) )/ (xval*xval);
      }
      else {
	this->resize(xsz);
	if (x.hasFastAccess())
	  for(int i=0; i<xsz; ++i)
	    this->fastAccessDx(i) = - v*x.fastAccessDx(i) / (xval*xval);
	else
	  for (int i=0; i<xsz; ++i)
	    this->fastAccessDx(i) = -v*x.dx(i) / (xval*xval);
      }
    }
    else {
      if (sz) {
	for (int i=0; i<sz; ++i)
	  this->fastAccessDx(i) /= xval;
      }
    }
  }
  else {
    // Number of arguments
    const int N = Expr<S>::num_args;
    
    if (xsz) {
      
      T xval2 = xval*xval;
      
      if (sz) {

	if (x.hasFastAccess()) {
	  // Compute partials
	  FastLocalAccumOp< Expr<S> > op(x);
	  
	  // Compute each tangent direction
	  for(op.i=0; op.i<xsz; ++op.i) {
	    op.t = T(0.);
	    
	    // Automatically unrolled loop that computes
	    // for (int j=0; j<N; j++)
	    //   op.t += op.partials[j] * x.getTangent<j>(i);
	    Sacado::mpl::for_each< mpl::range_c< int, 0, N > > f(op);
	  
	    this->fastAccessDx(op.i) = 
	      (this->fastAccessDx(op.i) * xval - v * op.t) / xval2;
	  }
	}
	else {
	  // Compute partials
	  SlowLocalAccumOp< Expr<S> > op(x);
	  
	  // Compute each tangent direction
	  for(op.i=0; op.i<xsz; ++op.i) {
	    op.t = T(0.);
	    
	    // Automatically unrolled loop that computes
	    // for (int j=0; j<N; j++)
	    //   op.t += op.partials[j] * x.getTangent<j>(i);
	    Sacado::mpl::for_each< mpl::range_c< int, 0, N > > f(op);
	  
	    this->fastAccessDx(op.i) = 
	      (this->fastAccessDx(op.i) * xval - v * op.t) / xval2;
	  }
	}
	
      }
      
      else {
	
	this->resize(xsz);
	
	if (x.hasFastAccess()) {
	  // Compute partials
	  FastLocalAccumOp< Expr<S> > op(x);
	  
	  // Compute each tangent direction
	  for(op.i=0; op.i<xsz; ++op.i) {
	    op.t = T(0.);
	    
	    // Automatically unrolled loop that computes
	    // for (int j=0; j<N; j++)
	    //   op.t += op.partials[j] * x.getTangent<j>(i);
	    Sacado::mpl::for_each< mpl::range_c< int, 0, N > > f(op);
	  
	    this->fastAccessDx(op.i) = (-v * op.t) / xval2;
	  }
	}
	else {
	  // Compute partials
	  SlowLocalAccumOp< Expr<S> > op(x);
	  
	  // Compute each tangent direction
	  for(op.i=0; op.i<xsz; ++op.i) {
	    op.t = T(0.);
	    
	    // Automatically unrolled loop that computes
	    // for (int j=0; j<N; j++)
	    //   op.t += op.partials[j] * x.getTangent<j>(i);
	    Sacado::mpl::for_each< mpl::range_c< int, 0, N > > f(op);
	  
	    this->fastAccessDx(op.i) = (-v * op.t) / xval2;
	  }
	}
	
      }
      
    }
    
    else {
      
      if (sz) {
	for (int i=0; i<sz; ++i)
	  this->fastAccessDx(i) /= xval;
      }
      
    }

  }

  update_val_ = x.updateValue();
  if (update_val_)
    this->val() /= xval;

  return *this;
}