source: branches/cache/cppad/local/tanh_op.hpp @ 3324

Last change on this file since 3324 was 3324, checked in by bradbell, 6 years ago

merge trunk changes into cache

  • Property svn:keywords set to Id
File size: 5.7 KB
Line 
1/* $Id: tanh_op.hpp 3324 2014-09-12 12:14:53Z bradbell $ */
2# ifndef CPPAD_TANH_OP_INCLUDED
3# define CPPAD_TANH_OP_INCLUDED
4
5/* --------------------------------------------------------------------------
6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 Bradley M. Bell
7
8CppAD is distributed under multiple licenses. This distribution is under
9the terms of the
10                    Eclipse Public License Version 1.0.
11
12A copy of this license is included in the COPYING file of this distribution.
13Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
14-------------------------------------------------------------------------- */
15
16
17namespace CppAD { // BEGIN_CPPAD_NAMESPACE
18/*!
19\file tanh_op.hpp
20Forward and reverse mode calculations for z = tanh(x).
21*/
22
23
24/*!
25Compute forward mode Taylor coefficient for result of op = TanOp.
26
27The C++ source code corresponding to this operation is
28\verbatim
29        z = tanh(x)
30\endverbatim
31The auxillary result is
32\verbatim
33        y = tanh(x)^2
34\endverbatim
35The value of y, and its derivatives, are computed along with the value
36and derivatives of z.
37
38\copydetails forward_unary2_op
39*/
40template <class Base>
41inline void forward_tanh_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
50        CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );
51        CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );
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* y = z      -       cap_order;
59
60        size_t k;
61        if( p == 0 )
62        {       z[0] = tanh( x[0] );
63                y[0] = z[0] * z[0];
64                p++;
65        }
66        for(size_t j = p; j <= q; j++)
67        {       Base base_j = static_cast<Base>(j);
68
69                z[j] = x[j];
70                for(k = 1; k <= j; k++)
71                        z[j] -= Base(k) * x[k] * y[j-k] / base_j;
72
73                y[j] = z[0] * z[j];
74                for(k = 1; k <= j; k++)
75                        y[j] += z[k] * z[j-k];
76        }
77}
78
79/*!
80Multiple directions forward mode Taylor coefficient for op = TanOp.
81
82The C++ source code corresponding to this operation is
83\verbatim
84        z = tanh(x)
85\endverbatim
86The auxillary result is
87\verbatim
88        y = tanh(x)^2
89\endverbatim
90The value of y, and its derivatives, are computed along with the value
91and derivatives of z.
92
93\copydetails forward_unary2_op_dir
94*/
95template <class Base>
96inline void forward_tanh_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
105        CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );
106        CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );
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* y = z      -       num_taylor_per_var;
115
116        size_t k;
117        size_t m = (q-1) * r + 1;
118        for(size_t ell = 0; ell < r; ell++)
119        {       z[m+ell] = Base(q) * ( x[m+ell] - x[m+ell] * y[0] );
120                for(k = 1; k < q; k++)
121                        z[m+ell] -= Base(k) * x[(k-1)*r+1+ell] * y[(q-k-1)*r+1+ell];
122                z[m+ell] /= Base(q);
123                //
124                y[m+ell] = Base(2) * z[m+ell] * z[0];
125                for(k = 1; k < q; k++)
126                        y[m+ell] += z[(k-1)*r+1+ell] * z[(q-k-1)*r+1+ell];
127        }
128}
129
130/*!
131Compute zero order forward mode Taylor coefficient for result of op = TanOp.
132
133The C++ source code corresponding to this operation is
134\verbatim
135        z = tanh(x)
136\endverbatim
137The auxillary result is
138\verbatim
139        y = cos(x)
140\endverbatim
141The value of y is computed along with the value of z.
142
143\copydetails forward_unary2_op_0
144*/
145template <class Base>
146inline void forward_tanh_op_0(
147        size_t i_z         ,
148        size_t i_x         ,
149        size_t cap_order   , 
150        Base*  taylor      )
151{
152        // check assumptions
153        CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );
154        CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );
155        CPPAD_ASSERT_UNKNOWN( 0 < cap_order );
156
157        // Taylor coefficients corresponding to argument and result
158        Base* x = taylor + i_x * cap_order;
159        Base* z = taylor + i_z * cap_order;  // called z in documentation
160        Base* y = z      -       cap_order;  // called y in documentation
161
162        z[0] = tanh( x[0] );
163        y[0] = z[0] * z[0];
164}
165
166/*!
167Compute reverse mode partial derivatives for result of op = TanOp.
168
169The C++ source code corresponding to this operation is
170\verbatim
171        z = tanh(x)
172\endverbatim
173The auxillary result is
174\verbatim
175        y = cos(x)
176\endverbatim
177The value of y is computed along with the value of z.
178
179\copydetails reverse_unary2_op
180*/
181
182template <class Base>
183inline void reverse_tanh_op(
184        size_t      d            ,
185        size_t      i_z          ,
186        size_t      i_x          ,
187        size_t      cap_order    , 
188        const Base* taylor       ,
189        size_t      nc_partial   ,
190        Base*       partial      )
191{
192        // check assumptions
193        CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );
194        CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );
195        CPPAD_ASSERT_UNKNOWN( d < cap_order );
196        CPPAD_ASSERT_UNKNOWN( d < nc_partial );
197
198        // Taylor coefficients and partials corresponding to argument
199        const Base* x  = taylor  + i_x * cap_order;
200        Base* px       = partial + i_x * nc_partial;
201
202        // Taylor coefficients and partials corresponding to first result
203        const Base* z  = taylor  + i_z * cap_order; // called z in doc
204        Base* pz       = partial + i_z * nc_partial;
205
206        // Taylor coefficients and partials corresponding to auxillary result
207        const Base* y  = z  - cap_order; // called y in documentation
208        Base* py       = pz - nc_partial;
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(j);
217                for(k = 1; k <= j; k++)
218                {       px[k]   -= pz[j] * y[j-k] * Base(k);
219                        py[j-k] -= pz[j] * x[k] * Base(k);
220                }
221                for(k = 0; k < j; k++)
222                        pz[k] += py[j-1] * z[j-k-1] * base_two;
223       
224                --j;
225        }
226        px[0] += pz[0] * (Base(1) - y[0]);
227}
228
229} // END_CPPAD_NAMESPACE
230# endif
Note: See TracBrowser for help on using the repository browser.