CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
atanh_op.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_LOCAL_ATANH_OP_HPP
2 # define CPPAD_LOCAL_ATANH_OP_HPP
3 # if CPPAD_USE_CPLUSPLUS_2011
4 
5 /* --------------------------------------------------------------------------
6 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
7 
8 CppAD is distributed under multiple licenses. This distribution is under
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.
13 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
14 -------------------------------------------------------------------------- */
15 
16 
17 namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE
18 /*!
19 \file atanh_op.hpp
20 Forward and reverse mode calculations for z = atanh(x).
21 */
22 
23 
24 /*!
25 Forward mode Taylor coefficient for result of op = AtanhOp.
26 
27 The C++ source code corresponding to this operation is
28 \verbatim
29  z = atanh(x)
30 \endverbatim
31 The auxillary result is
32 \verbatim
33  y = 1 - x * x
34 \endverbatim
35 The value of y, and its derivatives, are computed along with the value
36 and derivatives of z.
37 
38 \copydetails CppAD::local::forward_unary2_op
39 */
40 template <class Base>
41 inline void forward_atanh_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  if( p == 0 )
62  { z[0] = atanh( x[0] );
63  b[0] = Base(1.0) - x[0] * x[0];
64  p++;
65  }
66  for(size_t j = p; j <= q; j++)
67  {
68  b[j] = - Base(2.0) * x[0] * x[j];
69  z[j] = Base(0.0);
70  for(k = 1; k < j; k++)
71  { b[j] -= x[k] * x[j-k];
72  z[j] -= Base(double(k)) * z[k] * b[j-k];
73  }
74  z[j] /= Base(double(j));
75  z[j] += x[j];
76  z[j] /= b[0];
77  }
78 }
79 
80 /*!
81 Multiple direction Taylor coefficient for op = AtanhOp.
82 
83 The C++ source code corresponding to this operation is
84 \verbatim
85  z = atanh(x)
86 \endverbatim
87 The auxillary result is
88 \verbatim
89  y = 1 - x * x
90 \endverbatim
91 The value of y, and its derivatives, are computed along with the value
92 and derivatives of z.
93 
94 \copydetails CppAD::local::forward_unary2_op_dir
95 */
96 template <class Base>
98  size_t q ,
99  size_t r ,
100  size_t i_z ,
101  size_t i_x ,
102  size_t cap_order ,
103  Base* taylor )
104 {
105  // check assumptions
108  CPPAD_ASSERT_UNKNOWN( 0 < q );
109  CPPAD_ASSERT_UNKNOWN( q < cap_order );
110 
111  // Taylor coefficients corresponding to argument and result
112  size_t num_taylor_per_var = (cap_order-1) * r + 1;
113  Base* x = taylor + i_x * num_taylor_per_var;
114  Base* z = taylor + i_z * num_taylor_per_var;
115  Base* b = z - num_taylor_per_var; // called y in documentation
116 
117  size_t m = (q-1) * r + 1;
118  for(size_t ell = 0; ell < r; ell++)
119  { b[m+ell] = - Base(2.0) * x[m+ell] * x[0];
120  z[m+ell] = Base(double(q)) * x[m+ell];
121  for(size_t k = 1; k < q; k++)
122  { b[m+ell] -= x[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell];
123  z[m+ell] -= Base(double(k)) * z[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell];
124  }
125  z[m+ell] /= ( Base(double(q)) * b[0] );
126  }
127 }
128 
129 /*!
130 Zero order forward mode Taylor coefficient for result of op = AtanhOp.
131 
132 The C++ source code corresponding to this operation is
133 \verbatim
134  z = atanh(x)
135 \endverbatim
136 The auxillary result is
137 \verbatim
138  y = 1 - x * x
139 \endverbatim
140 The value of y is computed along with the value of z.
141 
142 \copydetails CppAD::local::forward_unary2_op_0
143 */
144 template <class Base>
145 inline void forward_atanh_op_0(
146  size_t i_z ,
147  size_t i_x ,
148  size_t cap_order ,
149  Base* taylor )
150 {
151  // check assumptions
154  CPPAD_ASSERT_UNKNOWN( 0 < cap_order );
155 
156  // Taylor coefficients corresponding to argument and result
157  Base* x = taylor + i_x * cap_order;
158  Base* z = taylor + i_z * cap_order;
159  Base* b = z - cap_order; // called y in documentation
160 
161  z[0] = atanh( x[0] );
162  b[0] = Base(1.0) - x[0] * x[0];
163 }
164 /*!
165 Reverse mode partial derivatives for result of op = AtanhOp.
166 
167 The C++ source code corresponding to this operation is
168 \verbatim
169  z = atanh(x)
170 \endverbatim
171 The auxillary result is
172 \verbatim
173  y = 1 - x * x
174 \endverbatim
175 The value of y is computed along with the value of z.
176 
177 \copydetails CppAD::local::reverse_unary2_op
178 */
179 
180 template <class Base>
181 inline void reverse_atanh_op(
182  size_t d ,
183  size_t i_z ,
184  size_t i_x ,
185  size_t cap_order ,
186  const Base* taylor ,
187  size_t nc_partial ,
188  Base* partial )
189 {
190  // check assumptions
193  CPPAD_ASSERT_UNKNOWN( d < cap_order );
194  CPPAD_ASSERT_UNKNOWN( d < nc_partial );
195 
196  // Taylor coefficients and partials corresponding to argument
197  const Base* x = taylor + i_x * cap_order;
198  Base* px = partial + i_x * nc_partial;
199 
200  // Taylor coefficients and partials corresponding to first result
201  const Base* z = taylor + i_z * cap_order;
202  Base* pz = partial + i_z * nc_partial;
203 
204  // Taylor coefficients and partials corresponding to auxillary result
205  const Base* b = z - cap_order; // called y in documentation
206  Base* pb = pz - nc_partial;
207 
208  Base inv_b0 = Base(1.0) / b[0];
209 
210  // number of indices to access
211  size_t j = d;
212  size_t k;
213  while(j)
214  { // scale partials w.r.t z[j] and b[j]
215  pz[j] = azmul(pz[j], inv_b0);
216  pb[j] *= Base(2.0);
217 
218  pb[0] -= azmul(pz[j], z[j]);
219  px[j] += pz[j] - azmul(pb[j], x[0]);
220  px[0] -= azmul(pb[j], x[j]);
221 
222  // more scaling of partials w.r.t z[j]
223  pz[j] /= Base(double(j));
224 
225  for(k = 1; k < j; k++)
226  { pb[j-k] -= Base(double(k)) * azmul(pz[j], z[k]);
227  pz[k] -= Base(double(k)) * azmul(pz[j], b[j-k]);
228  px[k] -= azmul(pb[j], x[j-k]);
229  }
230  --j;
231  }
232  px[0] += azmul(pz[0], inv_b0) - Base(2.0) * azmul(pb[0], x[0]);
233 }
234 
235 } } // END_CPPAD_LOCAL_NAMESPACE
236 # endif
237 # endif
AD< Base > azmul(const AD< Base > &x, const AD< Base > &y)
Definition: azmul.hpp:94
void forward_atanh_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 = AtanhOp.
Definition: atanh_op.hpp:41
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
void forward_atanh_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 = AtanhOp.
Definition: atanh_op.hpp:145
std::complex< double > atanh(const std::complex< double > &x)
#define CPPAD_ASSERT_UNKNOWN(exp)
Check that exp is true, if not terminate execution.
void forward_atanh_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 = AtanhOp.
Definition: atanh_op.hpp:97
void reverse_atanh_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 = AtanhOp.
Definition: atanh_op.hpp:181