ReFRACtor
auto_derivative.h
Go to the documentation of this file.
1 #ifndef AUTO_DERIVATIVE_H
2 #define AUTO_DERIVATIVE_H
3 #include "fp_exception.h"
4 #include "printable.h"
5 #include <cmath>
6 #include <boost/operators.hpp>
7 #include <boost/foreach.hpp>
8 
9 // Because of the way blitz expands things, we need to declare these
10 // functions before including blitz.
11 namespace FullPhysics {
12  template<class T> class AutoDerivative;
13 }
14 namespace std { // Math functions are in std:: namespace.
36 pow(const FullPhysics::AutoDerivative<double>& x, const double y);
38 pow(const double x, const FullPhysics::AutoDerivative<double>& y);
39 }
40 namespace blitz {
43 }
44 #include <blitz/array.h>
45 
46 namespace FullPhysics {
47 /****************************************************************/
51 template<class T> class AutoDerivativeRef :
52 public Printable<AutoDerivativeRef<T> >
53 {
54 public:
55  AutoDerivativeRef(T& V, const blitz::Array<T, 1>& G)
56  : v(V), grad(G)
57  { }
59  : v(V)
60  { }
61  // This is const because although the values change, the reference doesn't
63  {
64  v = D.value();
65  if(D.is_constant())
66  grad = 0;
67  else if(grad.rows() == D.gradient().rows())
68  grad = D.gradient();
69  else {
70  Exception e;
71  e << "Size of gradient in AutoDerivative doesn't match value you "
72  << "are trying to assign. Size of destination is " << grad.rows()
73  << " and size of source is " << D.gradient().rows();
74  throw e;
75  }
76  return *this;
77  }
78  T& value_ref() const {return v;}
79  blitz::Array<T, 1>& gradient_ref() const {return grad; }
80  T value() const {return v;}
81  const blitz::Array<T, 1>& gradient() const {return grad; }
83  const AutoDerivativeRef<T>& Y)
84  { AutoDerivative<T> r(X);
85  r+= Y;
86  return r;
87  }
89  const AutoDerivativeRef<T>& Y)
90  { AutoDerivative<T> r(X);
91  r-= Y;
92  return r;
93  }
95  { AutoDerivative<T> r(X);
96  r*= -1;
97  return r;
98  }
100  const AutoDerivativeRef<T>& Y)
101  { AutoDerivative<T> r(X);
102  r*= Y;
103  return r;
104  }
106  const AutoDerivativeRef<T>& Y)
107  { AutoDerivative<T> r(X);
108  r/= Y;
109  return r;
110  }
112  const T& Y)
113  { AutoDerivative<T> r(X);
114  r+= Y;
115  return r;
116  }
118  const T& Y)
119  { AutoDerivative<T> r(X);
120  r-= Y;
121  return r;
122  }
124  const T& Y)
125  { AutoDerivative<T> r(X);
126  r*= Y;
127  return r;
128  }
130  const T& Y)
131  { AutoDerivative<T> r(X);
132  r/= Y;
133  return r;
134  }
135  friend AutoDerivative<T> operator+(const T& X,
136  const AutoDerivativeRef<T>& Y)
137  { AutoDerivative<T> r(Y);
138  r+= X;
139  return r;
140  }
141  friend AutoDerivative<T> operator-(const T& X,
142  const AutoDerivativeRef<T>& Y)
143  { AutoDerivative<T> r(X);
144  r-= Y;
145  return r;
146  }
147  friend AutoDerivative<T> operator*(const T& X,
148  const AutoDerivativeRef<T>& Y)
149  { AutoDerivative<T> r(Y);
150  r*= X;
151  return r;
152  }
153  friend AutoDerivative<T> operator/(const T& X,
154  const AutoDerivativeRef<T>& Y)
155  { AutoDerivative<T> r(X);
156  r/= Y;
157  return r;
158  }
159  void print(std::ostream& Os) const
160  { Os << "AutoDerivativeRef\n"
161  << " Value: " << value() << "\n"
162  << " Gradient:\n" << gradient() << "\n";
163  }
164 private:
165  T& v;
166  // We can assign to grad because although the value changes the
167  // reference doesn't
168  mutable blitz::Array<T, 1> grad;
169 };
170 
171 /****************************************************************/
206 template<class T> class AutoDerivative:
207 public Printable<AutoDerivative<T> >,
208 boost::totally_ordered<class AutoDerivative<T> >,
209 boost::totally_ordered<class AutoDerivative<T>, T>
210 {
211 public:
212  typedef T value_type;
213 
214 //-----------------------------------------------------------------------
216 //-----------------------------------------------------------------------
217 
219 
220 //-----------------------------------------------------------------------
224 //-----------------------------------------------------------------------
225 
226  AutoDerivative(const T& Val, const blitz::Array<T, 1>& G)
227  : val(Val), grad(G) {}
228 
229 //-----------------------------------------------------------------------
231 //-----------------------------------------------------------------------
233  : val(V.value()), grad(V.gradient().copy()) { }
234 
235 //-----------------------------------------------------------------------
238 //-----------------------------------------------------------------------
239 
240  AutoDerivative(const T& Val, int i_th, int nvars)
241  : val(Val), grad(nvars)
242  {
243  range_check(i_th, 0, nvars);
244  grad = 0;
245  grad(i_th) = 1;
246  }
247 
248 //-----------------------------------------------------------------------
250 //-----------------------------------------------------------------------
251 
252  AutoDerivative(const T& Val)
253  : val(Val)
254  {
255  }
256 
257 //-----------------------------------------------------------------------
259 //-----------------------------------------------------------------------
260 
262  : val(D.val), grad(D.grad.copy())
263  {
264  }
265 
266 //-----------------------------------------------------------------------
268 //-----------------------------------------------------------------------
269 
271  {
272  val = D.val;
273  // Copy the data into existing gradient if it fits
274  if(grad.rows() == D.grad.rows())
275  grad = D.grad;
276  else
277  grad.reference(D.grad.copy());
278  return *this;
279  }
280 
281 //-----------------------------------------------------------------------
283 //-----------------------------------------------------------------------
284 
286  { return AutoDerivative<T>(value(), gradient().copy()); }
287 
288 //-----------------------------------------------------------------------
290 //-----------------------------------------------------------------------
291 
292  const T& value() const {return val;}
293  T& value() {return val;}
294 
295 //-----------------------------------------------------------------------
297 //-----------------------------------------------------------------------
298 
299  const blitz::Array<T, 1>& gradient() const { return grad; }
300  blitz::Array<T, 1>& gradient() { return grad; }
301 
302 //-----------------------------------------------------------------------
304 //-----------------------------------------------------------------------
305 
306  int number_variable() const {return grad.rows();}
307 
308 //-----------------------------------------------------------------------
310 //-----------------------------------------------------------------------
311 
312  bool is_constant() const { return number_variable() == 0; }
313 
314 //-----------------------------------------------------------------------
315 // Operators needed by boost to give all the arithmetic operators.
316 //-----------------------------------------------------------------------
317 
318  bool operator<(const AutoDerivative<T>& V) const {return val < V.val;}
319  bool operator<(const T& V) const {return val < V;}
320  bool operator>(const AutoDerivative<T>& V) const {return val > V.val;}
321  bool operator>(const T& V) const {return val > V;}
322  bool operator==(const AutoDerivative<T>& V) const {return val == V.val;}
323  bool operator==(const T& V) const {return val == V;}
325  {
326  val += V.val;
327  // Handling for V or self actually being a constant, which means
328  // we have a zero size gradient.
329  if(!V.is_constant()) {
330  if(!is_constant())
331  grad += V.grad;
332  else
333  grad.reference(V.grad.copy());
334  }
335  return *this;
336  }
338  { val += V; return *this;}
340  { val -= V.val;
341  // Handling for V or self actually being a constant, which means
342  // we have a zero size gradient.
343  if(!V.is_constant()) {
344  if(!is_constant())
345  grad -= V.grad;
346  else {
347  grad.resize(V.grad.shape());
348  grad = -V.grad;
349  }
350  }
351  return *this;
352  }
354  { val -= V; return *this;}
356  {
357  // Handling for V or self actually being a constant, which means
358  // we have a zero size gradient.
359  if(!V.is_constant()) {
360  if(!is_constant())
361  grad = V.val * grad + val * V.grad;
362  else {
363  grad.reference(V.grad.copy());
364  grad *= val;
365  }
366  } else
367  grad *= V.val;
368  val *= V.val;
369  return *this;
370  }
372  { val *= V; grad *= V; return *this;}
374  {
375  // Handling for V or self actually being a constant, which means
376  // we have a zero size gradient.
377  if(!V.is_constant()) {
378  if(!is_constant())
379  grad = 1 / V.val * grad - val / (V.val * V.val) * V.grad;
380  else {
381  grad.resize(V.grad.shape());
382  grad = - val / (V.val * V.val) * V.grad;
383  }
384  } else
385  grad /= V.val;
386  val /= V.val;
387  return *this;
388  }
390  { val /= V; grad /= V; return *this;}
391  void print(std::ostream& Os) const
392  { Os << "AutoDerivative\n"
393  << " Value: " << val << "\n"
394  << " Gradient:\n" << grad << "\n";
395  }
397  const AutoDerivative<T>& Y)
398  { AutoDerivative<T> r(X);
399  r+= Y;
400  return r;
401  }
403  const AutoDerivative<T>& Y)
404  { AutoDerivative<T> r(X);
405  r -= Y;
406  return r;
407  }
409  { AutoDerivative<T> r(X);
410  r *= -1;
411  return r;
412  }
414  const AutoDerivative<T>& Y)
415  { AutoDerivative<T> r(X);
416  r *= Y;
417  return r;
418  }
420  const AutoDerivative<T>& Y)
421  { AutoDerivative<T> r(X);
422  r /= Y;
423  return r;
424  }
426  const T& Y)
427  { AutoDerivative<T> r(X);
428  r+= Y;
429  return r;
430  }
432  const T& Y)
433  { AutoDerivative<T> r(X);
434  r -= Y;
435  return r;
436  }
438  const T& Y)
439  { AutoDerivative<T> r(X);
440  r *= Y;
441  return r;
442  }
444  const T& Y)
445  { AutoDerivative<T> r(X);
446  r /= Y;
447  return r;
448  }
449  friend AutoDerivative<T> operator+(const T& X,
450  const AutoDerivative<T>& Y)
451  { AutoDerivative<T> r(Y);
452  r+= X;
453  return r;
454  }
455  friend AutoDerivative<T> operator-(const T& X,
456  const AutoDerivative<T>& Y)
457  { AutoDerivative<T> r(X);
458  r -= Y;
459  return r;
460  }
461  friend AutoDerivative<T> operator*(const T& X,
462  const AutoDerivative<T>& Y)
463  { AutoDerivative<T> r(Y);
464  r *= X;
465  return r;
466  }
467  friend AutoDerivative<T> operator/(const T& X,
468  const AutoDerivative<T>& Y)
469  { AutoDerivative<T> r(X);
470  r /= Y;
471  return r;
472  }
473 private:
474  T val;
475  blitz::Array<T, 1> grad;
476  bool keep_grad;
477 };
478 
479 //-----------------------------------------------------------------------
482 //-----------------------------------------------------------------------
483 
484 template<class T> inline blitz::Array<T, 2> jacobian
485 (const blitz::Array<AutoDerivative<T>, 1>& Ad)
486 {
487  int nvar = 0;
488  BOOST_FOREACH(const AutoDerivative<T>& v, Ad)
489  if(!v.is_constant()) {
490  nvar = v.number_variable();
491  break;
492  }
493  blitz::Array<T, 2> res(Ad.rows(), nvar);
494  if(nvar > 0) {
495  for(int i = 0; i < Ad.rows(); ++i)
496  if(!Ad(i).is_constant())
497  res(i, blitz::Range::all()) = Ad(i).gradient();
498  else
499  res(i, blitz::Range::all()) = 0;
500  }
501  return res;
502 }
503 
504 template<class T> inline blitz::Array<T, 3> jacobian
505 (const blitz::Array<AutoDerivative<T>, 2>& Ad)
506 {
507  int nvar = 0;
508  BOOST_FOREACH(const AutoDerivative<T>& v, Ad)
509  if(!v.is_constant()) {
510  nvar = v.number_variable();
511  break;
512  }
513  blitz::Array<T, 3> res(Ad.rows(), Ad.cols(), nvar);
514  if(nvar > 0) {
515  for(int i = 0; i < Ad.rows(); ++i)
516  for(int j = 0; j < Ad.cols(); ++j)
517  if(!Ad(i, j).is_constant())
518  res(i, j, blitz::Range::all()) = Ad(i, j).gradient();
519  else
520  res(i, j, blitz::Range::all()) = 0;
521  }
522  return res;
523 }
524 
525 template<class T> inline blitz::Array<T, 4> jacobian
526 (const blitz::Array<AutoDerivative<T>, 3>& Ad)
527 {
528  int nvar = 0;
529  BOOST_FOREACH(const AutoDerivative<T>& v, Ad)
530  if(!v.is_constant()) {
531  nvar = v.number_variable();
532  break;
533  }
534  blitz::Array<T, 4> res(Ad.rows(), Ad.cols(), Ad.depth(), nvar);
535  if(nvar > 0) {
536  for(int i = 0; i < Ad.rows(); ++i)
537  for(int j = 0; j < Ad.cols(); ++j)
538  for(int k = 0; k < Ad.depth(); ++k)
539  if(!Ad(i, j, k).is_constant())
540  res(i, j, k, blitz::Range::all()) = Ad(i, j, k).gradient();
541  else
542  res(i, j, k, blitz::Range::all()) = 0;
543  }
544  return res;
545 }
546 
547 template<class T> inline blitz::Array<T, 5> jacobian
548 (const blitz::Array<AutoDerivative<T>, 4>& Ad)
549 {
550  int nvar = 0;
551  BOOST_FOREACH(const AutoDerivative<T>& v, Ad)
552  if(!v.is_constant()) {
553  nvar = v.number_variable();
554  break;
555  }
556  blitz::Array<T, 5> res(Ad.rows(), Ad.cols(), Ad.depth(),
557  Ad.extent(blitz::fourthDim), nvar);
558  if(nvar > 0) {
559  for(int i = 0; i < Ad.rows(); ++i)
560  for(int j = 0; j < Ad.cols(); ++j)
561  for(int k = 0; k < Ad.depth(); ++k)
562  for(int m = 0; m < Ad.extent(blitz::fourthDim); ++m)
563  if(!Ad(i, j, k, m).is_constant())
564  res(i, j, k, m, blitz::Range::all()) = Ad(i, j, k, m).gradient();
565  else
566  res(i, j, k, m, blitz::Range::all()) = 0;
567  }
568  return res;
569 }
570 
571 //-----------------------------------------------------------------------
574 //-----------------------------------------------------------------------
575 
576 inline blitz::Array<AutoDerivative<double>, 1> auto_derivative
577 (const blitz::Array<double, 1>& Val, const blitz::Array<double, 2>& Jac)
578 {
579  blitz::Array<AutoDerivative<double>, 1> res(Val.shape());
580  for(int i = 0; i < Val.rows(); ++i) {
581  res(i).value() = Val(i);
582  if(Jac.cols() > 0)
583  res(i).gradient().reference(Jac(i, blitz::Range::all()));
584  }
585  return res;
586 }
587 
588 inline blitz::Array<AutoDerivative<double>, 1> auto_derivative
589 (const blitz::Array<double, 1>& Val, int i_th, int nvars)
590 {
591  blitz::Array<AutoDerivative<double>, 1> res(Val.shape());
592  for(int i = 0; i < Val.rows(); ++i)
593  res(i) = AutoDerivative<double>(Val(i), i_th, nvars);
594  return res;
595 }
596 
597 inline blitz::Array<AutoDerivative<double>, 2> auto_derivative
598 (const blitz::Array<double, 2>& Val, const blitz::Array<double, 3>& Jac)
599 {
600  blitz::Array<AutoDerivative<double>, 2> res(Val.shape());
601  for(int i = 0; i < Val.rows(); ++i)
602  for(int j = 0; j < Val.cols(); ++j) {
603  res(i, j).value() = Val(i, j);
604  if(Jac.depth() > 0)
605  res(i, j).gradient().reference(Jac(i, j, blitz::Range::all()));
606  }
607  return res;
608 }
609 
610 inline blitz::Array<AutoDerivative<double>, 3> auto_derivative
611 (const blitz::Array<double, 3>& Val, const blitz::Array<double, 4>& Jac)
612 {
613  blitz::Array<AutoDerivative<double>, 3> res(Val.shape());
614  for(int i = 0; i < Val.rows(); ++i)
615  for(int j = 0; j < Val.cols(); ++j)
616  for(int k = 0; k < Val.extent(blitz::thirdDim); ++k) {
617  res(i, j, k).value() = Val(i, j, k);
618  if(Jac.extent(blitz::fourthDim) > 0)
619  res(i, j, k).gradient().reference(Jac(i, j, k, blitz::Range::all()));
620  }
621  return res;
622 }
623 }
624 
625 //-----------------------------------------------------------------------
627 //-----------------------------------------------------------------------
628 namespace std { // Math functions are in std:: namespace.
629 
632 {
633  if(x.is_constant())
635  else
636  return FullPhysics::AutoDerivative<double>(::sqrt(x.value()),
637  blitz::Array<double, 1>(x.gradient() / (2*::sqrt(x.value())) ));
638 }
639 
642 {
643  if(x.is_constant())
645  else
646  return FullPhysics::AutoDerivative<double>(::log(x.value()),
647  blitz::Array<double, 1>(x.gradient() / x.value()));
648 }
649 
652 {
653  if(x.is_constant())
655  else
656  return FullPhysics::AutoDerivative<double>(::log10(x.value()),
657  blitz::Array<double, 1>(M_LOG10E * x.gradient() / x.value()));
658 }
659 
662 {
663  if(x.is_constant())
665  else
666  return FullPhysics::AutoDerivative<double>(::exp(x.value()),
667  blitz::Array<double, 1>(x.gradient() * ::exp(x.value())));
668 }
669 
672 {
673  if(x.is_constant())
675  else {
676  return FullPhysics::AutoDerivative<double>(::sin(x.value()),
677  blitz::Array<double, 1>(x.gradient() * ::cos(x.value()) ));
678  }
679 }
680 
683 {
684  if(x.value() < -1.0 || x.value() > 1.0) {
685  FullPhysics::Exception err_msg;
686  err_msg << "Value not within domain of arcsine: -1 <= x <= 1 where x = " << x.value();
687  throw err_msg;
688  }
689 
690  if(x.is_constant())
692  else {
693  return FullPhysics::AutoDerivative<double>(::asin(x.value()),
694  blitz::Array<double, 1>(x.gradient() / sqrt(1-x.value()*x.value()) ));
695  }
696 }
697 
700 {
701  if(x.is_constant())
703  else {
704  return FullPhysics::AutoDerivative<double>(::cos(x.value()),
705  blitz::Array<double, 1>(x.gradient() * (- ::sin(x.value())) ));
706  }
707 }
708 
711 {
712  if(x.value() < -1.0 || x.value() > 1.0) {
713  FullPhysics::Exception err_msg;
714  err_msg << "Value not within domain of arccosine: -1 <= x <= 1 where x = " << x.value();
715  throw err_msg;
716  }
717 
718  if(x.is_constant())
720  else {
721  return FullPhysics::AutoDerivative<double>(::acos(x.value()),
722  blitz::Array<double, 1>(-1.0 * x.gradient() / sqrt(1-x.value()*x.value()) ));
723  }
724 }
725 
728 {
729  if(x.is_constant())
731  else {
732  return FullPhysics::AutoDerivative<double>(::tan(x.value()),
733  blitz::Array<double, 1>(x.gradient() / (::cos(x.value()) * ::cos(x.value())) ));
734  }
735 }
736 
739 {
740  if(x.is_constant())
742  else {
743  return FullPhysics::AutoDerivative<double>(::atan(x.value()),
744  blitz::Array<double, 1>(x.gradient() / (x.value()*x.value() + 1) ));
745  }
746 }
747 
749 pow(const FullPhysics::AutoDerivative<double>& base, const double exponent)
750 {
751  if(base.is_constant())
752  return FullPhysics::AutoDerivative<double>(::pow(base.value(), exponent));
753  else {
754  return FullPhysics::AutoDerivative<double>(::pow(base.value(), exponent),
755  blitz::Array<double, 1>( base.gradient() * exponent * pow(base.value(), exponent - 1) ));
756  }
757 }
758 
760 pow(const double base, const FullPhysics::AutoDerivative<double>& exponent)
761 {
762  if(exponent.is_constant())
763  return FullPhysics::AutoDerivative<double>(::pow(base, exponent.value()));
764  else {
765  return FullPhysics::AutoDerivative<double>(::pow(base, exponent.value()),
766  blitz::Array<double, 1>( exponent.gradient() * ::log(base) * ::pow(base, exponent.value()) ));
767  }
768 }
769 
770 }
771 
772 
773 //-----------------------------------------------------------------------
775 //-----------------------------------------------------------------------
776 
777 namespace blitz {
778  inline double value(const FullPhysics::AutoDerivative<double>& Ad )
779  { return Ad.value(); }
784  BZ_DECLARE_ARRAY_ET_SCALAR_FUNCS(FullPhysics::AutoDerivative<double>)
785  BZ_DECLARE_ARRAY_ET_SCALAR_OPS(FullPhysics::AutoDerivative<double>)
786 
789 {
790  if(base.is_constant())
791  return FullPhysics::AutoDerivative<double>(base.value() * base.value());
792  else {
793  return FullPhysics::AutoDerivative<double>(base.value() * base.value(),
794  blitz::Array<double, 1>( base.gradient() * 2 * base.value()));
795  }
796 }
797 }
798 #endif
AutoDerivative< T > & operator=(const AutoDerivative< T > &D)
Assignment operator. This makes a deep copy.
friend AutoDerivative< T > operator+(const AutoDerivative< T > &X, const AutoDerivative< T > &Y)
#define range_check(V, Min, Max)
Range check.
Definition: fp_exception.h:140
AutoDerivative(const T &Val, int i_th, int nvars)
Constructor for a value of the i_th independent variable (0 based).
friend AutoDerivative< T > operator/(const T &X, const AutoDerivative< T > &Y)
AutoDerivative< T > & operator+=(const T &V)
void print(std::ostream &Os) const
friend AutoDerivative< T > operator*(const T &X, const AutoDerivativeRef< T > &Y)
blitz::Array< AutoDerivative< double >, 1 > auto_derivative(const blitz::Array< double, 1 > &Val, const blitz::Array< double, 2 > &Jac)
Utility routine to take value and Jacobian separately and create a blitz::Array<AutoDerivative<double...
AutoDerivative< T > & operator+=(const AutoDerivative< T > &V)
friend AutoDerivative< T > operator/(const AutoDerivative< T > &X, const AutoDerivative< T > &Y)
bool is_constant() const
Is this object a constant (with a gradient() all zeros)?
AutoDerivative< T > & operator*=(const AutoDerivative< T > &V)
AutoDerivative()
Default constructor, data is uninitialized.
FullPhysics::AutoDerivative< double > sqrt(const FullPhysics::AutoDerivative< double > &x)
friend AutoDerivative< T > operator+(const T &X, const AutoDerivative< T > &Y)
bool operator<(const T &V) const
FullPhysics::AutoDerivative< double > acos(const FullPhysics::AutoDerivative< double > &x)
bool operator>(const AutoDerivative< T > &V) const
AutoDerivative(const AutoDerivativeRef< T > &V)
Convert AutoDerivativeRef to a AutoDerivative.
friend AutoDerivative< T > operator+(const AutoDerivativeRef< T > &X, const T &Y)
friend AutoDerivative< T > operator-(const AutoDerivativeRef< T > &X, const T &Y)
AutoDerivative(const T &Val, const blitz::Array< T, 1 > &G)
Constructor that takes a value and a gradient.
This is the base of the exception hierarchy for Full Physics code.
Definition: fp_exception.h:16
friend AutoDerivative< T > operator*(const AutoDerivative< T > &X, const T &Y)
STL namespace.
blitz::Array< T, 2 > jacobian(const blitz::Array< AutoDerivative< T >, 1 > &Ad)
Utility function to extract the Jacobian as a separate matrix from an array of AutoDerivative.
FullPhysics::AutoDerivative< double > asin(const FullPhysics::AutoDerivative< double > &x)
friend AutoDerivative< T > operator*(const AutoDerivativeRef< T > &X, const T &Y)
BZ_DECLARE_FUNCTION_RET(auto_derivative, FullPhysics::AutoDerivative< double >)
AutoDerivativeRef(T &V, const blitz::Array< T, 1 > &G)
const blitz::Array< T, 1 > & gradient() const
bool operator==(const AutoDerivative< T > &V) const
AutoDerivative(const AutoDerivative< T > &D)
Copy constructor. This does a deep copy.
blitz::Array< T, 1 > & gradient_ref() const
Helper class that gives us a reference that we can assign a AutoDerivative to and write into the corr...
This is a Mixin for classes that can be printed.
Definition: printable.h:24
AutoDerivative< T > & operator/=(const T &V)
friend AutoDerivative< T > operator-(const AutoDerivative< T > &X)
Apply value function to a blitz array.
friend AutoDerivative< T > operator*(const T &X, const AutoDerivative< T > &Y)
friend AutoDerivative< T > operator+(const AutoDerivativeRef< T > &X, const AutoDerivativeRef< T > &Y)
bool operator==(const T &V) const
bool operator>(const T &V) const
There are a number of tools that can be used to do "Automatic Differentiation" (see for example http:...
friend AutoDerivative< T > operator/(const AutoDerivative< T > &X, const T &Y)
friend AutoDerivative< T > operator-(const AutoDerivativeRef< T > &X, const AutoDerivativeRef< T > &Y)
void print(std::ostream &Os) const
friend AutoDerivative< T > operator*(const AutoDerivative< T > &X, const AutoDerivative< T > &Y)
FullPhysics::AutoDerivative< double > pow2(const FullPhysics::AutoDerivative< double > &x)
const Unit m("m", 1.0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
int number_variable() const
Number of variables in gradient.
const blitz::Array< T, 1 > & gradient() const
Gradient.
Unit pow(const Unit &Dunit, const boost::rational< int > &Exponent)
Definition: unit.cc:158
FullPhysics::AutoDerivative< double > atan(const FullPhysics::AutoDerivative< double > &x)
AutoDerivative< T > copy() const
Create deep copy.
friend AutoDerivative< T > operator+(const T &X, const AutoDerivativeRef< T > &Y)
const AutoDerivativeRef< T > & operator=(const AutoDerivative< T > &D) const
blitz::Array< T, 1 > & gradient()
friend AutoDerivative< T > operator/(const AutoDerivativeRef< T > &X, const AutoDerivativeRef< T > &Y)
AutoDerivative< T > & operator-=(const AutoDerivative< T > &V)
friend AutoDerivative< T > operator-(const AutoDerivativeRef< T > &X)
Contains classes to abstract away details in various Spurr Radiative Transfer software.
Definition: doxygen_python.h:1
const T & value() const
Convert to type T.
FullPhysics::AutoDerivative< double > log10(const FullPhysics::AutoDerivative< double > &x)
friend AutoDerivative< T > operator-(const T &X, const AutoDerivative< T > &Y)
friend AutoDerivative< T > operator+(const AutoDerivative< T > &X, const T &Y)
friend AutoDerivative< T > operator*(const AutoDerivativeRef< T > &X, const AutoDerivativeRef< T > &Y)
friend AutoDerivative< T > operator-(const T &X, const AutoDerivativeRef< T > &Y)
AutoDerivative< T > & operator-=(const T &V)
FullPhysics::AutoDerivative< double > cos(const FullPhysics::AutoDerivative< double > &x)
friend AutoDerivative< T > operator-(const AutoDerivative< T > &X, const T &Y)
FullPhysics::AutoDerivative< double > exp(const FullPhysics::AutoDerivative< double > &x)
AutoDerivative< T > & operator*=(const T &V)
AutoDerivative< T > & operator/=(const AutoDerivative< T > &V)
friend AutoDerivative< T > operator/(const T &X, const AutoDerivativeRef< T > &Y)
friend AutoDerivative< T > operator/(const AutoDerivativeRef< T > &X, const T &Y)
double value(const FullPhysics::AutoDerivative< double > &Ad)
AutoDerivative(const T &Val)
Constructor for a value that is a constant.
friend AutoDerivative< T > operator-(const AutoDerivative< T > &X, const AutoDerivative< T > &Y)
FullPhysics::AutoDerivative< double > tan(const FullPhysics::AutoDerivative< double > &x)
FullPhysics::AutoDerivative< double > sin(const FullPhysics::AutoDerivative< double > &x)
FullPhysics::AutoDerivative< double > log(const FullPhysics::AutoDerivative< double > &x)

Copyright © 2017, California Institute of Technology.
ALL RIGHTS RESERVED.
U.S. Government Sponsorship acknowledged.
Generated Fri Aug 24 2018 15:44:11