|
Sacado Package Browser (Single Doxygen Collection) Version of the Day
|
00001 // $Id$ 00002 // $Source$ 00003 // @HEADER 00004 // *********************************************************************** 00005 // 00006 // Sacado Package 00007 // Copyright (2006) Sandia Corporation 00008 // 00009 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00010 // the U.S. Government retains certain rights in this software. 00011 // 00012 // This library is free software; you can redistribute it and/or modify 00013 // it under the terms of the GNU Lesser General Public License as 00014 // published by the Free Software Foundation; either version 2.1 of the 00015 // License, or (at your option) any later version. 00016 // 00017 // This library is distributed in the hope that it will be useful, but 00018 // WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00020 // Lesser General Public License for more details. 00021 // 00022 // You should have received a copy of the GNU Lesser General Public 00023 // License along with this library; if not, write to the Free Software 00024 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00025 // USA 00026 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps 00027 // (etphipp@sandia.gov). 00028 // 00029 // *********************************************************************** 00030 // 00031 // The forward-mode AD classes in Sacado are a derivative work of the 00032 // expression template classes in the Fad package by Nicolas Di Cesare. 00033 // The following banner is included in the original Fad source code: 00034 // 00035 // ************ DO NOT REMOVE THIS BANNER **************** 00036 // 00037 // Nicolas Di Cesare <Nicolas.Dicesare@ann.jussieu.fr> 00038 // http://www.ann.jussieu.fr/~dicesare 00039 // 00040 // CEMRACS 98 : C++ courses, 00041 // templates : new C++ techniques 00042 // for scientific computing 00043 // 00044 //******************************************************** 00045 // 00046 // A short implementation ( not all operators and 00047 // functions are overloaded ) of 1st order Automatic 00048 // Differentiation in forward mode (FAD) using 00049 // EXPRESSION TEMPLATES. 00050 // 00051 //******************************************************** 00052 // @HEADER 00053 00054 #include "Sacado_ConfigDefs.h" 00055 00056 template <typename T, int Num> 00057 inline Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00058 Expr(const int sz, const T & x) : val_(x), update_val_(true) 00059 { 00060 #ifdef SACADO_DEBUG 00061 if (sz != Num) 00062 throw "SFad::SFad() Error: Supplied derivative dimension does not match compile time length."; 00063 #endif 00064 00065 ss_array<T>::zero(dx_, Num); 00066 } 00067 00068 template <typename T, int Num> 00069 inline Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00070 Expr(const int sz, const int i, const T & x) : val_(x), update_val_(true) 00071 { 00072 #ifdef SACADO_DEBUG 00073 if (sz != Num) 00074 throw "SFad::SFad() Error: Supplied derivative dimension does not match compile time length."; 00075 if (i >= Num) 00076 throw "SFad::SFad() Error: Invalid derivative index."; 00077 #endif 00078 00079 ss_array<T>::zero(dx_, Num); 00080 dx_[i]=1.; 00081 } 00082 00083 template <typename T, int Num> 00084 inline Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00085 Expr(const Expr< Sacado::Fad::SFadExprTag<T,Num> >& x) : 00086 val_(x.val()), update_val_(x.update_val_) 00087 { 00088 for (int i=0; i<Num; i++) 00089 dx_[i] = x.dx_[i]; 00090 } 00091 00092 template <typename T, int Num> 00093 template <typename S> 00094 inline Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00095 Expr(const Expr<S>& x) : update_val_(x.updateValue()) 00096 { 00097 #ifdef SACADO_DEBUG 00098 if (x.size() != Num) 00099 throw "SFad::SFad() Error: Attempt to assign with incompatible sizes"; 00100 #endif 00101 00102 for(int i=0; i<Num; ++i) 00103 dx_[i] = x.fastAccessDx(i); 00104 00105 if (update_val_) 00106 this->val() = x.val(); 00107 } 00108 00109 00110 template <typename T, int Num> 00111 inline void 00112 Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00113 diff(const int ith, const int n) 00114 { 00115 #ifdef SACADO_DEBUG 00116 if (n != Num) 00117 throw "SFad::diff() Error: Supplied derivative dimension does not match compile time length."; 00118 #endif 00119 00120 ss_array<T>::zero(dx_, Num); 00121 dx_[ith] = T(1.); 00122 } 00123 00124 template <typename T, int Num> 00125 inline void 00126 Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00127 resize(int sz) 00128 { 00129 #ifdef SACADO_DEBUG 00130 if (sz != Num) 00131 throw "SFad::resize() Error: Cannot resize fixed derivative array dimension"; 00132 #endif 00133 } 00134 00135 template <typename T, int Num> 00136 inline Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >& 00137 Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00138 operator=(const T& v) 00139 { 00140 val_ = v; 00141 ss_array<T>::zero(dx_, Num); 00142 00143 return *this; 00144 } 00145 00146 template <typename T, int Num> 00147 inline Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >& 00148 Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00149 operator=(const Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >& x) 00150 { 00151 // Copy value 00152 val_ = x.val_; 00153 00154 // Copy dx_ 00155 for (int i=0; i<Num; i++) 00156 dx_[i] = x.dx_[i]; 00157 00158 update_val_ = x.update_val_; 00159 00160 return *this; 00161 } 00162 00163 template <typename T, int Num> 00164 template <typename S> 00165 inline Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >& 00166 Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00167 operator=(const Expr<S>& x) 00168 { 00169 #ifdef SACADO_DEBUG 00170 if (x.size() != Num) 00171 throw "SFad::operator=() Error: Attempt to assign with incompatible sizes"; 00172 #endif 00173 00174 for(int i=0; i<Num; ++i) 00175 dx_[i] = x.fastAccessDx(i); 00176 00177 update_val_ = x.updateValue(); 00178 if (update_val_) 00179 val_ = x.val(); 00180 00181 return *this; 00182 } 00183 00184 template <typename T, int Num> 00185 inline Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >& 00186 Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00187 operator += (const T& v) 00188 { 00189 if (update_val_) 00190 val_ += v; 00191 00192 return *this; 00193 } 00194 00195 template <typename T, int Num> 00196 inline Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >& 00197 Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00198 operator -= (const T& v) 00199 { 00200 if (update_val_) 00201 val_ -= v; 00202 00203 return *this; 00204 } 00205 00206 template <typename T, int Num> 00207 inline Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >& 00208 Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00209 operator *= (const T& v) 00210 { 00211 if (update_val_) 00212 val_ *= v; 00213 00214 for (int i=0; i<Num; ++i) 00215 dx_[i] *= v; 00216 00217 return *this; 00218 } 00219 00220 template <typename T, int Num> 00221 inline Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >& 00222 Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00223 operator /= (const T& v) 00224 { 00225 if (update_val_) 00226 val_ /= v; 00227 00228 for (int i=0; i<Num; ++i) 00229 dx_[i] /= v; 00230 00231 return *this; 00232 } 00233 00234 template <typename T, int Num> 00235 template <typename S> 00236 inline Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >& 00237 Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00238 operator += (const Sacado::Fad::Expr<S>& x) 00239 { 00240 #ifdef SACADO_DEBUG 00241 if (x.size() != Num) 00242 throw "SFad::operator+=() Error: Attempt to assign with incompatible sizes"; 00243 #endif 00244 00245 for (int i=0; i<Num; ++i) 00246 dx_[i] += x.fastAccessDx(i); 00247 00248 update_val_ = x.updateValue(); 00249 if (update_val_) 00250 val_ += x.val(); 00251 00252 return *this; 00253 } 00254 00255 template <typename T, int Num> 00256 template <typename S> 00257 inline Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >& 00258 Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00259 operator -= (const Sacado::Fad::Expr<S>& x) 00260 { 00261 #ifdef SACADO_DEBUG 00262 if (x.size() != Num) 00263 throw "SFad::operator-=() Error: Attempt to assign with incompatible sizes"; 00264 #endif 00265 00266 for(int i=0; i<Num; ++i) 00267 dx_[i] -= x.fastAccessDx(i); 00268 00269 update_val_ = x.updateValue(); 00270 if (update_val_) 00271 val_ -= x.val(); 00272 00273 return *this; 00274 } 00275 00276 template <typename T, int Num> 00277 template <typename S> 00278 inline Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >& 00279 Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00280 operator *= (const Sacado::Fad::Expr<S>& x) 00281 { 00282 T xval = x.val(); 00283 00284 #ifdef SACADO_DEBUG 00285 if (x.size() != Num) 00286 throw "SFad::operator*=() Error: Attempt to assign with incompatible sizes"; 00287 #endif 00288 00289 for(int i=0; i<Num; ++i) 00290 dx_[i] = val_ * x.fastAccessDx(i) + dx_[i] * xval; 00291 00292 update_val_ = x.updateValue(); 00293 if (update_val_) 00294 val_ *= xval; 00295 00296 return *this; 00297 } 00298 00299 template <typename T, int Num> 00300 template <typename S> 00301 inline Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >& 00302 Sacado::Fad::Expr< Sacado::Fad::SFadExprTag<T,Num> >:: 00303 operator /= (const Sacado::Fad::Expr<S>& x) 00304 { 00305 T xval = x.val(); 00306 00307 #ifdef SACADO_DEBUG 00308 if (x.size() != Num) 00309 throw "SFad::operator/=() Error: Attempt to assign with incompatible sizes"; 00310 #endif 00311 00312 for(int i=0; i<Num; ++i) 00313 dx_[i] = ( dx_[i]*xval - val_*x.fastAccessDx(i) )/ (xval*xval); 00314 00315 update_val_ = x.updateValue(); 00316 if (update_val_) 00317 val_ /= xval; 00318 00319 return *this; 00320 } 00321
1.7.4