CppAD: A C++ Algorithmic Differentiation Package  20171217
acosh_op.hpp
Go to the documentation of this file.
4
5 /* --------------------------------------------------------------------------
7
9 the terms of the
10  Eclipse Public License Version 1.0.
11
12 A copy of this license is included in the COPYING file of this distribution.
14 -------------------------------------------------------------------------- */
15
16
18 /*!
19 \file acosh_op.hpp
20 Forward and reverse mode calculations for z = acosh(x).
21 */
22
23
24 /*!
25 Compute forward mode Taylor coefficient for result of op = AcoshOp.
26
27 The C++ source code corresponding to this operation is
28 \verbatim
29  z = acosh(x)
30 \endverbatim
31 The auxillary result is
32 \verbatim
33  y = sqrt(x * x - 1)
34 \endverbatim
35 The value of y, and its derivatives, are computed along with the value
36 and derivatives of z.
37
39 */
40 template <class Base>
41 inline void forward_acosh_op(
42  size_t p ,
43  size_t q ,
44  size_t i_z ,
45  size_t i_x ,
46  size_t cap_order ,
47  Base* taylor )
48 {
49  // check assumptions
52  CPPAD_ASSERT_UNKNOWN( q < cap_order );
53  CPPAD_ASSERT_UNKNOWN( p <= q );
54
55  // Taylor coefficients corresponding to argument and result
56  Base* x = taylor + i_x * cap_order;
57  Base* z = taylor + i_z * cap_order;
58  Base* b = z - cap_order; // called y in documentation
59
60  size_t k;
61  Base uj;
62  if( p == 0 )
63  { z[0] = acosh( x[0] );
64  uj = x[0] * x[0] - Base(1.0);
65  b[0] = sqrt( uj );
66  p++;
67  }
68  for(size_t j = p; j <= q; j++)
69  { uj = Base(0.0);
70  for(k = 0; k <= j; k++)
71  uj += x[k] * x[j-k];
72  b[j] = Base(0.0);
73  z[j] = Base(0.0);
74  for(k = 1; k < j; k++)
75  { b[j] -= Base(double(k)) * b[k] * b[j-k];
76  z[j] -= Base(double(k)) * z[k] * b[j-k];
77  }
78  b[j] /= Base(double(j));
79  z[j] /= Base(double(j));
80  //
81  b[j] += uj / Base(2.0);
82  z[j] += x[j];
83  //
84  b[j] /= b[0];
85  z[j] /= b[0];
86  }
87 }
88 /*!
89 Multiple directions forward mode Taylor coefficient for op = AcoshOp.
90
91 The C++ source code corresponding to this operation is
92 \verbatim
93  z = acosh(x)
94 \endverbatim
95 The auxillary result is
96 \verbatim
97  y = sqrt(x * x - 1)
98 \endverbatim
99 The value of y, and its derivatives, are computed along with the value
100 and derivatives of z.
101
103 */
104 template <class Base>
106  size_t q ,
107  size_t r ,
108  size_t i_z ,
109  size_t i_x ,
110  size_t cap_order ,
111  Base* taylor )
112 {
113  // check assumptions
116  CPPAD_ASSERT_UNKNOWN( 0 < q );
117  CPPAD_ASSERT_UNKNOWN( q < cap_order );
118
119  // Taylor coefficients corresponding to argument and result
120  size_t num_taylor_per_var = (cap_order-1) * r + 1;
121  Base* x = taylor + i_x * num_taylor_per_var;
122  Base* z = taylor + i_z * num_taylor_per_var;
123  Base* b = z - num_taylor_per_var; // called y in documentation
124
125  size_t k, ell;
126  size_t m = (q-1) * r + 1;
127  for(ell = 0; ell < r; ell ++)
128  { Base uq = 2.0 * x[m + ell] * x[0];
129  for(k = 1; k < q; k++)
130  uq += x[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell];
131  b[m+ell] = Base(0.0);
132  z[m+ell] = Base(0.0);
133  for(k = 1; k < q; k++)
134  { b[m+ell] += Base(double(k)) * b[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell];
135  z[m+ell] += Base(double(k)) * z[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell];
136  }
137  b[m+ell] = ( uq / Base(2.0) - b[m+ell] / Base(double(q)) ) / b[0];
138  z[m+ell] = ( x[m+ell] - z[m+ell] / Base(double(q)) ) / b[0];
139  }
140 }
141
142 /*!
143 Compute zero order forward mode Taylor coefficient for result of op = AcoshOp.
144
145 The C++ source code corresponding to this operation is
146 \verbatim
147  z = acosh(x)
148 \endverbatim
149 The auxillary result is
150 \verbatim
151  y = sqrt( x * x - 1 )
152 \endverbatim
153 The value of y is computed along with the value of z.
154
156 */
157 template <class Base>
158 inline void forward_acosh_op_0(
159  size_t i_z ,
160  size_t i_x ,
161  size_t cap_order ,
162  Base* taylor )
163 {
164  // check assumptions
167  CPPAD_ASSERT_UNKNOWN( 0 < cap_order );
168
169  // Taylor coefficients corresponding to argument and result
170  Base* x = taylor + i_x * cap_order;
171  Base* z = taylor + i_z * cap_order;
172  Base* b = z - cap_order; // called y in documentation
173
174  z[0] = acosh( x[0] );
175  b[0] = sqrt( x[0] * x[0] - Base(1.0) );
176 }
177 /*!
178 Compute reverse mode partial derivatives for result of op = AcoshOp.
179
180 The C++ source code corresponding to this operation is
181 \verbatim
182  z = acosh(x)
183 \endverbatim
184 The auxillary result is
185 \verbatim
186  y = sqrt( x * x - 1 )
187 \endverbatim
188 The value of y is computed along with the value of z.
189
191 */
192
193 template <class Base>
194 inline void reverse_acosh_op(
195  size_t d ,
196  size_t i_z ,
197  size_t i_x ,
198  size_t cap_order ,
199  const Base* taylor ,
200  size_t nc_partial ,
201  Base* partial )
202 {
203  // check assumptions
206  CPPAD_ASSERT_UNKNOWN( d < cap_order );
207  CPPAD_ASSERT_UNKNOWN( d < nc_partial );
208
209  // Taylor coefficients and partials corresponding to argument
210  const Base* x = taylor + i_x * cap_order;
211  Base* px = partial + i_x * nc_partial;
212
213  // Taylor coefficients and partials corresponding to first result
214  const Base* z = taylor + i_z * cap_order;
215  Base* pz = partial + i_z * nc_partial;
216
217  // Taylor coefficients and partials corresponding to auxillary result
218  const Base* b = z - cap_order; // called y in documentation
219  Base* pb = pz - nc_partial;
220
221  Base inv_b0 = Base(1.0) / b[0];
222
223  // number of indices to access
224  size_t j = d;
225  size_t k;
226  while(j)
227  {
228  // scale partials w.r.t b[j] by 1 / b[0]
229  pb[j] = azmul(pb[j], inv_b0);
230
231  // scale partials w.r.t z[j] by 1 / b[0]
232  pz[j] = azmul(pz[j], inv_b0);
233
234  // update partials w.r.t b^0
235  pb[0] -= azmul(pz[j], z[j]) + azmul(pb[j], b[j]);
236
237  // update partial w.r.t. x^0
238  px[0] += azmul(pb[j], x[j]);
239
240  // update partial w.r.t. x^j
241  px[j] += pz[j] + azmul(pb[j], x[0]);
242
243  // further scale partial w.r.t. z[j] by 1 / j
244  pz[j] /= Base(double(j));
245
246  for(k = 1; k < j; k++)
247  { // update partials w.r.t b^(j-k)
248  pb[j-k] -= Base(double(k)) * azmul(pz[j], z[k]) + azmul(pb[j], b[k]);
249
250  // update partials w.r.t. x^k
251  px[k] += azmul(pb[j], x[j-k]);
252
253  // update partials w.r.t. z^k
254  pz[k] -= Base(double(k)) * azmul(pz[j], b[j-k]);
255  }
256  --j;
257  }
258
259  // j == 0 case
260  px[0] += azmul(pz[0] + azmul(pb[0], x[0]), inv_b0);
261 }
262
264 # endif
265 # endif
Definition: azmul.hpp:94
void forward_acosh_op_dir(size_t q, size_t r, size_t i_z, size_t i_x, size_t cap_order, Base *taylor)
Multiple directions forward mode Taylor coefficient for op = AcoshOp.
Definition: acosh_op.hpp:105
size_t NumArg(OpCode op)
Number of arguments for a specified operator.
Definition: op_code.hpp:175
size_t NumRes(OpCode op)
Number of variables resulting from the specified operation.
Definition: op_code.hpp:281
std::complex< double > acosh(const std::complex< double > &x)