Logo  0.95.0-final
Finite Element Embedded Library and Language in C++
Feel++ Feel++ on Github Feel++ community
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
adoperators.hpp
Go to the documentation of this file.
1 /* -*- mode: c++; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; show-trailing-whitespace: t -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
2 
3  This file is part of the Feel library
4 
5  Author(s): Christophe Prud'homme <christophe.prudhomme@feelpp.org>
6  Date: 2008-02-14
7 
8  Copyright (C) 2008-2011 Université Joseph Fourier (Grenoble I)
9 
10  This library is free software; you can redistribute it and/or
11  modify it under the terms of the GNU Lesser General Public
12  License as published by the Free Software Foundation; either
13  version 3.0 of the License, or (at your option) any later version.
14 
15  This library is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public
21  License along with this library; if not, write to the Free Software
22  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
29 #ifndef __ADOperators_H
30 #define __ADOperators_H 1
31 
32 #include <feel/feelopt/adexpr.hpp>
33 
34 
35 namespace Feel
36 {
37 //------------------------------- Ad binary operators ------------------------------------------
38 
39 
40 //------------------------------- Ad addition operators ------------------------------------------
41 template <class L, class R>
42 class ADBinaryAdd
43 {
44 public:
45  enum { nvar = L::nvar };
46  typedef typename L::value_type value_type_L;
47 
48  typedef typename R::value_type value_type_R;
49 
50  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type;
51 
52 protected:
53  ADBinaryAdd() {}
54 
55  const L& __left;
56  const R& __right;
57 
58 public:
59  ADBinaryAdd( const L& left, const R& rigth ) : __left( left ), __right( rigth )
60  {
61  ;
62  }
63  ~ADBinaryAdd()
64  {
65  ;
66  }
67 
68 
69  value_type value() const
70  {
71  return __left.value() + __right.value();
72  }
73  value_type grad( int __i ) const
74  {
75  return __left.grad( __i ) + __right.grad( __i );
76  }
77  value_type hessian( int __i, int __j ) const
78  {
79  return __left.hessian( __i, __j ) + __right.hessian( __i, __j );
80  }
81 
82 
83  bool deps( int i ) const
84  {
85  return __left.deps( i ) || __right.deps( i );
86  }
87 };
88 
89 #define AD_BIN_ADD_CST(TYPE) \
90 template <class L> \
91 class ADBinaryAdd<L, ADCst<TYPE> > \
92 { \
93 public: \
94  enum { nvar = L::nvar }; \
95  \
96  typedef typename L::value_type value_type_L; \
97  typedef TYPE value_type_R; \
98  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type; \
99  typedef ADCst<TYPE> R; \
100  \
101 protected: \
102  ADBinaryAdd() {} \
103  \
104  const L& __left; const R __right; \
105  \
106 public: \
107  ADBinaryAdd(const L& left, const R& rigth) : __left(left), __right(rigth) {;} \
108  ~ADBinaryAdd() {;} \
109  \
110  \
111  value_type value() const {return __left.value() + __right.value();} \
112  value_type grad( int __i ) const {return __left.grad( __i );} \
113  value_type hessian( int __i, int __j ) const {return __left.hessian(__i, __j);} \
114  \
115  bool deps( int i ) const { return __left.deps( i ); } \
116 }; \
117  \
118  \
119 template <class R> \
120 class ADBinaryAdd< ADCst<TYPE>, R> \
121 { \
122 public: \
123  enum { nvar = R::nvar }; \
124  \
125  typedef TYPE value_type_L; \
126  typedef typename R::value_type value_type_R; \
127  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type; \
128  typedef ADCst<TYPE> L; \
129  \
130 protected: \
131  ADBinaryAdd() {} \
132  \
133  const L __left; const R& __right; \
134  \
135 public: \
136  ADBinaryAdd(const L& left, const R& rigth) : __left(left), __right(rigth) {;} \
137  ~ADBinaryAdd() {;} \
138  \
139  \
140  value_type value() const {return __left.value() + __right.value();} \
141  value_type grad( int __i ) const {return __right.grad( __i );} \
142  value_type hessian( int __i, int __j ) const {return __right.hessian( __i, __j);} \
143  \
144  bool deps( int i ) const { return __right.deps( i ); } \
145 };
146 
147 AD_BIN_ADD_CST( int )
148 AD_BIN_ADD_CST( long int )
149 AD_BIN_ADD_CST( float )
150 AD_BIN_ADD_CST( double )
151 AD_BIN_ADD_CST( long double )
152 
153 #undef AD_BIN_ADD_CST
154 
155 //------------------------------- AD substraction operators ------------------------------------------
156 template <class L, class R>
157 class ADBinarySubtract
158 {
159 public:
160  enum { nvar = L::nvar };
161  typedef typename L::value_type value_type_L;
162  typedef typename R::value_type value_type_R;
163  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type;
164 
165 protected:
166  ADBinarySubtract() {}
167 
168  const L& __left;
169  const R& __right;
170 
171 public:
172  ADBinarySubtract( const L& left, const R& rigth ) : __left( left ), __right( rigth )
173  {
174  ;
175  }
176  ~ADBinarySubtract()
177  {
178  ;
179  }
180 
181 
182  value_type value() const
183  {
184  return __left.value() - __right.value();
185  }
186  value_type grad( int __i ) const
187  {
188  return __left.grad( __i ) - __right.grad( __i );
189  }
190  value_type hessian( int __i, int __j ) const
191  {
192  return __left.hessian( __i, __j ) - __right.hessian( __i, __j );
193  }
194 
195  bool deps( int i ) const
196  {
197  return __left.deps( i ) || __right.deps( i );
198  }
199 };
200 
201 #define AD_BIN_SUB_CST(TYPE) \
202 template <class L> \
203 class ADBinarySubtract<L, ADCst<TYPE> > \
204 { \
205 public: \
206  \
207  enum { nvar = L::nvar }; \
208  \
209  typedef typename L::value_type value_type_L; \
210  typedef TYPE value_type_R; \
211  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type; \
212  typedef ADCst<TYPE> R; \
213  \
214  \
215 protected: \
216  ADBinarySubtract() {} \
217  \
218  const L& __left; const R __right; \
219  \
220 public: \
221  ADBinarySubtract(const L& left, const R & rigth) : __left(left), __right(rigth) {;} \
222  ~ADBinarySubtract() {;} \
223  \
224  \
225  value_type value() const {return __left.value() - __right.value();} \
226  value_type grad( int __i) const {return __left.grad(__i);} \
227  value_type hessian( int __i, int __j ) const {return __left.hessian( __i, __j);} \
228  bool deps( int i ) const { return __left.deps( i ); } \
229 }; \
230  \
231  \
232 template <class R> \
233 class ADBinarySubtract< ADCst<TYPE>, R> \
234 { \
235 public: \
236  enum { nvar = R::nvar }; \
237  \
238  typedef TYPE value_type_L; \
239  typedef typename R::value_type value_type_R; \
240  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type; \
241  typedef ADCst<TYPE> L; \
242  \
243 protected: \
244  ADBinarySubtract() {} \
245  \
246  const L __left; const R& __right; \
247  \
248 public: \
249  ADBinarySubtract(const L& left, const R& rigth) : __left(left), __right(rigth) {;} \
250  ~ADBinarySubtract() {;} \
251  \
252  \
253  value_type value() const {return __left.value() - __right.value();} \
254  value_type grad(int __i) const {return - __right.grad(__i);} \
255  value_type hessian( int __i, int __j ) const {return - __right.hessian( __i, __j);} \
256  bool deps( int i ) const { return __right.deps( i ); } \
257 };
258 
259 AD_BIN_SUB_CST( int )
260 AD_BIN_SUB_CST( long int )
261 AD_BIN_SUB_CST( float )
262 AD_BIN_SUB_CST( double )
263 AD_BIN_SUB_CST( long double )
264 
265 #undef AD_BIN_SUB_CST
266 
267 //------------------------------- AD multiplication operators ------------------------------------------
268 template <class L, class R>
269 class ADBinaryMultiply
270 {
271 public:
272  enum { nvar = R::nvar };
273  typedef typename L::value_type value_type_L;
274  typedef typename R::value_type value_type_R;
275  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type;
276 
277 protected:
278  ADBinaryMultiply() {}
279 
280  const L& __left;
281  const R& __right;
282 
283 public:
284  ADBinaryMultiply( const L& left, const R& rigth ) : __left( left ), __right( rigth )
285  {
286  ;
287  }
288  ~ADBinaryMultiply()
289  {
290  ;
291  }
292 
293  value_type value() const
294  {
295  return __left.value() * __right.value() ;
296  }
297  value_type grad( int i ) const
298  {
299  return __left.grad( i ) * __right.value() + __right.grad( i ) * __left.value();
300  }
301  value_type hessian( int __i, int __j ) const
302  {
303  return ( __left.hessian( __i, __j )*__right.value() + __left.grad( __i ) * __right.grad( __j ) +
304  __left.grad( __j ) * __right.grad( __i ) + __left.value()*__right.hessian( __i, __j ) );
305  }
306 
307  bool deps( int i ) const
308  {
309  return __left.deps( i ) || __right.deps( i );
310  }
311 };
312 
313 #define AD_BIN_MUL_CST(TYPE) \
314 template <class L> \
315 class ADBinaryMultiply<L, ADCst<TYPE> > \
316 { \
317 public: \
318  \
319  enum { nvar = L::nvar }; \
320  \
321  typedef typename L::value_type value_type_L; \
322  typedef TYPE value_type_R; \
323  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type; \
324  typedef ADCst<TYPE> R; \
325  \
326 protected: \
327  ADBinaryMultiply() {} \
328  \
329  const L& __left; const R __right; \
330  \
331 public: \
332  ADBinaryMultiply(const L& left, const R& rigth) : __left(left), __right(rigth) {;} \
333  ~ADBinaryMultiply() {;} \
334  \
335  value_type value() const {return __left.value() * __right.value() ;} \
336  value_type grad(int i) const {return __left.grad(i) * __right.value();} \
337  value_type hessian(int i, int j) const {return __left.hessian(i,j) * __right.value();} \
338  bool deps( int i ) const { return __left.deps( i ); } \
339 }; \
340  \
341 template <class R> \
342 class ADBinaryMultiply< ADCst<TYPE>, R> \
343 { \
344 public: \
345  \
346  enum { nvar = R::nvar }; \
347  \
348  typedef TYPE value_type_L; \
349  typedef typename R::value_type value_type_R; \
350  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type; \
351  typedef ADCst<TYPE> L; \
352  \
353 protected: \
354  ADBinaryMultiply() {} \
355  \
356  const L __left; const R& __right; \
357  \
358 public: \
359  ADBinaryMultiply(const L& left, const R& rigth) : __left(left), __right(rigth) {;} \
360  ~ADBinaryMultiply() {;} \
361  \
362  value_type value() const {return __left.value() * __right.value() ;} \
363  value_type grad(int i) const {return __right.grad(i) * __left.value();} \
364  value_type hessian(int i, int j) const {return __right.hessian(i,j) * __left.value();} \
365  bool deps( int i ) const { return __right.deps( i ); } \
366 };
367 
368 AD_BIN_MUL_CST( int )
369 AD_BIN_MUL_CST( long int )
370 AD_BIN_MUL_CST( float )
371 AD_BIN_MUL_CST( double )
372 AD_BIN_MUL_CST( long double )
373 
374 #undef AD_BIN_MUL_CST
375 
376 //------------------------------- AD division operators ------------------------------------------
377 template <class L, class R> class ADBinaryDivide
378 {
379 public:
380  enum { nvar = R::nvar };
381  typedef typename L::value_type value_type_L;
382  typedef typename R::value_type value_type_R;
383  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type;
384 
385 protected:
386  ADBinaryDivide() {}
387 
388  const L& __left;
389  const R& __right;
390 
391 public:
392  ADBinaryDivide( const L& left, const R& rigth ) : __left( left ), __right( rigth )
393  {
394  ;
395  }
396  ~ADBinaryDivide()
397  {
398  ;
399  }
400 
401 
402  value_type value() const
403  {
404  return __left.value() / __right.value();
405  }
406  value_type grad( int i ) const
407  {
408  return ( __left.grad( i ) / __right.value() ) - __right.grad( i ) * __left.value() / ( __right.value() * __right.value() ) ;
409  }
410 
411  value_type hessian( int __i, int __j ) const
412  {
413  return -( - __left.hessian( __i,__j )*__right.value()*__right.value() +
414  __left.grad( __j )* __right.grad( __i ) * __right.value() +
415  __left.grad( __i )* __right.grad( __j ) * __right.value() -
416  value_type( 2.0 ) * __left.value()* __right.grad( __i ) * __right.grad( __j ) +
417  __left.value() * __right.value() * __right.hessian( __i, __j ) ) / ( __right.value()*__right.value()*__right.value() );
418  };
419 
420  bool deps( int i ) const
421  {
422  return __left.deps( i ) || __right.deps( i );
423  }
424 };
425 
426 #define AD_BIN_DIV_CST(TYPE) \
427 template <class L> \
428 class ADBinaryDivide<L, ADCst<TYPE> > \
429 { \
430  public: \
431  \
432  enum { nvar = L::nvar }; \
433  \
434  typedef typename L::value_type value_type_L; \
435  typedef TYPE value_type_R; \
436  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type; \
437  typedef ADCst<TYPE> R; \
438  \
439 protected: \
440  ADBinaryDivide() {} \
441  \
442  const L& __left; const R __right; \
443  \
444  public: \
445  ADBinaryDivide(const L& left, const R& rigth) : __left(left), __right(rigth) {;} \
446  ~ADBinaryDivide() {;} \
447  \
448  \
449  value_type value() const {return __left.value() / __right.value();} \
450  value_type grad(int i) const {return __left.grad(i) / __right.value();} \
451  value_type hessian(int i, int j) const {return __left.hessian(i,j) / __right.value();} \
452  bool deps( int i ) const { return __left.deps( i ); } \
453 }; \
454  \
455 template <class R> \
456 class ADBinaryDivide< ADCst<TYPE>, R> \
457 { \
458 public: \
459  \
460  enum { nvar = R::nvar }; \
461  \
462  typedef TYPE value_type_L; \
463  typedef typename R::value_type value_type_R; \
464  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type; \
465  typedef ADCst<TYPE> L; \
466  \
467 protected: \
468  ADBinaryDivide() {} \
469  \
470  const L __left; const R& __right; \
471  \
472 public: \
473  ADBinaryDivide(L left, const R& right) : __left(left), __right(right) {;} \
474  ~ADBinaryDivide() {;} \
475  \
476  value_type value() const {return __left.value() / __right.value();} \
477  value_type grad(int i) const {return (- __right.grad(i) * __left.value() ) / (__right.value() * __right.value()) ;} \
478  value_type hessian(int __i, int __j) const \
479  { return __left.value() * \
480  ( 2 *__right.grad(__i)*__right.grad(__j) - __right.value()*__right.hessian(__i,__j) )/ \
481  std::pow(__right.value(),3.); \
482  }; \
483  bool deps( int i ) const { return __right.deps( i ); } \
484 };
485 
486 AD_BIN_DIV_CST( int )
487 AD_BIN_DIV_CST( long int )
488 AD_BIN_DIV_CST( float )
489 AD_BIN_DIV_CST( double )
490 AD_BIN_DIV_CST( long double )
491 
492 #undef AD_BIN_DIV_CST
493 
494 
495 //------------------------------- AD pow function ------------------------------------------
496 template <class L, class R>
497 class ADBinaryPow
498 {
499 public:
500  enum { nvar = R::nvar };
501  typedef typename L::value_type value_type_L;
502  typedef typename R::value_type value_type_R;
503 
504  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type;
505 
506 protected:
507  ADBinaryPow() {}
508 
509  const L& __left;
510  const R& __right;
511 
512 public:
513  ADBinaryPow( const L& left, const R& rigth ) : __left( left ), __right( rigth )
514  {
515  ;
516  }
517  ~ADBinaryPow()
518  {
519  ;
520  }
521 
522 
523  value_type value() const
524  {
525  return std::pow( __left.value(), __right.value() );
526  }
527  value_type grad( int i ) const
528  {
529  return ( __right.grad( i )*std::log( __left.value() )+__right.value()*__left.grad( i )/__left.value() )
530  *std::pow( __left.value(), __right.value() );
531  }
532 
533  bool deps( int i ) const
534  {
535  return __left.deps( i ) || __right.deps( i );
536  }
537 };
538 
539 
540 template <class L>
541 class ADBinaryPow<L, ADCst<typename L::value_type> >
542 {
543 public:
544  enum { nvar = L::nvar };
545  typedef typename L::value_type value_type;
546  typedef ADCst<value_type> R;
547 
548 protected:
549  ADBinaryPow() {}
550 
551  const L& __left;
552  const R __right;
553 
554 public:
555  ADBinaryPow( const L& left, const R& rigth ) : __left( left ), __right( rigth )
556  {
557  ;
558  }
559  ~ADBinaryPow()
560  {
561  ;
562  }
563 
564 
565  value_type value() const
566  {
567  return std::pow( __left.value(),__right.value() ) ;
568  }
569  value_type grad( int i ) const
570  {
571  return ( __right.value()*__left.grad( i )/__left.value() )*std::pow( __left.value(), __right.value() );
572  }
573  value_type hessian( int i, int j ) const
574  {
575  //return std::pow(__left.value(),__right.value())*std::pow(__right.value(),2)*__left.grad(i)*__left.grad(j)/std::pow(__left.value(),2) + std::pow(__left.value(),__right.value())*__right.value()*__left.hessian(i,j)/__left.value() - std::pow(__left.value(),__right.value())*__right.value()*
576  }
577  bool deps( int i ) const
578  {
579  return __left.deps( i );
580  }
581 };
582 
583 
584 template <class R>
585 class ADBinaryPow< ADCst<typename R::value_type>, R>
586 {
587 public:
588  enum { nvar = R::nvar };
589  typedef typename R::value_type value_type;
590  typedef ADCst<value_type> L;
591 
592 protected:
593  ADBinaryPow() {}
594 
595  const L __left;
596  const R& __right;
597 
598 public:
599  ADBinaryPow( const L& left, const R& rigth ) : __left( left ), __right( rigth )
600  {
601  ;
602  }
603  ~ADBinaryPow()
604  {
605  ;
606  }
607 
608  const value_type value() const
609  {
610  return std::pow( __left.value(),__right.value() );
611  }
612  value_type grad( int i ) const
613  {
614  return ( __right.grad( i )*std::log( __left.value() ) )*std::pow( __left.value(), __right.value() );
615  }
616 
617  value_type hessian( int i, int j ) const
618  {
619  return std::pow( __left.value(),__right.value()-2.0 )*__right.value()*__right.value()*__left.grad( i )*__left.grad( j ) +
620  std::pow( __left.value(),__right.value()-1.0 )*__right.value()*__left.hessian( i,j ) -
621  std::pow( __left.value(),__right.value()-2.0 )*__right.value()*__left.grad( i )*__left.grad( j );
622  }
623  bool deps( int i ) const
624  {
625  return __right.deps( i );
626  }
627 };
628 
629 template <class L>
630 class ADBinaryPow< L , ADCst<int> >
631 {
632 public:
633  enum { nvar = L::nvar };
634 
635  typedef typename L::value_type value_type;
636  typedef ADCst<int> R;
637 
638 protected:
639  ADBinaryPow() {}
640 
641  const L& __left;
642  const R __right;
643 
644 public:
645  ADBinaryPow( const L& left, const R& rigth ) : __left( left ), __right( rigth )
646  {
647  ;
648  }
649  ~ADBinaryPow()
650  {
651  ;
652  }
653 
654  template<int isFundamental, typename L_, typename R_>
655  struct Value
656  {
657  typedef typename L_::value_type value_type;
658  static value_type value( L_ const& __left, R_ const& __right )
659  {
660  return pow( __left.value(),__right.value() );
661  }
662  static value_type grad( L_ const& __left, R_ const& __right, int __i )
663  {
664  return value_type( __right.value() )*pow( __left.value(), __right.value()-1 );
665  }
666  static value_type hessian( L_ const& __left, R_ const& __right, int i, int j )
667  {
668  return pow( __left.value(),__right.value()-2.0 )*__right.value()*__right.value()*__left.grad( i )*__left.grad( j ) +
669  pow( __left.value(),__right.value()-1.0 )*__right.value()*__left.hessian( i,j ) -
670  pow( __left.value(),__right.value()-2.0 )*__right.value()*__left.grad( i )*__left.grad( j );
671  }
672  };
673  template<typename L_, typename R_>
674  struct Value<1, L_, R_>
675  {
676  typedef typename L_::value_type value_type;
677  static value_type value( L_ const& __left, R_ const& __right )
678  {
679  return std::pow( __left.value(),__right.value() );
680  }
681  static value_type grad( L_ const& __left, R_ const& __right, int __i )
682  {
683  return __right.value()*std::pow( __left.value(), __right.value()-1 );
684  }
685  static value_type hessian( L_ const& __left, R_ const& __right, int i, int j )
686  {
687  return std::pow( __left.value(),__right.value()-2.0 )*__right.value()*__right.value()*__left.grad( i )*__left.grad( j ) +
688  std::pow( __left.value(),__right.value()-1.0 )*__right.value()*__left.hessian( i,j ) -
689  std::pow( __left.value(),__right.value()-2.0 )*__right.value()*__left.grad( i )*__left.grad( j );
690  }
691  };
692  value_type value() const
693  {
694  return Value<true,L,R>::value( __left, __right );
695  }
696  value_type grad( int i ) const
697  {
698  return Value<true,L,R>::grad( __left, __right, i );
699  }
700  value_type hessian( int i, int j ) const
701  {
702  return Value<true,L,R>::hessian( __left, __right, i, j );;
703  }
704  bool deps( int i ) const
705  {
706  return __left.deps( i );
707  }
708 };
709 
710 
711 //------------------------------- AD Greater function ------------------------------------------
712 #define AD_BIN_REL_CST(Rel, OP,TYPE) \
713 template <class L> \
714 class ADBinary ##Rel <L, ADCst<TYPE> > \
715 { \
716  public: \
717  \
718  enum { nvar = L::nvar }; \
719  \
720  typedef typename L::value_type value_type_L; \
721  typedef TYPE value_type_R; \
722  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type; \
723  typedef ADCst<TYPE> R; \
724  \
725 protected: \
726  ADBinary ##Rel () {} \
727  \
728  const L& __left; const R __right; \
729  \
730  public: \
731  ADBinary ##Rel (const L& left, const R& rigth) : __left(left), __right(rigth) {;} \
732  ~ADBinary ##Rel () {;} \
733  \
734  \
735  value_type value() const { return __left.value() OP __right.value(); } \
736  value_type grad(int i) const { return __left.value() OP __right.value(); } \
737  value_type hessian(int i, int j) const { return __left.value() OP __right.value(); } \
738  bool deps( int i ) const { return __left.deps( i ); } \
739 }; \
740  \
741 template <class R> \
742 class ADBinary ##Rel < ADCst<TYPE>, R> \
743 { \
744 public: \
745  \
746  enum { nvar = R::nvar }; \
747  \
748  typedef TYPE value_type_L; \
749  typedef typename R::value_type value_type_R; \
750  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type; \
751  typedef ADCst<TYPE> L; \
752  \
753 protected: \
754  ADBinary ##Rel () {} \
755  \
756  const L __left; const R& __right; \
757  \
758 public: \
759  ADBinary ##Rel (L left, const R& right) : __left(left), __right(right) {;} \
760  ~ADBinary ##Rel () {;} \
761  \
762  value_type value() const { return __left.value() OP __right.value(); } \
763  value_type grad(int i) const { return __left.value() OP __right.value(); } \
764  value_type hessian(int i, int j) const { return __left.value() OP __right.value(); } \
765  bool deps( int i ) const { return __right.deps( i ); } \
766 };
767 
768 #define AD_BIN_REL( Rel, OP ) \
769 template <class L, class R> \
770 class ADBinary ##Rel \
771 { \
772 public: \
773  enum { nvar = R::nvar }; \
774  typedef typename L::value_type value_type_L; \
775  typedef typename R::value_type value_type_R; \
776  \
777  typedef typename SNumericalTraits<value_type_L,value_type_R>::promote value_type; \
778  \
779 protected: \
780  ADBinary ##Rel () {} \
781  \
782  const L& __left; const R& __right; \
783  \
784 public: \
785  ADBinary ##Rel (const L& left, const R& rigth) : __left(left), __right(rigth) {;} \
786  ~ADBinary ##Rel () {;} \
787  \
788  \
789  value_type value() const {return __left.value() OP __right.value();} \
790  value_type grad(int i) const { return __left.value() OP __right.value(); } \
791  value_type hessian(int i, int j) const { return __left.value() OP __right.value(); } \
792  \
793  bool deps( int i ) const { return __left.deps( i ) || __right.deps( i ); } \
794 }; \
795 AD_BIN_REL_CST( Rel, OP, int) \
796 AD_BIN_REL_CST( Rel, OP, long int) \
797 AD_BIN_REL_CST( Rel, OP, float) \
798 AD_BIN_REL_CST( Rel, OP, double) \
799 AD_BIN_REL_CST( Rel, OP, long double)
800 
801 AD_BIN_REL( Greater, > )
802 AD_BIN_REL( Less, < )
803 AD_BIN_REL( GreaterOrEqual, >= )
804 AD_BIN_REL( LessOrEqual, <= )
805 AD_BIN_REL( Equal, == )
806 AD_BIN_REL( NotEqual, != )
807 
808 #undef AD_BIN_REL
809 #undef AD_BIN_REL_CST
810 
812 }
813 
814 #endif
815 

Generated on Fri Oct 25 2013 14:24:03 for Feel++ by doxygen 1.8.4