source: trunk/cppad/local/tanh_op.hpp @ 3301

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

merge in multiple forward direcitons from branches/forward_dir

  • Property svn:keywords set to Id
File size: 5.9 KB
Line 
1/* $Id: tanh_op.hpp 3301 2014-05-24 05:20:21Z 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( i_x + 1 < i_z );
53        CPPAD_ASSERT_UNKNOWN( q < cap_order );
54        CPPAD_ASSERT_UNKNOWN( p <= q );
55
56        // Taylor coefficients corresponding to argument and result
57        Base* x = taylor + i_x * cap_order;
58        Base* z = taylor + i_z * cap_order;
59        Base* y = z      -       cap_order;
60
61        size_t k;
62        if( p == 0 )
63        {       z[0] = tanh( x[0] );
64                y[0] = z[0] * z[0];
65                p++;
66        }
67        for(size_t j = p; j <= q; j++)
68        {       Base base_j = static_cast<Base>(j);
69
70                z[j] = x[j];
71                for(k = 1; k <= j; k++)
72                        z[j] -= Base(k) * x[k] * y[j-k] / base_j;
73
74                y[j] = z[0] * z[j];
75                for(k = 1; k <= j; k++)
76                        y[j] += z[k] * z[j-k];
77        }
78}
79
80/*!
81Multiple directions forward mode Taylor coefficient for op = TanOp.
82
83The C++ source code corresponding to this operation is
84\verbatim
85        z = tanh(x)
86\endverbatim
87The auxillary result is
88\verbatim
89        y = tanh(x)^2
90\endverbatim
91The value of y, and its derivatives, are computed along with the value
92and derivatives of z.
93
94\copydetails forward_unary2_op_dir
95*/
96template <class Base>
97inline void forward_tanh_op_dir(
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
106        CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );
107        CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );
108        CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
109        CPPAD_ASSERT_UNKNOWN( 0 < q );
110        CPPAD_ASSERT_UNKNOWN( q < cap_order );
111
112        // Taylor coefficients corresponding to argument and result
113        size_t num_taylor_per_var = (cap_order-1) * r + 1;
114        Base* x = taylor + i_x * num_taylor_per_var;
115        Base* z = taylor + i_z * num_taylor_per_var;
116        Base* y = z      -       num_taylor_per_var;
117
118        size_t k;
119        size_t m = (q-1) * r + 1;
120        for(size_t ell = 0; ell < r; ell++)
121        {       z[m+ell] = Base(q) * ( x[m+ell] - x[m+ell] * y[0] );
122                for(k = 1; k < q; k++)
123                        z[m+ell] -= Base(k) * x[(k-1)*r+1+ell] * y[(q-k-1)*r+1+ell];
124                z[m+ell] /= Base(q);
125                //
126                y[m+ell] = Base(2) * z[m+ell] * z[0];
127                for(k = 1; k < q; k++)
128                        y[m+ell] += z[(k-1)*r+1+ell] * z[(q-k-1)*r+1+ell];
129        }
130}
131
132/*!
133Compute zero order forward mode Taylor coefficient for result of op = TanOp.
134
135The C++ source code corresponding to this operation is
136\verbatim
137        z = tanh(x)
138\endverbatim
139The auxillary result is
140\verbatim
141        y = cos(x)
142\endverbatim
143The value of y is computed along with the value of z.
144
145\copydetails forward_unary2_op_0
146*/
147template <class Base>
148inline void forward_tanh_op_0(
149        size_t i_z         ,
150        size_t i_x         ,
151        size_t cap_order   , 
152        Base*  taylor      )
153{
154        // check assumptions
155        CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );
156        CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );
157        CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
158        CPPAD_ASSERT_UNKNOWN( 0 < cap_order );
159
160        // Taylor coefficients corresponding to argument and result
161        Base* x = taylor + i_x * cap_order;
162        Base* z = taylor + i_z * cap_order;  // called z in documentation
163        Base* y = z      -       cap_order;  // called y in documentation
164
165        z[0] = tanh( x[0] );
166        y[0] = z[0] * z[0];
167}
168
169/*!
170Compute reverse mode partial derivatives for result of op = TanOp.
171
172The C++ source code corresponding to this operation is
173\verbatim
174        z = tanh(x)
175\endverbatim
176The auxillary result is
177\verbatim
178        y = cos(x)
179\endverbatim
180The value of y is computed along with the value of z.
181
182\copydetails reverse_unary2_op
183*/
184
185template <class Base>
186inline void reverse_tanh_op(
187        size_t      d            ,
188        size_t      i_z          ,
189        size_t      i_x          ,
190        size_t      cap_order    , 
191        const Base* taylor       ,
192        size_t      nc_partial   ,
193        Base*       partial      )
194{
195        // check assumptions
196        CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );
197        CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );
198        CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
199        CPPAD_ASSERT_UNKNOWN( d < cap_order );
200        CPPAD_ASSERT_UNKNOWN( d < nc_partial );
201
202        // Taylor coefficients and partials corresponding to argument
203        const Base* x  = taylor  + i_x * cap_order;
204        Base* px       = partial + i_x * nc_partial;
205
206        // Taylor coefficients and partials corresponding to first result
207        const Base* z  = taylor  + i_z * cap_order; // called z in doc
208        Base* pz       = partial + i_z * nc_partial;
209
210        // Taylor coefficients and partials corresponding to auxillary result
211        const Base* y  = z  - cap_order; // called y in documentation
212        Base* py       = pz - nc_partial;
213
214        size_t j = d;
215        size_t k;
216        Base base_two(2);
217        while(j)
218        {
219                px[j]   += pz[j];
220                pz[j]   /= Base(j);
221                for(k = 1; k <= j; k++)
222                {       px[k]   -= pz[j] * y[j-k] * Base(k);
223                        py[j-k] -= pz[j] * x[k] * Base(k);
224                }
225                for(k = 0; k < j; k++)
226                        pz[k] += py[j-1] * z[j-k-1] * base_two;
227       
228                --j;
229        }
230        px[0] += pz[0] * (Base(1) - y[0]);
231}
232
233} // END_CPPAD_NAMESPACE
234# endif
Note: See TracBrowser for help on using the repository browser.