CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
tanh_op.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_LOCAL_TANH_OP_HPP
2 # define CPPAD_LOCAL_TANH_OP_HPP
3 
4 /* --------------------------------------------------------------------------
5 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
6 
7 CppAD is distributed under multiple licenses. This distribution is under
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.
12 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
13 -------------------------------------------------------------------------- */
14 
15 
16 namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE
17 /*!
18 \file tanh_op.hpp
19 Forward and reverse mode calculations for z = tanh(x).
20 */
21 
22 
23 /*!
24 Compute forward mode Taylor coefficient for result of op = TanOp.
25 
26 The C++ source code corresponding to this operation is
27 \verbatim
28  z = tanh(x)
29 \endverbatim
30 The auxillary result is
31 \verbatim
32  y = tanh(x)^2
33 \endverbatim
34 The value of y, and its derivatives, are computed along with the value
35 and derivatives of z.
36 
37 \copydetails CppAD::local::forward_unary2_op
38 */
39 template <class Base>
40 inline void forward_tanh_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* y = z - cap_order;
58 
59  size_t k;
60  if( p == 0 )
61  { z[0] = tanh( x[0] );
62  y[0] = z[0] * z[0];
63  p++;
64  }
65  for(size_t j = p; j <= q; j++)
66  { Base base_j = static_cast<Base>(double(j));
67 
68  z[j] = x[j];
69  for(k = 1; k <= j; k++)
70  z[j] -= Base(double(k)) * x[k] * y[j-k] / base_j;
71 
72  y[j] = z[0] * z[j];
73  for(k = 1; k <= j; k++)
74  y[j] += z[k] * z[j-k];
75  }
76 }
77 
78 /*!
79 Multiple directions forward mode Taylor coefficient for op = TanOp.
80 
81 The C++ source code corresponding to this operation is
82 \verbatim
83  z = tanh(x)
84 \endverbatim
85 The auxillary result is
86 \verbatim
87  y = tanh(x)^2
88 \endverbatim
89 The value of y, and its derivatives, are computed along with the value
90 and derivatives of z.
91 
92 \copydetails CppAD::local::forward_unary2_op_dir
93 */
94 template <class Base>
95 inline void forward_tanh_op_dir(
96  size_t q ,
97  size_t r ,
98  size_t i_z ,
99  size_t i_x ,
100  size_t cap_order ,
101  Base* taylor )
102 {
103  // check assumptions
106  CPPAD_ASSERT_UNKNOWN( 0 < q );
107  CPPAD_ASSERT_UNKNOWN( q < cap_order );
108 
109  // Taylor coefficients corresponding to argument and result
110  size_t num_taylor_per_var = (cap_order-1) * r + 1;
111  Base* x = taylor + i_x * num_taylor_per_var;
112  Base* z = taylor + i_z * num_taylor_per_var;
113  Base* y = z - num_taylor_per_var;
114 
115  size_t k;
116  size_t m = (q-1) * r + 1;
117  for(size_t ell = 0; ell < r; ell++)
118  { z[m+ell] = Base(double(q)) * ( x[m+ell] - x[m+ell] * y[0] );
119  for(k = 1; k < q; k++)
120  z[m+ell] -= Base(double(k)) * x[(k-1)*r+1+ell] * y[(q-k-1)*r+1+ell];
121  z[m+ell] /= Base(double(q));
122  //
123  y[m+ell] = Base(2.0) * z[m+ell] * z[0];
124  for(k = 1; k < q; k++)
125  y[m+ell] += z[(k-1)*r+1+ell] * z[(q-k-1)*r+1+ell];
126  }
127 }
128 
129 /*!
130 Compute zero order forward mode Taylor coefficient for result of op = TanOp.
131 
132 The C++ source code corresponding to this operation is
133 \verbatim
134  z = tanh(x)
135 \endverbatim
136 The auxillary result is
137 \verbatim
138  y = cos(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_tanh_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; // called z in documentation
159  Base* y = z - cap_order; // called y in documentation
160 
161  z[0] = tanh( x[0] );
162  y[0] = z[0] * z[0];
163 }
164 
165 /*!
166 Compute reverse mode partial derivatives for result of op = TanOp.
167 
168 The C++ source code corresponding to this operation is
169 \verbatim
170  z = tanh(x)
171 \endverbatim
172 The auxillary result is
173 \verbatim
174  y = cos(x)
175 \endverbatim
176 The value of y is computed along with the value of z.
177 
178 \copydetails CppAD::local::reverse_unary2_op
179 */
180 
181 template <class Base>
182 inline void reverse_tanh_op(
183  size_t d ,
184  size_t i_z ,
185  size_t i_x ,
186  size_t cap_order ,
187  const Base* taylor ,
188  size_t nc_partial ,
189  Base* partial )
190 {
191  // check assumptions
194  CPPAD_ASSERT_UNKNOWN( d < cap_order );
195  CPPAD_ASSERT_UNKNOWN( d < nc_partial );
196 
197  // Taylor coefficients and partials corresponding to argument
198  const Base* x = taylor + i_x * cap_order;
199  Base* px = partial + i_x * nc_partial;
200 
201  // Taylor coefficients and partials corresponding to first result
202  const Base* z = taylor + i_z * cap_order; // called z in doc
203  Base* pz = partial + i_z * nc_partial;
204 
205  // Taylor coefficients and partials corresponding to auxillary result
206  const Base* y = z - cap_order; // called y in documentation
207  Base* py = pz - nc_partial;
208 
209 
210  size_t j = d;
211  size_t k;
212  Base base_two(2);
213  while(j)
214  {
215  px[j] += pz[j];
216  pz[j] /= Base(double(j));
217  for(k = 1; k <= j; k++)
218  { px[k] -= azmul(pz[j], y[j-k]) * Base(double(k));
219  py[j-k] -= azmul(pz[j], x[k]) * Base(double(k));
220  }
221  for(k = 0; k < j; k++)
222  pz[k] += azmul(py[j-1], z[j-k-1]) * base_two;
223 
224  --j;
225  }
226  px[0] += azmul(pz[0], Base(1.0) - y[0]);
227 }
228 
229 } } // END_CPPAD_LOCAL_NAMESPACE
230 # endif
AD< Base > azmul(const AD< Base > &x, const AD< Base > &y)
Definition: azmul.hpp:94
size_t NumArg(OpCode op)
Number of arguments for a specified operator.
Definition: op_code.hpp:175
void forward_tanh_op_0(size_t i_z, size_t i_x, size_t cap_order, Base *taylor)
Compute zero order forward mode Taylor coefficient for result of op = TanOp.
Definition: tanh_op.hpp:145
size_t NumRes(OpCode op)
Number of variables resulting from the specified operation.
Definition: op_code.hpp:281
void reverse_tanh_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)
Compute reverse mode partial derivatives for result of op = TanOp.
Definition: tanh_op.hpp:182
void forward_tanh_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 = TanOp.
Definition: tanh_op.hpp:95
AD< Base > tanh(const AD< Base > &x)
#define CPPAD_ASSERT_UNKNOWN(exp)
Check that exp is true, if not terminate execution.
void forward_tanh_op(size_t p, size_t q, size_t i_z, size_t i_x, size_t cap_order, Base *taylor)
Compute forward mode Taylor coefficient for result of op = TanOp.
Definition: tanh_op.hpp:40