NeoPZ
tfadop.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 _tfadop_h_
21 #define _tfadop_h_
22 
23 #include "utils/promote.h"
24 
25 //------------------------------- TFad binary operators ------------------------------------------
26 
27 
28 //------------------------------- TFad addition operators ------------------------------------------
29 template <class L, class R> class TFadBinaryAdd {
30 public:
31  typedef typename L::value_type value_type_L;
32  typedef typename R::value_type value_type_R;
33 
35 
36 protected:
38 
39  const L& left_; const R& right_;
40 
41 public:
42  TFadBinaryAdd(const L& left, const R& rigth) : left_(left), right_(rigth) {;}
44 
45 
46  const value_type val() const {return left_.val() + right_.val();}
47  const value_type dx(int i) const {return left_.dx(i) + right_.dx(i);}
48  int size() const {
49  int lsz = left_.size(), rsz = right_.size();
50  return max(lsz, rsz);
51  }
52 
53  bool hasFastAccess() const { return left_.hasFastAccess() && right_.hasFastAccess();}
54  value_type fastAccessDx(int i) const { return left_.fastAccessDx(i)+right_.fastAccessDx(i);}
55 };
56 
57 
58 template <class L> class TFadBinaryAdd<L, TFadCst<typename L::value_type> > {
59 public:
60  typedef typename L::value_type value_type;
62 
63 protected:
65 
66  const L& left_; const R right_;
67 
68 public:
69  TFadBinaryAdd(const L& left, const R& rigth) : left_(left), right_(rigth) {;}
71 
72 
73  const value_type val() const {return left_.val() + right_.val();}
74  const value_type dx(int i) const {return left_.dx(i);}
75  int size() const { return left_.size();}
76 
77  bool hasFastAccess() const { return left_.hasFastAccess();}
78  value_type fastAccessDx(int i) const { return left_.fastAccessDx(i);}
79 };
80 
81 
82 template <class R> class TFadBinaryAdd< TFadCst<typename R::value_type>, R> {
83 public:
84  typedef typename R::value_type value_type;
86 
87 protected:
89 
90  const L left_; const R& right_;
91 
92 public:
93  TFadBinaryAdd(const L& left, const R& rigth) : left_(left), right_(rigth) {;}
95 
96 
97  const value_type val() const {return left_.val() + right_.val();}
98  value_type dx(int i) const {return right_.dx(i);}
99  int size() const {return right_.size();}
100 
101  bool hasFastAccess() const { return right_.hasFastAccess();}
102  value_type fastAccessDx(int i) const { return right_.fastAccessDx(i);}
103 };
104 
105 
106 
107 
108 
109 
110 //------------------------------- TFad substraction operators ------------------------------------------
111 template <class L, class R> class TFadBinaryMinus {
112 public:
113  typedef typename L::value_type value_type_L;
114  typedef typename R::value_type value_type_R;
116 
117 protected:
119 
120  const L& left_; const R& right_;
121 
122 public:
123  TFadBinaryMinus(const L& left, const R& rigth) : left_(left), right_(rigth) {;}
125 
126 
127  const value_type val() const {return left_.val() - right_.val();}
128  const value_type dx(int i) const {return left_.dx(i) - right_.dx(i);}
129  int size() const {
130  int lsz = left_.size(), rsz = right_.size();
131  return max(lsz, rsz);
132  }
133 
134  bool hasFastAccess() const { return left_.hasFastAccess() && right_.hasFastAccess();}
135  value_type fastAccessDx(int i) const { return left_.fastAccessDx(i) - right_.fastAccessDx(i);}
136 };
137 
138 
139 template <class L> class TFadBinaryMinus<L, TFadCst<typename L::value_type> > {
140 public:
141  typedef typename L::value_type value_type;
143 
144 protected:
146 
147  const L& left_; const R right_;
148 
149 public:
150  TFadBinaryMinus(const L& left, const R & rigth) : left_(left), right_(rigth) {;}
152 
153 
154  const value_type val() const {return left_.val() - right_.val();}
155  const value_type dx(int i) const {return left_.dx(i);}
156  int size() const { return left_.size();}
157 
158  bool hasFastAccess() const { return left_.hasFastAccess();}
159  value_type fastAccessDx(int i) const { return left_.fastAccessDx(i);}
160 };
161 
162 
163 template <class R> class TFadBinaryMinus< TFadCst<typename R::value_type>, R> {
164 public:
165  typedef typename R::value_type value_type;
167 
168 protected:
170 
171  const L left_; const R& right_;
172 
173 public:
174  TFadBinaryMinus(const L& left, const R& rigth) : left_(left), right_(rigth) {;}
176 
177 
178  const value_type val() const {return left_.val() - right_.val();}
179  const value_type dx(int i) const {return - right_.dx(i);}
180  int size() const { return right_.size(); }
181 
182  bool hasFastAccess() const { return right_.hasFastAccess();}
183  value_type fastAccessDx(int i) const { return - right_.fastAccessDx(i);}
184 };
185 
186 
187 //------------------------------- TFad multiplication operators ------------------------------------------
188 template <class L, class R> class TFadBinaryMul {
189  public:
190  typedef typename L::value_type value_type_L;
191  typedef typename R::value_type value_type_R;
193 
194  protected:
196 
197  const L& left_; const R& right_;
198 
199  public:
200  TFadBinaryMul(const L& left, const R& rigth) : left_(left), right_(rigth) {;}
202 
203  const value_type val() const {return left_.val() * right_.val() ;}
204  const value_type dx(int i) const {return left_.dx(i) * right_.val() + right_.dx(i) * left_.val();}
205  int size() const {
206  int lsz = left_.size(), rsz = right_.size();
207  return max(lsz, rsz);
208  }
209 
210  bool hasFastAccess() const { return left_.hasFastAccess() && right_.hasFastAccess();}
211  value_type fastAccessDx(int i) const { return left_.fastAccessDx(i) * right_.val() + right_.fastAccessDx(i) * left_.val();}
212 
213 };
214 
215 template <class L> class TFadBinaryMul<L, TFadCst<typename L::value_type> > {
216  public:
217  typedef typename L::value_type value_type;
219 
220  protected:
222 
223  const L& left_; const R right_;
224 
225  public:
226  TFadBinaryMul(const L& left, const R& rigth) : left_(left), right_(rigth) {;}
228 
229  const value_type val() const {return left_.val() * right_.val() ;}
230  const value_type dx(int i) const {return left_.dx(i) * right_.val();}
231  int size() const { return left_.size();}
232 
233  bool hasFastAccess() const { return left_.hasFastAccess();}
234  value_type fastAccessDx(int i) const { return left_.fastAccessDx(i) * right_.val();}
235 };
236 
237 template <class R> class TFadBinaryMul< TFadCst<typename R::value_type>, R> {
238  public:
239  typedef typename R::value_type value_type;
241 
242  protected:
244 
245  const L left_; const R& right_;
246 
247  public:
248  TFadBinaryMul(const L& left, const R& rigth) : left_(left), right_(rigth) {;}
250 
251  const value_type val() const {return left_.val() * right_.val() ;}
252  const value_type dx(int i) const {return right_.dx(i) * left_.val();}
253  int size() const { return right_.size();}
254 
255  bool hasFastAccess() const { return right_.hasFastAccess();}
256  value_type fastAccessDx(int i) const { return right_.fastAccessDx(i) * left_.val();}
257 };
258 
259 
260 //------------------------------- TFad division operators ------------------------------------------
261 template <class L, class R> class TFadBinaryDiv {
262  public:
263  typedef typename L::value_type value_type_L;
264  typedef typename R::value_type value_type_R;
266 
267  protected:
269 
270  const L& left_; const R& right_;
271 
272  public:
273  TFadBinaryDiv(const L& left, const R& rigth) : left_(left), right_(rigth) {;}
275 
276 
277  const value_type val() const {return left_.val() / right_.val();}
278  const value_type dx(int i) const {return (left_.dx(i) * right_.val() - right_.dx(i) * left_.val() ) / (right_.val() * right_.val()) ;}
279  int size() const {
280  int lsz = left_.size(), rsz = right_.size();
281  return max(lsz, rsz);
282  }
283 
284  bool hasFastAccess() const { return left_.hasFastAccess() && right_.hasFastAccess();}
285  value_type fastAccessDx(int i) const { return (left_.fastAccessDx(i) * right_.val() - right_.fastAccessDx(i) * left_.val() )
286  / (right_.val() * right_.val()) ;}
287 };
288 
289 
290 template <class L> class TFadBinaryDiv<L, TFadCst<typename L::value_type> > {
291  public:
292  typedef typename L::value_type value_type;
294 
295  protected:
297 
298  const L& left_; const R right_;
299 
300  public:
301  TFadBinaryDiv(const L& left, const R& rigth) : left_(left), right_(rigth) {;}
303 
304 
305  const value_type val() const {return left_.val() / right_.val();}
306  const value_type dx(int i) const {return left_.dx(i) / right_.val();}
307  int size() const { return left_.size();}
308 
309  bool hasFastAccess() const { return left_.hasFastAccess();}
310  value_type fastAccessDx(int i) const { return left_.fastAccessDx(i) / right_.val() ;}
311 };
312 
313 
314 template <class R> class TFadBinaryDiv< TFadCst<typename R::value_type>, R> {
315  public:
316  typedef typename R::value_type value_type;
318 
319  protected:
321 
322  const L left_; const R& right_;
323 
324  public:
325  TFadBinaryDiv(const L& left, const R& rigth) : left_(left), right_(rigth) {;}
327 
328  const value_type val() const {return left_.val() / right_.val();}
329  const value_type dx(int i) const {return (- right_.dx(i) * left_.val() ) / (right_.val() * right_.val()) ;}
330  int size() const { return right_.size();}
331 
332  bool hasFastAccess() const { return right_.hasFastAccess();}
333  value_type fastAccessDx(int i) const { return (- right_.fastAccessDx(i) * left_.val() )
334  / (right_.val() * right_.val()) ;}
335 };
336 
337 
338 //------------------------------- TFad pow function ------------------------------------------
339 template <class L, class R> class TFadBinaryPow {
340 public:
341  typedef typename L::value_type value_type_L;
342  typedef typename R::value_type value_type_R;
343 
345 
346 protected:
348 
349  const L& left_; const R& right_;
350 
351 public:
352  TFadBinaryPow(const L& left, const R& rigth) : left_(left), right_(rigth) {;}
354 
355 
356  const value_type val() const {return std::pow( left_.val(), right_.val() );}
357  const value_type dx(int i) const
358  {
359  return (right_.dx(i)*std::log(left_.val())+right_.val()*left_.dx(i)/left_.val())
360  *std::pow( left_.val(), right_.val() );
361  }
362  int size() const {
363  int lsz = left_.size(), rsz = right_.size();
364  return max(lsz, rsz);
365  }
366 
367  bool hasFastAccess() const { return left_.hasFastAccess() && right_.hasFastAccess();}
368  value_type fastAccessDx(int i) const
369  {
370  return (right_.fastAccessDx(i)*std::log(left_.val())+right_.val()*left_.fastAccessDx(i)/left_.val())
371  *std::pow( left_.val(), right_.val() );
372  }
373 };
374 
375 
376 template <class L> class TFadBinaryPow<L, TFadCst<typename L::value_type> > {
377 public:
378  typedef typename L::value_type value_type;
380 
381 protected:
383 
384  const L& left_; const R right_;
385 
386 public:
387  TFadBinaryPow(const L& left, const R& rigth) : left_(left), right_(rigth) {;}
389 
390 
391  const value_type val() const {return std::pow(left_.val(),right_.val()) ;}
392  const value_type dx(int i) const
393  {
394  return (right_.val()*left_.dx(i)/left_.val())*std::pow( left_.val(), right_.val() );
395  }
396  int size() const { return left_.size();}
397 
398  bool hasFastAccess() const { return left_.hasFastAccess();}
399  value_type fastAccessDx(int i) const
400  {
401  return (right_.val()*left_.fastAccessDx(i)/left_.val())
402  *std::pow( left_.val(), right_.val() );
403  }
404 };
405 
406 
407 template <class R> class TFadBinaryPow< TFadCst<typename R::value_type>, R> {
408 public:
409  typedef typename R::value_type value_type;
411 
412 protected:
414 
415  const L left_; const R& right_;
416 
417 public:
418  TFadBinaryPow(const L& left, const R& rigth) : left_(left), right_(rigth) {;}
420 
421  const value_type val() const {return std::pow(left_.val(),right_.val());}
422  value_type dx(int i) const
423  {
424  return (right_.dx(i)*std::log(left_.val()))*std::pow( left_.val(), right_.val() );
425  }
426  int size() const {return right_.size();}
427 
428  bool hasFastAccess() const { return right_.hasFastAccess();}
429  value_type fastAccessDx(int i) const
430  {
431  return (right_.fastAccessDx(i)*std::log(left_.val()))
432  *std::pow( left_.val(), right_.val() );
433  }
434 };
435 
436 template <class L> class TFadBinaryPow< L , int> {
437 public:
438  typedef typename L::value_type value_type;
439  typedef TFadCst<int> R;
440 
441 protected:
443 
444  const L& left_; const R right_;
445 
446 public:
447  TFadBinaryPow(const L& left, const R& rigth) : left_(left), right_(rigth) {;}
449 
450 
451  const value_type val() const {return std::pow(left_.val(),right_.val());}
452  value_type dx(int i) const
453  {
454  return right_.val()*std::pow( left_.val(), right_.val()-1);
455  }
456  int size() const {return right_.size();}
457 
458  bool hasFastAccess() const { return right_.hasFastAccess();}
459  value_type fastAccessDx(int i) const
460  {
461  return right_.val() * std::pow( left_.val(), right_.val()-1 );
462  }
463 };
464 
465 
466 //------------------------------- TFad operators ------------------------------------------
467 #define FAD_BIN_MACRO(OP,TYPE) \
468 template<class E1, class E2> \
469 inline TFadExpr< TYPE< TFadExpr<E1>, TFadExpr<E2> > > \
470 OP (const TFadExpr<E1> &v, const TFadExpr<E2> &w){ \
471  typedef TYPE<TFadExpr<E1>, TFadExpr<E2> > expr_t; \
472  return TFadExpr<expr_t> (expr_t (v , w )); \
473 } \
474  \
475 template<class E> \
476 inline TFadExpr<TYPE<TFadExpr<E>,TFadCst<typename E::value_type> > > \
477 OP (const TFadExpr<E> &e, const typename E::value_type &t){ \
478  typedef typename E::value_type A; \
479  typedef TYPE<TFadExpr<E>,TFadCst<A> > expr_t; \
480  return TFadExpr<expr_t>(expr_t (e, TFadCst<A> (t))); \
481 } \
482  \
483 template<typename A,int Num> \
484 inline TFadExpr<TYPE<TFadCst<A>,TFad<Num,A> > > \
485 OP (const A& a, const TFad<Num,A> &e){ \
486  typedef TYPE<TFadCst<A>,TFad<Num,A> > expr_t; \
487  return TFadExpr<expr_t> (expr_t (TFadCst<A>(a), e )); \
488 } \
489  \
490 template<typename A,int Num> \
491 inline TFadExpr<TYPE<TFad<Num,A>,TFadCst<A> > > \
492 OP (const TFad<Num,A> &e, const A& a){ \
493  typedef TYPE<TFad<Num,A>,TFadCst<A> > expr_t; \
494  return TFadExpr<expr_t>(expr_t (e ,TFadCst<A>(a))); \
495 } \
496  \
497 template<class E> \
498 inline TFadExpr<TYPE<TFadCst<typename E::value_type>,TFadExpr<E> > > \
499 OP (const typename E::value_type &t, const TFadExpr<E> &e){ \
500  typedef typename E::value_type A; \
501  typedef TYPE<TFadCst<A>,TFadExpr<E> > expr_t; \
502  return TFadExpr<expr_t> (expr_t (TFadCst<A> (t),e )); \
503 } \
504  \
505 template<class E,int Num> \
506 inline TFadExpr<TYPE<TFadExpr<E>,TFad<Num,typename E::value_type> > > \
507 OP (const TFadExpr<E> &e,const TFad<Num,typename E::value_type>& v){ \
508  /*typedef typename E::value_type A;*/ \
509  typedef TYPE<TFadExpr<E>,TFad<Num,typename E::value_type> > expr_t; \
510  return TFadExpr<expr_t>(expr_t (e, v )); \
511 } \
512  \
513 template<typename A,int Num> \
514 inline TFadExpr<TYPE<TFad<Num,A>,TFad<Num,A> > > \
515 OP (const TFad<Num,A> &e1,const TFad<Num,A>& e2){ \
516  typedef TYPE<TFad<Num,A>,TFad<Num,A> > expr_t; \
517  return TFadExpr<expr_t>(expr_t (e1 , e2 )); \
518 } \
519  \
520 template<class E, int Num> \
521 inline TFadExpr<TYPE<TFad<Num,typename E::value_type>,TFadExpr<E> > > \
522 OP (const TFad<Num,typename E::value_type> &v, const TFadExpr<E> &e){ \
523  /*typedef typename E::value_type A;*/ \
524  typedef TYPE<TFad<Num,typename E::value_type>,TFadExpr<E> > expr_t; \
525  return TFadExpr<expr_t> (expr_t (v , e )); \
526 }
527 
528 FAD_BIN_MACRO(operator+,TFadBinaryAdd)
530 FAD_BIN_MACRO(operator*,TFadBinaryMul)
531 FAD_BIN_MACRO(operator/,TFadBinaryDiv)
532 
534 
535 #undef FAD_BIN_MACRO
536 
537 
538 #endif
value_type fastAccessDx(int i) const
Definition: tfadop.h:368
TFadBinaryAdd(const L &left, const R &rigth)
Definition: tfadop.h:93
const value_type val() const
Definition: tfadop.h:277
TFadBinaryPow(const L &left, const R &rigth)
Definition: tfadop.h:387
bool hasFastAccess() const
Definition: tfad.h:423
const value_type val() const
Definition: tfadop.h:356
R::value_type value_type_R
Definition: tfadop.h:342
bool hasFastAccess() const
Definition: tfadop.h:210
bool hasFastAccess() const
Definition: tfadop.h:284
TFadBinaryMul(const L &left, const R &rigth)
Definition: tfadop.h:248
const value_type dx(int i) const
Definition: tfadop.h:357
~TFadBinaryPow()
Definition: tfadop.h:353
value_type dx(int i) const
Definition: tfadop.h:452
TFadBinaryPow(const L &left, const R &rigth)
Definition: tfadop.h:447
L::value_type value_type
Definition: tfadop.h:438
value_type fastAccessDx(int i) const
Definition: tfadop.h:135
int size() const
Definition: tfadop.h:279
~TFadBinaryMinus()
Definition: tfadop.h:124
L::value_type value_type_L
Definition: tfadop.h:31
value_type fastAccessDx(int i) const
Definition: tfadop.h:285
int size() const
Definition: tfad.h:421
TFadBinaryMinus(const L &left, const R &rigth)
Definition: tfadop.h:123
~TFadBinaryDiv()
Definition: tfadop.h:274
TFadBinaryDiv(const L &left, const R &rigth)
Definition: tfadop.h:301
L::value_type value_type_L
Definition: tfadop.h:113
const value_type dx(int i) const
Definition: tfadop.h:47
TFadBinaryMinus(const L &left, const R &rigth)
Definition: tfadop.h:150
TFadBinaryPow(const L &left, const R &rigth)
Definition: tfadop.h:418
TFadBinaryMinus(const L &left, const R &rigth)
Definition: tfadop.h:174
const value_type val() const
Definition: tfadop.h:127
bool hasFastAccess() const
Definition: tfadop.h:134
TFadBinaryDiv()
Definition: tfadop.h:268
NumericalTraits< value_type_L, value_type_R >::promote value_type
Definition: tfadop.h:265
const value_type dx(int i) const
Definition: tfadop.h:278
NumericalTraits< value_type_L, value_type_R >::promote value_type
Definition: tfadop.h:34
const value_type val() const
Definition: tfadop.h:451
R::value_type value_type_R
Definition: tfadop.h:32
L::value_type value_type_L
Definition: tfadop.h:341
NumericalTraits< value_type_L, value_type_R >::promote value_type
Definition: tfadop.h:115
const R & right_
Definition: tfadop.h:270
const R & right_
Definition: tfadop.h:197
const value_type & val() const
Definition: tfad.h:419
TFadBinaryPow(const L &left, const R &rigth)
Definition: tfadop.h:352
R::value_type value_type_R
Definition: tfadop.h:191
const value_type val() const
Definition: tfadop.h:203
TFadBinaryMul(const L &left, const R &rigth)
Definition: tfadop.h:226
bool hasFastAccess() const
Definition: tfadop.h:458
int size() const
Definition: tfadop.h:205
NumericalTraits< value_type_L, value_type_R >::promote value_type
Definition: tfadop.h:192
int size() const
Definition: tfadop.h:48
const R & right_
Definition: tfadop.h:349
R::value_type value_type_R
Definition: tfadop.h:114
TFadBinaryMul()
Definition: tfadop.h:195
const value_type val() const
Definition: tfadop.h:46
TFadBinaryDiv(const L &left, const R &rigth)
Definition: tfadop.h:325
Definition: tfad.h:42
TFadBinaryMul(const L &left, const R &rigth)
Definition: tfadop.h:200
bool hasFastAccess() const
Definition: tfadop.h:367
value_type fastAccessDx(int i) const
Definition: tfadop.h:211
const value_type dx(int i) const
Definition: tfadop.h:128
TFadBinaryDiv(const L &left, const R &rigth)
Definition: tfadop.h:273
L::value_type value_type_L
Definition: tfadop.h:190
TFadBinaryPow()
Definition: tfadop.h:347
TPZFlopCounter pow(const TPZFlopCounter &orig, const TPZFlopCounter &xp)
Returns the power and increments the counter of the power.
Definition: pzreal.h:487
bool hasFastAccess() const
Definition: tfadop.h:53
int size() const
Definition: tfadop.h:129
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ log
Definition: tfadfunc.h:130
L::value_type value_type_L
Definition: tfadop.h:263
const value_type dx(int i) const
Definition: tfadop.h:204
#define FAD_BIN_MACRO(OP, TYPE)
Definition: tfadop.h:467
TFadBinaryAdd(const L &left, const R &rigth)
Definition: tfadop.h:42
const R & right_
Definition: tfadop.h:120
int size() const
Definition: tfadop.h:362
R::value_type value_type_R
Definition: tfadop.h:264
int size() const
Definition: tfadop.h:456
~TFadBinaryAdd()
Definition: tfadop.h:43
const L & left_
Definition: tfadop.h:39
TFadBinaryAdd()
Definition: tfadop.h:37
value_type fastAccessDx(int i) const
Definition: tfadop.h:459
value_type fastAccessDx(int i) const
Definition: tfadop.h:54
const R & right_
Definition: tfadop.h:39
NumericalTraits< value_type_L, value_type_R >::promote value_type
Definition: tfadop.h:344
TFadBinaryAdd(const L &left, const R &rigth)
Definition: tfadop.h:69
TFadCst< int > R
Definition: tfadop.h:439
~TFadBinaryMul()
Definition: tfadop.h:201