CppAD: A C++ Algorithmic Differentiation Package  20171217
atan_op.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_LOCAL_ATAN_OP_HPP
2 # define CPPAD_LOCAL_ATAN_OP_HPP
3
4 /* --------------------------------------------------------------------------
5 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
6
8 the terms of the
9  Eclipse Public License Version 1.0.
10
11 A copy of this license is included in the COPYING file of this distribution.
13 -------------------------------------------------------------------------- */
14
15
16 namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE
17 /*!
18 \file atan_op.hpp
19 Forward and reverse mode calculations for z = atan(x).
20 */
21
22
23 /*!
24 Forward mode Taylor coefficient for result of op = AtanOp.
25
26 The C++ source code corresponding to this operation is
27 \verbatim
28  z = atan(x)
29 \endverbatim
30 The auxillary result is
31 \verbatim
32  y = 1 + x * x
33 \endverbatim
34 The value of y, and its derivatives, are computed along with the value
35 and derivatives of z.
36
38 */
39 template <class Base>
40 inline void forward_atan_op(
41  size_t p ,
42  size_t q ,
43  size_t i_z ,
44  size_t i_x ,
45  size_t cap_order ,
46  Base* taylor )
47 {
48  // check assumptions
51  CPPAD_ASSERT_UNKNOWN( q < cap_order );
52  CPPAD_ASSERT_UNKNOWN( p <= q );
53
54  // Taylor coefficients corresponding to argument and result
55  Base* x = taylor + i_x * cap_order;
56  Base* z = taylor + i_z * cap_order;
57  Base* b = z - cap_order; // called y in documentation
58
59  size_t k;
60  if( p == 0 )
61  { z[0] = atan( x[0] );
62  b[0] = Base(1.0) + x[0] * x[0];
63  p++;
64  }
65  for(size_t j = p; j <= q; j++)
66  {
67  b[j] = Base(2.0) * x[0] * x[j];
68  z[j] = Base(0.0);
69  for(k = 1; k < j; k++)
70  { b[j] += x[k] * x[j-k];
71  z[j] -= Base(double(k)) * z[k] * b[j-k];
72  }
73  z[j] /= Base(double(j));
74  z[j] += x[j];
75  z[j] /= b[0];
76  }
77 }
78
79 /*!
80 Multiple direction Taylor coefficient for op = AtanOp.
81
82 The C++ source code corresponding to this operation is
83 \verbatim
84  z = atan(x)
85 \endverbatim
86 The auxillary result is
87 \verbatim
88  y = 1 + x * x
89 \endverbatim
90 The value of y, and its derivatives, are computed along with the value
91 and derivatives of z.
92
94 */
95 template <class Base>
96 inline void forward_atan_op_dir(
97  size_t q ,
98  size_t r ,
99  size_t i_z ,
100  size_t i_x ,
101  size_t cap_order ,
102  Base* taylor )
103 {
104  // check assumptions
107  CPPAD_ASSERT_UNKNOWN( 0 < q );
108  CPPAD_ASSERT_UNKNOWN( q < cap_order );
109
110  // Taylor coefficients corresponding to argument and result
111  size_t num_taylor_per_var = (cap_order-1) * r + 1;
112  Base* x = taylor + i_x * num_taylor_per_var;
113  Base* z = taylor + i_z * num_taylor_per_var;
114  Base* b = z - num_taylor_per_var; // called y in documentation
115
116  size_t m = (q-1) * r + 1;
117  for(size_t ell = 0; ell < r; ell++)
118  { b[m+ell] = Base(2.0) * x[m+ell] * x[0];
119  z[m+ell] = Base(double(q)) * x[m+ell];
120  for(size_t k = 1; k < q; k++)
121  { b[m+ell] += x[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell];
122  z[m+ell] -= Base(double(k)) * z[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell];
123  }
124  z[m+ell] /= ( Base(double(q)) * b[0] );
125  }
126 }
127
128 /*!
129 Zero order forward mode Taylor coefficient for result of op = AtanOp.
130
131 The C++ source code corresponding to this operation is
132 \verbatim
133  z = atan(x)
134 \endverbatim
135 The auxillary result is
136 \verbatim
137  y = 1 + x * x
138 \endverbatim
139 The value of y is computed along with the value of z.
140
142 */
143 template <class Base>
144 inline void forward_atan_op_0(
145  size_t i_z ,
146  size_t i_x ,
147  size_t cap_order ,
148  Base* taylor )
149 {
150  // check assumptions
153  CPPAD_ASSERT_UNKNOWN( 0 < cap_order );
154
155  // Taylor coefficients corresponding to argument and result
156  Base* x = taylor + i_x * cap_order;
157  Base* z = taylor + i_z * cap_order;
158  Base* b = z - cap_order; // called y in documentation
159
160  z[0] = atan( x[0] );
161  b[0] = Base(1.0) + x[0] * x[0];
162 }
163 /*!
164 Reverse mode partial derivatives for result of op = AtanOp.
165
166 The C++ source code corresponding to this operation is
167 \verbatim
168  z = atan(x)
169 \endverbatim
170 The auxillary result is
171 \verbatim
172  y = 1 + x * x
173 \endverbatim
174 The value of y is computed along with the value of z.
175
177 */
178
179 template <class Base>
180 inline void reverse_atan_op(
181  size_t d ,
182  size_t i_z ,
183  size_t i_x ,
184  size_t cap_order ,
185  const Base* taylor ,
186  size_t nc_partial ,
187  Base* partial )
188 {
189  // check assumptions
192  CPPAD_ASSERT_UNKNOWN( d < cap_order );
193  CPPAD_ASSERT_UNKNOWN( d < nc_partial );
194
195  // Taylor coefficients and partials corresponding to argument
196  const Base* x = taylor + i_x * cap_order;
197  Base* px = partial + i_x * nc_partial;
198
199  // Taylor coefficients and partials corresponding to first result
200  const Base* z = taylor + i_z * cap_order;
201  Base* pz = partial + i_z * nc_partial;
202
203  // Taylor coefficients and partials corresponding to auxillary result
204  const Base* b = z - cap_order; // called y in documentation
205  Base* pb = pz - nc_partial;
206
207  Base inv_b0 = Base(1.0) / b[0];
208
209  // number of indices to access
210  size_t j = d;
211  size_t k;
212  while(j)
213  { // scale partials w.r.t z[j] and b[j]
214  pz[j] = azmul(pz[j], inv_b0);
215  pb[j] *= Base(2.0);
216
217  pb[0] -= azmul(pz[j], z[j]);
218  px[j] += pz[j] + azmul(pb[j], x[0]);
219  px[0] += azmul(pb[j], x[j]);
220
221  // more scaling of partials w.r.t z[j]
222  pz[j] /= Base(double(j));
223
224  for(k = 1; k < j; k++)
225  { pb[j-k] -= Base(double(k)) * azmul(pz[j], z[k]);
226  pz[k] -= Base(double(k)) * azmul(pz[j], b[j-k]);
227  px[k] += azmul(pb[j], x[j-k]);
228  }
229  --j;
230  }
231  px[0] += azmul(pz[0], inv_b0) + Base(2.0) * azmul(pb[0], x[0]);
232 }
233
234 } } // END_CPPAD_LOCAL_NAMESPACE
235 # endif
AD< Base > azmul(const AD< Base > &x, const AD< Base > &y)
Definition: azmul.hpp:94
void reverse_atan_op(size_t d, size_t i_z, size_t i_x, size_t cap_order, const Base *taylor, size_t nc_partial, Base *partial)
Reverse mode partial derivatives for result of op = AtanOp.
Definition: atan_op.hpp:180
void forward_atan_op_dir(size_t q, size_t r, size_t i_z, size_t i_x, size_t cap_order, Base *taylor)
Multiple direction Taylor coefficient for op = AtanOp.
Definition: atan_op.hpp:96
std::complex< double > atan(const std::complex< double > &x)
size_t NumArg(OpCode op)
Number of arguments for a specified operator.
Definition: op_code.hpp:175
void forward_atan_op_0(size_t i_z, size_t i_x, size_t cap_order, Base *taylor)
Zero order forward mode Taylor coefficient for result of op = AtanOp.
Definition: atan_op.hpp:144
size_t NumRes(OpCode op)
Number of variables resulting from the specified operation.
Definition: op_code.hpp:281
void forward_atan_op(size_t p, size_t q, size_t i_z, size_t i_x, size_t cap_order, Base *taylor)
Forward mode Taylor coefficient for result of op = AtanOp.
Definition: atan_op.hpp:40