|
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::CacheFad::Expr< Sacado::CacheFad::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 "CacheFad::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::CacheFad::Expr< Sacado::CacheFad::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 "CacheFad::SFad() Error: Supplied derivative dimension does not match compile time length."; 00075 if (i >= Num) 00076 throw "CacheFad::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::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >:: 00085 Expr(const Expr< Sacado::CacheFad::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::CacheFad::Expr< Sacado::CacheFad::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 "CacheFad::SFad() Error: Attempt to assign with incompatible sizes"; 00100 #endif 00101 00102 x.cache(); 00103 00104 if (update_val_) 00105 this->val() = x.val(); 00106 00107 for(int i=0; i<Num; ++i) 00108 dx_[i] = x.fastAccessDx(i); 00109 } 00110 00111 00112 template <typename T, int Num> 00113 inline void 00114 Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >:: 00115 diff(const int ith, const int n) 00116 { 00117 #ifdef SACADO_DEBUG 00118 if (n != Num) 00119 throw "CacheFad::diff() Error: Supplied derivative dimension does not match compile time length."; 00120 #endif 00121 00122 ss_array<T>::zero(dx_, Num); 00123 dx_[ith] = T(1.); 00124 } 00125 00126 template <typename T, int Num> 00127 inline void 00128 Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >:: 00129 resize(int sz) 00130 { 00131 #ifdef SACADO_DEBUG 00132 if (sz != Num) 00133 throw "CacheFad::resize() Error: Cannot resize fixed derivative array dimension"; 00134 #endif 00135 } 00136 00137 template <typename T, int Num> 00138 inline Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >& 00139 Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >:: 00140 operator=(const T& v) 00141 { 00142 val_ = v; 00143 ss_array<T>::zero(dx_, Num); 00144 00145 return *this; 00146 } 00147 00148 template <typename T, int Num> 00149 inline Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >& 00150 Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >:: 00151 operator=(const Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >& x) 00152 { 00153 // Copy value 00154 val_ = x.val_; 00155 00156 // Copy dx_ 00157 for (int i=0; i<Num; i++) 00158 dx_[i] = x.dx_[i]; 00159 00160 update_val_ = x.update_val_; 00161 00162 return *this; 00163 } 00164 00165 template <typename T, int Num> 00166 template <typename S> 00167 inline Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >& 00168 Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >:: 00169 operator=(const Expr<S>& x) 00170 { 00171 #ifdef SACADO_DEBUG 00172 if (x.size() != Num) 00173 throw "CacheFad::operator=() Error: Attempt to assign with incompatible sizes"; 00174 #endif 00175 00176 x.cache(); 00177 00178 for(int i=0; i<Num; ++i) 00179 dx_[i] = x.fastAccessDx(i); 00180 00181 update_val_ = x.updateValue(); 00182 if (update_val_) 00183 val_ = x.val(); 00184 00185 return *this; 00186 } 00187 00188 template <typename T, int Num> 00189 inline Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >& 00190 Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >:: 00191 operator += (const T& v) 00192 { 00193 if (update_val_) 00194 val_ += v; 00195 00196 return *this; 00197 } 00198 00199 template <typename T, int Num> 00200 inline Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >& 00201 Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >:: 00202 operator -= (const T& v) 00203 { 00204 if (update_val_) 00205 val_ -= v; 00206 00207 return *this; 00208 } 00209 00210 template <typename T, int Num> 00211 inline Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >& 00212 Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >:: 00213 operator *= (const T& v) 00214 { 00215 if (update_val_) 00216 val_ *= v; 00217 00218 for (int i=0; i<Num; ++i) 00219 dx_[i] *= v; 00220 00221 return *this; 00222 } 00223 00224 template <typename T, int Num> 00225 inline Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >& 00226 Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >:: 00227 operator /= (const T& v) 00228 { 00229 if (update_val_) 00230 val_ /= v; 00231 00232 for (int i=0; i<Num; ++i) 00233 dx_[i] /= v; 00234 00235 return *this; 00236 } 00237 00238 template <typename T, int Num> 00239 template <typename S> 00240 inline Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >& 00241 Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >:: 00242 operator += (const Sacado::CacheFad::Expr<S>& x) 00243 { 00244 #ifdef SACADO_DEBUG 00245 if (x.size() != Num) 00246 throw "CacheFad::operator+=() Error: Attempt to assign with incompatible sizes"; 00247 #endif 00248 00249 x.cache(); 00250 00251 for (int i=0; i<Num; ++i) 00252 dx_[i] += x.fastAccessDx(i); 00253 00254 update_val_ = x.updateValue(); 00255 if (update_val_) 00256 val_ += x.val(); 00257 00258 return *this; 00259 } 00260 00261 template <typename T, int Num> 00262 template <typename S> 00263 inline Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >& 00264 Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >:: 00265 operator -= (const Sacado::CacheFad::Expr<S>& x) 00266 { 00267 #ifdef SACADO_DEBUG 00268 if (x.size() != Num) 00269 throw "CacheFad::operator-=() Error: Attempt to assign with incompatible sizes"; 00270 #endif 00271 00272 x.cache(); 00273 00274 for(int i=0; i<Num; ++i) 00275 dx_[i] -= x.fastAccessDx(i); 00276 00277 update_val_ = x.updateValue(); 00278 if (update_val_) 00279 val_ -= x.val(); 00280 00281 return *this; 00282 } 00283 00284 template <typename T, int Num> 00285 template <typename S> 00286 inline Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >& 00287 Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >:: 00288 operator *= (const Sacado::CacheFad::Expr<S>& x) 00289 { 00290 x.cache(); 00291 00292 T xval = x.val(); 00293 00294 #ifdef SACADO_DEBUG 00295 if (x.size() != Num) 00296 throw "CacheFad::operator*=() Error: Attempt to assign with incompatible sizes"; 00297 #endif 00298 00299 for(int i=0; i<Num; ++i) 00300 dx_[i] = val_ * x.fastAccessDx(i) + dx_[i] * xval; 00301 00302 update_val_ = x.updateValue(); 00303 if (update_val_) 00304 val_ *= xval; 00305 00306 return *this; 00307 } 00308 00309 template <typename T, int Num> 00310 template <typename S> 00311 inline Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >& 00312 Sacado::CacheFad::Expr< Sacado::CacheFad::SFadExprTag<T,Num> >:: 00313 operator /= (const Sacado::CacheFad::Expr<S>& x) 00314 { 00315 x.cache(); 00316 00317 T xval = x.val(); 00318 00319 #ifdef SACADO_DEBUG 00320 if (x.size() != Num) 00321 throw "CacheFad::operator/=() Error: Attempt to assign with incompatible sizes"; 00322 #endif 00323 00324 for(int i=0; i<Num; ++i) 00325 dx_[i] = ( dx_[i]*xval - val_*x.fastAccessDx(i) )/ (xval*xval); 00326 00327 update_val_ = x.updateValue(); 00328 if (update_val_) 00329 val_ /= xval; 00330 00331 return *this; 00332 } 00333
1.7.4