NeoPZ
tfad.h
Go to the documentation of this file.
1 // Emacs will be in -*- Mode: c++ -*-
2 //
3 // ************ DO NOT REMOVE THIS BANNER ****************
4 //
5 // Nicolas Di Cesare <Nicolas.Dicesare@ann.jussieu.fr>
6 // http://www.ann.jussieu.fr/~dicesare
7 //
8 // CEMRACS 98 : C++ courses,
9 // templates : new C++ techniques
10 // for scientific computing
11 //
12 //********************************************************
13 //
14 // A short implementation ( not all operators and
15 // functions are overloaded ) of 1st order Automatic
16 // Differentiation in forward mode (FAD) using
17 // EXPRESSION TEMPLATES.
18 //
19 //********************************************************
20 #ifndef _tfad_h_
21 #define _tfad_h_
22 
23 // ANSI C++ algorithm include
24 #include <algorithm>
25 
26 // C include
27 #include <cmath>
28 #include <cstring>
29 #include <type_traits> // for enable_if
30 #include <TPZSavable.h>
31 #include <TPZStream.h>
32 
33 // type promotion include
34 #include <utils/promote.h>
35 #include <Hash/TPZHash.h>
36 
37 using namespace std;
38 
39 template <class L, class R, class Enable> class NumericalTraits;
40 
41 template <class T> class TFadExpr;
42 template <class T> class TFadCst;
43 
44 template <class T> class TFadUnaryPlus;
45 template <class T> class TFadUnaryMin;
46 
47 template <class L, class R> class TFadBinaryAdd;
48 template <class L, class R> class TFadBinaryMinus;
49 template <class L, class R> class TFadBinaryMul;
50 template <class L, class R> class TFadBinaryDiv;
51 
52 template <typename T>
54 public:
55  typedef T type;
56 };
57 
58 template<int Num, class T>
59 class GetArithmeticType<TFad<Num, T>> {
60 public:
61  typedef typename GetArithmeticType<T>::type type;
62 };
63 
64 template <int Num, class T=float> class TFad : public TPZSavable {
65 public:
66  typedef T value_type;
68 
69  void copy(const TFad<Num,T>& rhs);
70 protected:
71  T val_;
72  T dx_[Num];
73 
74 public:
75 
76  TFad() : val_( T(0.f)) {memset(((void *)dx_),0,Num*sizeof(T));}
77  TFad(const T & x) : val_(x) {memset((void *)dx_,0,Num*sizeof(T));}
78  // TFad(const int sz, const T & x) : val_(x), dx_(sz,T(0)) {;}
79  TFad(const T & x, const int i) : val_(x)
80  {memset((void *)dx_,0,Num*sizeof(T));dx_[i]=1.;}
81  TFad(const TFad<Num,T> & x);
82  template <class ExprT> TFad(const TFadExpr<ExprT>& fadexpr);
83  ~TFad() {;}
84 
85  void diff(const int ith, const int n);
86 
87  //const Vector<T>& dx() const { return dx_;}
88 
89  const T& val() const { return val_;}
90  T& val() { return val_;}
91 
92  bool hasFastAccess() const { return true;}
93 
94  T& fastAccessDx(int i) { return dx_[i];}
95  const T& fastAccessDx(int i) const { return dx_[i];}
96  const T& d(int i) const { return dx_[i];}
97 
98  const T dx(int i) const { return dx_[i];}
99  T dx(int i) { return dx_[i];}
100 
101  int size() const { return Num;}
102 
103  TFad<Num,T> & operator=(const T& val);
104  TFad<Num,T> & operator=(const TFad<Num,T>& rhs);
105  template <class ExprT> TFad<Num,T> & operator=(const TFadExpr<ExprT>& fadexpr);
106 
109 
110  TFad<Num,T>& operator+= (const T& x);
111  TFad<Num,T>& operator-= (const T& x);
112  TFad<Num,T>& operator*= (const T& x);
113  TFad<Num,T>& operator/= (const T& x);
114 
115  TFad<Num,T>& operator+= (const TFad<Num,T>& x);
117  TFad<Num,T>& operator*= (const TFad<Num,T>& x);
118  TFad<Num,T>& operator/= (const TFad<Num,T>& x);
119 
120  template <class ExprT> TFad<Num,T>& operator*= (const TFadExpr<ExprT>& fadexpr);
121  template <class ExprT> TFad<Num,T>& operator/= (const TFadExpr<ExprT>& fadexpr);
122  template <class ExprT> TFad<Num,T>& operator+= (const TFadExpr<ExprT>& fadexpr);
123  template <class ExprT> TFad<Num,T>& operator-= (const TFadExpr<ExprT>& fadexpr);
124 
125  int ClassId() const override;
126 
127 template <typename TEMP=void>
128 typename std::enable_if<is_arithmetic_pz<T>::value, TEMP>::type
129 Read(TPZStream& buf, void* context) {
130  buf.Read(&val_);
131  buf.Read(dx_,Num);
132 }
133 
134 template <typename TEMP=void>
135 typename std::enable_if<is_arithmetic_pz<T>::value, TEMP>::type
136 Write(TPZStream& buf, int withclassid) const {
137  buf.Write(&val_);
138  buf.Write(dx_,Num);
139 }
140 
141 template <typename TEMP=void>
142 typename std::enable_if<!is_arithmetic_pz<T>::value, TEMP>::type
143 Read(TPZStream& buf, void* context) {
144  val_.Read(buf, context);
145  for (unsigned int i = 0; i < Num; ++i) {
146  dx_[i].Read(buf, context);
147  }
148 }
149 
150 template <typename TEMP=void>
151 typename std::enable_if<!is_arithmetic_pz<T>::value, TEMP>::type
152 Write(TPZStream& buf, int withclassid) const {
153  val_.Write(buf,withclassid);
154  for (unsigned int i = 0; i < Num; ++i) {
155  dx_[i].Write(buf,withclassid);
156  }
157 }
158 
159  friend ostream& operator<< (ostream& stream, const TFad<Num,T>& x)
160  {
161  return stream << x.val();
162  }
163 
164  friend istream& operator>> (istream& stream, TFad<Num,T>& x)
165  {
166  return stream >> x.val();
167  }
168 
169 };
170 
171 
172 template <int Num,class T> inline void TFad<Num,T>::copy(const TFad<Num,T>& rhs)
173 {
174  //dx_ = rhs.dx_;
175  for (int i=0; i<Num; ++i)
176  dx_[i] = rhs.dx_[i];
177  val_ = rhs.val_;
178 }
179 
180 template <int Num,class T> inline TFad<Num,T>::TFad(const TFad<Num,T> & rhs)
181 {
182  copy(rhs);
183 }
184 
185 template <int Num,class T> template <class ExprT> inline
187 : val_(fadexpr.val())
188 {
189 
190  for(int i=0; i<Num; ++i)
191  dx_[i] = fadexpr.dx(i);
192 
193 }
194 
195 
196 template <int Num,class T> inline void TFad<Num,T>::diff(const int ith, const int n)
197 {
198 
199  for(int i=0; i<Num; ++i)
200  dx_[i] = T(0);
201  dx_[ith] = T(1.);
202 
203 }
204 
205 template <int Num,class T> inline TFad<Num,T> & TFad<Num,T>::operator=(const T& val)
206 {
207  val_ = val;
208 
209  for(int i=0; i<Num; ++i)
210  dx_[i] = T(0);
211 
212  return *this;
213 }
214 
215 template <int Num,class T> inline TFad<Num,T> & TFad<Num,T>::operator=(const TFad<Num,T>& rhs)
216 {
217  if ( this != &rhs ) copy(rhs);
218 
219  return *this;
220 }
221 
222 template <int Num,class T> template <class ExprT> inline TFad<Num,T> & TFad<Num,T>::operator=(const TFadExpr<ExprT>& fadexpr)
223 {
224  for(int i=0; i<Num; ++i)
225  dx_[i] = fadexpr.dx(i);
226 
227  val_ = fadexpr.val();
228 
229  return *this;
230 }
231 
232 template <int Num,class T> inline TFadExpr< TFadUnaryPlus< TFad<Num,T> > >
234 {
235  return TFadExpr< TFadUnaryPlus< TFad<Num,T> > >(*this);
236 }
237 
238 template <int Num,class T> inline TFadExpr< TFadUnaryMin< TFad<Num,T> > >
240 {
241  return TFadExpr< TFadUnaryMin< TFad<Num,T> > >(*this);
242 }
243 
244 
245 template <int Num,class T> inline TFad<Num,T> & TFad<Num,T>::operator+= (const T& val)
246 {
247  val_ += val;
248 
249  return *this;
250 }
251 
252 template <int Num,class T> inline TFad<Num,T> & TFad<Num,T>::operator-= (const T& val)
253 {
254  val_ -= val;
255 
256  return *this;
257 }
258 
259 template <int Num,class T> inline TFad<Num,T> & TFad<Num,T>::operator*= (const T& val)
260 {
261  val_ *= val;
262 
263  for (int i=0; i<Num;++i)
264  dx_[i] *= val;
265 
266  return *this;
267 }
268 
269 template <int Num,class T> inline TFad<Num,T> & TFad<Num,T>::operator/= (const T& val)
270 {
271  val_ /= val;
272 
273  for (int i=0; i<Num;++i)
274  dx_[i] /= val;
275 
276  return *this;
277 }
278 
279 
280 template <int Num,class T> inline TFad<Num,T> & TFad<Num,T>::operator+= (const TFad<Num,T>& x)
281 {
282  for (int i=0; i<Num; ++i)
283  dx_[i] += x.dx_[i];
284 
285  val_ += x.val_;
286 
287  return *this;
288 }
289 
290 template <int Num,class T> inline TFad<Num,T> & TFad<Num,T>::operator-= (const TFad<Num,T>& x)
291 {
292  for (int i=0; i<Num; ++i)
293  dx_[i] -= x.dx_[i];
294 
295  val_ -= x.val_;
296 
297  return *this;
298 }
299 
300 template <int Num,class T> inline TFad<Num,T> & TFad<Num,T>::operator*= (const TFad<Num,T>& x)
301 {
302  for (int i=0; i<Num; ++i)
303  dx_[i] = val_ * x.dx_[i] + dx_[i] * x.val_;
304 
305  val_ *= x.val_;
306 
307  return *this;
308 }
309 
310 template <int Num,class T> inline TFad<Num,T> & TFad<Num,T>::operator/= (const TFad<Num,T>& x)
311 {
312  for (int i=0; i<Num; ++i)
313  dx_[i] = (dx_[i]*x.val_ - val_*x.dx_[i])/ (x.val_*x.val_);
314 
315  val_ /= x.val_;
316 
317  return *this;
318 }
319 
320 
321 
322 template <int Num,class T> template <class ExprT> inline TFad<Num,T> & TFad<Num,T>::operator+= (const TFadExpr<ExprT>& x)
323 {
324  for (int i=0; i<Num; ++i)
325  dx_[i] += x.dx(i);
326 
327  val_ += x.val();
328 
329  return *this;
330 }
331 
332 template <int Num,class T> template <class ExprT> inline TFad<Num,T> & TFad<Num,T>::operator-= (const TFadExpr<ExprT>& x)
333 {
334  for (int i=0; i<Num; ++i)
335  dx_[i] -= x.dx(i);
336  val_ -= x.val();
337 
338 
339  return *this;
340 }
341 
342 template <int Num,class T> template <class ExprT> inline TFad<Num,T> & TFad<Num,T>::operator*= (const TFadExpr<ExprT>& x)
343 {
344  T xval = x.val();
345  for (int i=0; i<Num; ++i)
346  dx_[i] = val_ * x.dx(i) + dx_[i] * xval;
347 
348  val_ *= xval;
349 
350  return *this;
351 }
352 
353 template <int Num,class T> template <class ExprT> inline TFad<Num,T> & TFad<Num,T>::operator/= (const TFadExpr<ExprT>& x)
354 {
355  T xval = x.val();
356 
357  for (int i=0; i<Num; ++i)
358  dx_[i] = ( dx_[i]*xval - val_*x.dx(i) )/ (xval*xval);
359 
360  val_ /= xval;
361 
362  return *this;
363 }
364 
365 
366 
367 
368 //------------------------------- TFad ostream operator ------------------------------------------
369 template <int Num,class T> inline ostream& operator << (ostream& os, const TFad<Num,T>& a)
370 {
371  os.setf(ios::fixed,ios::floatfield);
372  os.width(12);
373  os << a.val() << " [";
374 
375 
376  for (int i=0; i< Num; i++) {
377  os.width(12);
378  os << a.dx(i);
379  }
380 
381  os << "]\n";
382  return os;
383 }
384 
385 //------------------------------- TFad expression ------------------------------------------
386 template < class T > class TFadExpr {
387 public:
388  typedef typename T::value_type value_type;
389 
390 protected:
391  TFadExpr() {}
392 
394 
395 public:
396  explicit TFadExpr(const T& fadexpr) : fadexpr_(fadexpr) {;}
397 
398  value_type val() const { return fadexpr_.val();}
399  value_type dx(int i) const { return fadexpr_.dx(i);}
400  int size() const {return fadexpr_.size();}
401 
402  bool hasFastAccess() const { return fadexpr_.hasFastAccess();}
403  value_type fastAccessDx(int i) const { return fadexpr_.fastAccessDx(i);}
404 };
405 
406 //------------------------------- TFad constant ------------------------------------------
407 template < class T > class TFadCst {
408 public:
409  typedef T value_type;
410 
411 protected:
412  TFadCst() {}
413 
414  const T constant_;
415 
416 public:
417  explicit TFadCst(const T& value) : constant_(value) {;}
418 
419  const value_type& val() const { return constant_;}
420  const value_type dx(int i) const { return value_type(0);}
421  int size() const {return 0;}
422 
423  bool hasFastAccess() const { return 1;}
424  value_type& fastAccessDx(int i) const { return value_type(0);}
425 };
426 
427 //------------------------------- TFad unary + ------------------------------------------
428 template < class T > class TFadUnaryPlus {
429 public:
430  typedef typename T::value_type value_type;
431 
432 protected:
434 
435  const T& expr_;
436 
437 public:
438  TFadUnaryPlus(const T& value) : expr_(value) {;}
439 
440  const value_type val() const { return expr_.val();}
441  const value_type dx(int i) const { return expr_.dx(i);}
442  int size() const {return expr_.size();}
443 
444  bool hasFastAccess() const { return expr_.hasFastAccess();}
445  value_type fastAccessDx(int i) const { return expr_.fastAccessDx(i);}
446 };
447 
448 //------------------------------- TFad unary - ------------------------------------------
449 template < class T > class TFadUnaryMin {
450 public:
451  typedef typename T::value_type value_type;
452 
453 protected:
455 
456  const T& expr_;
457 
458 public:
459  TFadUnaryMin(const T& value) : expr_(value) {;}
460 
461  const value_type val() const { return - expr_.val();}
462  const value_type dx(int i) const { return - expr_.dx(i);}
463  int size() const {return expr_.size();}
464 
465  bool hasFastAccess() const { return expr_.hasFastAccess();}
466  value_type fastAccessDx(int i) const { return - expr_.fastAccessDx(i);}
467 };
468 
469 template <class T> inline
472 {
473  typedef TFadUnaryPlus< TFadExpr<T> > expr_t;
474 
475  return TFadExpr< expr_t >( expr_t(expr) );
476 }
477 
478 template <class T> inline
481 {
482  typedef TFadUnaryMin< TFadExpr<T> > expr_t;
483 
484  return TFadExpr< expr_t >( expr_t(expr) );
485 }
486 
487 template <int Num, typename T>
489  return Hash("TFad") ^ Num<<1 ^ (ClassIdOrHash<T>()<<2);
490 }
491 
492 #include <TinyFadET/tfadlog.h>
493 #include <TinyFadET/tfadop.h>
494 #include <TinyFadET/tfadfunc.h>
495 
496 #endif
int size() const
Definition: tfad.h:101
bool hasFastAccess() const
Definition: tfad.h:423
T dx(int i)
Definition: tfad.h:99
Contains declaration of the TPZSavable class which defines the interface to save and restore objects ...
value_type val() const
Definition: tfad.h:398
TFadExpr< TFadUnaryMin< TFadExpr< T > > > operator-(const TFadExpr< T > &expr)
Definition: tfad.h:480
TFadCst()
Definition: tfad.h:412
int size() const
Definition: tfad.h:442
TFad< Num, T > & operator*=(const T &x)
Definition: tfad.h:259
const T constant_
Definition: tfad.h:414
T fadexpr_
Definition: tfad.h:393
TFadCst(const T &value)
Definition: tfad.h:417
T::value_type value_type
Definition: tfad.h:430
TFad< Num, T > & operator-=(const T &x)
Definition: tfad.h:252
GetArithmeticType< T >::type arithmetic_type
Definition: tfad.h:67
int size() const
Definition: tfad.h:463
int ClassId() const override
Define the class id associated with the class.
Definition: tfad.h:488
TPZVec< T > & operator-=(TPZVec< T > &a, const TPZVec< T > &b)
substracts two vectors
Definition: pzvec_extras.h:80
TFadExpr< TFadUnaryMin< TFad< Num, T > > > operator-() const
Definition: tfad.h:239
TFad(const T &x, const int i)
Definition: tfad.h:79
TFadExpr< TFadUnaryPlus< TFadExpr< T > > > operator+(const TFadExpr< T > &expr)
Definition: tfad.h:471
int size() const
Definition: tfad.h:421
REAL val(STATE &number)
Returns value of the variable.
Definition: pzartdiff.h:23
std::istream & operator>>(std::istream &out, TPZFlopCounter &val)
Implements to read (input) only the floating point value.
Definition: pzreal.h:625
value_type fastAccessDx(int i) const
Definition: tfad.h:403
T::value_type value_type
Definition: tfad.h:451
TFadExpr(const T &fadexpr)
Definition: tfad.h:396
bool hasFastAccess() const
Definition: tfad.h:402
TFadExpr()
Definition: tfad.h:391
const T & fastAccessDx(int i) const
Definition: tfad.h:95
T & fastAccessDx(int i)
Definition: tfad.h:94
std::enable_if<!is_arithmetic_pz< T >::value, TEMP >::type Read(TPZStream &buf, void *context)
read objects from the stream
Definition: tfad.h:143
T value_type
Definition: tfad.h:409
value_type dx(int i) const
Definition: tfad.h:399
TFad()
Definition: tfad.h:76
const T & expr_
Definition: tfad.h:435
const value_type dx(int i) const
Definition: tfad.h:462
f
Definition: test.py:287
bool hasFastAccess() const
Definition: tfad.h:465
TFadUnaryMin()
Definition: tfad.h:454
const value_type & val() const
Definition: tfad.h:419
TFadExpr< TFadUnaryPlus< TFad< Num, T > > > operator+() const
Definition: tfad.h:233
virtual void Write(const bool val)
Definition: TPZStream.cpp:8
T & val()
Definition: tfad.h:90
const T dx(int i) const
Definition: tfad.h:98
TFad< Num, T > & operator+=(const T &x)
Definition: tfad.h:245
Definition: tfad.h:64
const T & d(int i) const
Definition: tfad.h:96
std::enable_if< is_arithmetic_pz< T >::value, TEMP >::type Write(TPZStream &buf, int withclassid) const
Writes this object to the TPZStream buffer. Include the classid if withclassid = true.
Definition: tfad.h:136
void copy(const TFad< Num, T > &rhs)
Definition: tfad.h:172
TFad(const T &x)
Definition: tfad.h:77
Definition: tfad.h:41
Definition: tfad.h:42
bool hasFastAccess() const
Definition: tfad.h:444
int32_t Hash(std::string str)
Definition: TPZHash.cpp:10
GetArithmeticType< T >::type type
Definition: tfad.h:61
T::value_type value_type
Definition: tfad.h:388
void diff(const int ith, const int n)
Definition: tfad.h:196
value_type fastAccessDx(int i) const
Definition: tfad.h:466
const value_type val() const
Definition: tfad.h:461
const value_type dx(int i) const
Definition: tfad.h:420
std::enable_if<!is_arithmetic_pz< T >::value, TEMP >::type Write(TPZStream &buf, int withclassid) const
Writes this object to the TPZStream buffer. Include the classid if withclassid = true.
Definition: tfad.h:152
const value_type val() const
Definition: tfad.h:440
TFadUnaryMin(const T &value)
Definition: tfad.h:459
TFad< Num, T > & operator/=(const T &x)
Definition: tfad.h:269
value_type & fastAccessDx(int i) const
Definition: tfad.h:424
TFad< Num, T > & operator=(const T &val)
Definition: tfad.h:205
int size() const
Definition: tfad.h:400
std::enable_if< is_arithmetic_pz< T >::value, TEMP >::type Read(TPZStream &buf, void *context)
read objects from the stream
Definition: tfad.h:129
Contains declaration of the abstract TPZStream class. TPZStream defines the interface for saving and ...
Defines the interface for saving and reading data. Persistency.
Definition: TPZStream.h:50
TFadUnaryPlus()
Definition: tfad.h:433
~TFad()
Definition: tfad.h:83
TFadUnaryPlus(const T &value)
Definition: tfad.h:438
This class defines the interface to save and restore objects from TPZStream objects. Persistency.
Definition: TPZSavable.h:67
value_type fastAccessDx(int i) const
Definition: tfad.h:445
const value_type dx(int i) const
Definition: tfad.h:441
const T & val() const
Definition: tfad.h:89
const T & expr_
Definition: tfad.h:456
T val_
Definition: tfad.h:71
bool hasFastAccess() const
Definition: tfad.h:92
T dx_[Num]
Definition: tfad.h:72
virtual void Read(bool &val)
Definition: TPZStream.cpp:91
T value_type
Definition: tfad.h:66