/* Example programs from the book Scientific and Engineering Programming in C++: An Introduction with Advanced Techniques and Examples, Addison-Wesley, 1994. (c) COPYRIGHT INTERNATIONAL BUSINESS MACHINES CORPORATION 1994. ALL RIGHTS RESERVED. See README file for further details. */ #include "SciEng/utils.h" template Rall1d:: Rall1d(const T& c, Subscript nvars) : t(c), grad(nvars) { grad = T(0.); } template Rall1d:: Rall1d(const Rall1d& r): t(r.value()), grad(r.gradient()) { } template Rall1d:: Rall1d(const T& tn, const V& vn): t(tn), grad(vn) { } template Rall1d& Rall1d:: operator=(const T& c){ t = c; grad = T(0.0); return *this; } template Rall1d& Rall1d:: operator=(const Rall1d& r){ t = r.t; grad = r.grad; return *this; } template Rall1d::Rall1d(const T& v, Subscript i_th, Subscript nvars) : t(v), grad(nvars) { make_unit(i_th); } template void Rall1d::make_unit(Subscript i_th) { if (i_th < grad.shape(0)) { grad = T(0.0); // T() forces op=(const T&), not copy of V(Subscript); grad(i_th) = 1.0; } else throw RallInvalidUnitErr(); } template Rall1d& Rall1d:: operator*=(const Rall1d& rhs){ // f(x,y,z) = g(x,y,z)*h(x,y,z); df/dx = h*dg/dx+g*dh/dx grad = grad * rhs.value() + value() * rhs.grad; value() *= rhs.value(); return *this; } template Rall1d& Rall1d:: setToOne(){ value() = 1.0; grad.setToZero(); return *this; } template Rall1d& Rall1d:: operator/=(const Rall1d& rhs) { T rhs_val = rhs.value(); if (rhs_val == T(0.)) throw RallDivideZeroErr(); grad = (grad * rhs_val - value() * rhs.grad) / sqr(rhs_val); t /= rhs_val; return *this; } template Rall1d& Rall1d:: operator+=(const Rall1d& rhs){ grad += rhs.grad; value() += rhs.value(); return *this; } template Rall1d& Rall1d:: operator-=(const Rall1d& rhs){ grad -= rhs.grad; value() -= rhs.value(); return *this; } template Rall1d& Rall1d:: setToZero(){ grad.setToZero(); value() = 0; return *this; } template Rall1d& Rall1d::operator*=(const T& s) { grad *= s; value() *= s; return *this; } template Rall1d& Rall1d::operator/=(const T& s) { grad/=(s); value() /= s; return *this; } template Rall1d exp(const Rall1d& rhs){ Rall1d tmp(::exp(rhs.value()), rhs.grad); tmp.grad *= tmp.value(); return tmp; } template Rall1d sin(const Rall1d& rhs){ Rall1d tmp(::sin(rhs.value()), rhs.grad); tmp.grad *= ::cos( rhs.value() ); return tmp; } template Rall1d cos(const Rall1d& rhs){ Rall1d tmp(::cos(rhs.value()), rhs.grad); tmp.grad *= (-1.0)*::sin( rhs.value() ); return tmp; } template Rall1d asin(const Rall1d& rhs) { T val = rhs.value(); Rall1d tmp(::asin(val), rhs.grad); tmp.grad *= T(1)/(::sqrt(T(1.0) - sqr(val))); return tmp; } template Rall1d acos(const Rall1d& rhs){ T val = rhs.value(); Rall1d tmp(::acos(val), rhs.grad); tmp.grad *= -T(1)/(::sqrt(T(1.0) - sqr(val))); return tmp; } template Rall1d sqrt(const Rall1d& rhs){ Rall1d tmp(::sqrt(rhs.value()), rhs.grad); tmp.grad /= T(2.0)*tmp.value(); return tmp; } template Rall1d log(const Rall1d& rhs){ Rall1d tmp(::log(rhs.value()), rhs.grad); tmp.grad /= rhs.value(); return tmp; } template Rall1d log10(const Rall1d& rhs){ Rall1d tmp(::log10(rhs.value()), rhs.grad); tmp.grad /= rhs.value(); return tmp; } template ostream& operator<<(ostream& os, const Rall1d& r){ const T& v = r.value(); return os << "(" << v << "," << r.gradient() << ")"; } template Boolean Rall1d::equivalentTo(const Rall1d& rhs) const { return ( value() == rhs.value() ) && ( gradient() == rhs.gradient() ); } #include "AutoDeriv/TaylorCoefficient1d.h" template TaylorCoefficient1d reform(const Rall1d& r) { Subscript n = r.gradient().numElts(); TaylorCoefficient1d tmp(r.value(), n); while(n--) tmp(n) = r.gradient()(n); return tmp; }