AutoDiff.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2013 SINTEF ICT, Applied Mathematics.
3  Copyright 2013 Statoil ASA.
4 
5  This file is part of the Open Porous Media Project (OPM).
6 
7  OPM is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  OPM is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with OPM. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #ifndef OPM_AUTODIFF_HPP_HEADER
22 #define OPM_AUTODIFF_HPP_HEADER
23 
24 #include <cmath>
25 
26 namespace Opm
27 {
28 
35  template <typename Scalar>
36  class AutoDiff
37  {
38  public:
41  static AutoDiff
42  constant(const Scalar x)
43  {
44  return function(x, Scalar(0));
45  }
46 
49  static AutoDiff
50  variable(const Scalar x)
51  {
52  return function(x, Scalar(1));
53  }
54 
57  static AutoDiff
58  function(const Scalar x, const Scalar dx)
59  {
60  return AutoDiff(x, dx);
61  }
62 
63  void
64  operator +=(const Scalar& rhs)
65  {
66  val_ += rhs;
67  }
68 
69  void
70  operator +=(const AutoDiff& rhs)
71  {
72  val_ += rhs.val_;
73  der_ += rhs.der_;
74  }
75 
76  void
77  operator -=(const Scalar& rhs)
78  {
79  val_ -= rhs;
80  }
81 
82  void
83  operator -=(const AutoDiff& rhs)
84  {
85  val_ -= rhs.val_;
86  der_ -= rhs.der_;
87  }
88 
89  void
90  operator *=(const Scalar& rhs)
91  {
92  val_ *= rhs;
93  der_ *= rhs;
94  }
95 
96  void
97  operator *=(const AutoDiff& rhs)
98  {
99  der_ = der_*rhs.val_ + val_*rhs.der_;
100  val_ *= rhs.val_;
101  }
102 
103  void
104  operator /=(const Scalar& rhs)
105  {
106  val_ /= rhs;
107  der_ /= rhs;
108  }
109 
110  void
111  operator /=(const AutoDiff& rhs)
112  {
113  der_ = (der_*rhs.val_ - val_*rhs.der_) / (rhs.val_ * rhs.val_);
114  val_ /= rhs.val_;
115  }
116 
117  template <class Ostream>
118  Ostream&
119  print(Ostream& os) const
120  {
121  os << "(x,dx) = (" << val_ << ',' << der_ << ")";
122 
123  return os;
124  }
125 
126  const Scalar val() const { return val_; }
127  const Scalar der() const { return der_; }
128 
129  private:
130  AutoDiff(const Scalar x, const Scalar dx)
131  : val_(x), der_(dx)
132  {}
133 
134  Scalar val_;
135  Scalar der_;
136  };
137 
138 
139  template <class Ostream, typename Scalar>
140  Ostream&
141  operator<<(Ostream& os, const AutoDiff<Scalar>& fw)
142  {
143  return fw.print(os);
144  }
145 
146  template <typename Scalar>
147  AutoDiff<Scalar>
149  const AutoDiff<Scalar>& rhs)
150  {
151  AutoDiff<Scalar> ret = lhs;
152  ret += rhs;
153 
154  return ret;
155  }
156 
157  template <typename Scalar, typename T>
158  AutoDiff<Scalar>
159  operator +(const T lhs,
160  const AutoDiff<Scalar>& rhs)
161  {
162  AutoDiff<Scalar> ret = rhs;
163  ret += Scalar(lhs);
164 
165  return ret;
166  }
167 
168  template <typename Scalar, typename T>
169  AutoDiff<Scalar>
171  const T rhs)
172  {
173  AutoDiff<Scalar> ret = lhs;
174  ret += Scalar(rhs);
175 
176  return ret;
177  }
178 
179  template <typename Scalar>
180  AutoDiff<Scalar>
182  const AutoDiff<Scalar>& rhs)
183  {
184  AutoDiff<Scalar> ret = lhs;
185  ret -= rhs;
186 
187  return ret;
188  }
189 
190  template <typename Scalar, typename T>
191  AutoDiff<Scalar>
192  operator -(const T lhs,
193  const AutoDiff<Scalar>& rhs)
194  {
195  return AutoDiff<Scalar>::function(Scalar(lhs) - rhs.val(), -rhs.der());
196  }
197 
198  template <typename Scalar, typename T>
199  AutoDiff<Scalar>
201  const T rhs)
202  {
203  AutoDiff<Scalar> ret = lhs;
204  ret -= Scalar(rhs);
205 
206  return ret;
207  }
208 
209  template <typename Scalar>
210  AutoDiff<Scalar>
212  const AutoDiff<Scalar>& rhs)
213  {
214  AutoDiff<Scalar> ret = lhs;
215  ret *= rhs;
216 
217  return ret;
218  }
219 
220  template <typename Scalar, typename T>
221  AutoDiff<Scalar>
222  operator *(const T lhs,
223  const AutoDiff<Scalar>& rhs)
224  {
225  AutoDiff<Scalar> ret = rhs;
226  ret *= Scalar(lhs);
227 
228  return ret;
229  }
230 
231  template <typename Scalar, typename T>
232  AutoDiff<Scalar>
234  const T rhs)
235  {
236  AutoDiff<Scalar> ret = lhs;
237  ret *= Scalar(rhs);
238 
239  return ret;
240  }
241 
242  template <typename Scalar>
243  AutoDiff<Scalar>
245  const AutoDiff<Scalar>& rhs)
246  {
247  AutoDiff<Scalar> ret = lhs;
248  ret /= rhs;
249 
250  return ret;
251  }
252 
253  template <typename Scalar, typename T>
254  AutoDiff<Scalar>
255  operator /(const T lhs,
256  const AutoDiff<Scalar>& rhs)
257  {
258  Scalar a = Scalar(lhs) / rhs.val();
259  Scalar b = -Scalar(lhs) / (rhs.val() * rhs.val());
260 
261  return AutoDiff<Scalar>::function(a, b);
262  }
263 
264  template <typename Scalar, typename T>
265  AutoDiff<Scalar>
267  const T rhs)
268  {
269  Scalar a = lhs.val() / Scalar(rhs);
270  Scalar b = lhs.der() / Scalar(rhs);
271 
272  return AutoDiff<Scalar>::function(a, b);
273  }
274 
275  template <typename Scalar>
276  AutoDiff<Scalar>
278  {
279  Scalar a = std::cos(x.val());
280  Scalar b = -std::sin(x.val()) * x.der();
281 
282  return AutoDiff<Scalar>::function(a, b);
283  }
284 
285  template <typename Scalar>
286  AutoDiff<Scalar>
288  {
289  Scalar a = std::sqrt(x.val());
290  Scalar b = (Scalar(1.0) / (Scalar(2.0) * a)) * x.der();
291 
292  return AutoDiff<Scalar>::function(a, b);
293  }
294 
295 } // namespace Opm
296 
297 namespace std {
298  using Opm::cos;
299  using Opm::sqrt;
300 }
301 
302 #endif /* OPM_AUTODIFF_HPP_HEADER */
AutoDiff< Scalar > operator+(const AutoDiff< Scalar > &lhs, const AutoDiff< Scalar > &rhs)
Definition: AutoDiff.hpp:148
AutoDiff< Scalar > operator*(const AutoDiff< Scalar > &lhs, const AutoDiff< Scalar > &rhs)
Definition: AutoDiff.hpp:211
static AutoDiff constant(const Scalar x)
Definition: AutoDiff.hpp:42
static AutoDiff variable(const Scalar x)
Definition: AutoDiff.hpp:50
void operator/=(const Scalar &rhs)
Definition: AutoDiff.hpp:104
Definition: AdditionalObjectDeleter.hpp:22
Definition: AutoDiff.hpp:36
STL namespace.
void operator-=(const Scalar &rhs)
Definition: AutoDiff.hpp:77
AutoDiff< Scalar > operator/(const AutoDiff< Scalar > &lhs, const AutoDiff< Scalar > &rhs)
Definition: AutoDiff.hpp:244
AutoDiff< Scalar > operator-(const AutoDiff< Scalar > &lhs, const AutoDiff< Scalar > &rhs)
Definition: AutoDiff.hpp:181
AutoDiff< Scalar > cos(const AutoDiff< Scalar > &x)
Definition: AutoDiff.hpp:277
const Scalar der() const
Definition: AutoDiff.hpp:127
Ostream & print(Ostream &os) const
Definition: AutoDiff.hpp:119
static AutoDiff function(const Scalar x, const Scalar dx)
Definition: AutoDiff.hpp:58
void operator*=(const Scalar &rhs)
Definition: AutoDiff.hpp:90
AutoDiff< Scalar > sqrt(const AutoDiff< Scalar > &x)
Definition: AutoDiff.hpp:287
const Scalar val() const
Definition: AutoDiff.hpp:126
void operator+=(const Scalar &rhs)
Definition: AutoDiff.hpp:64