source: trunk/cppad/local/tan_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.8 KB
Line 
1/* $Id: tan_op.hpp 3301 2014-05-24 05:20:21Z bradbell $ */
2# ifndef CPPAD_TAN_OP_INCLUDED
3# define CPPAD_TAN_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 tan_op.hpp
20Forward and reverse mode calculations for z = tan(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 = tan(x)
30\endverbatim
31The auxillary result is
32\verbatim
33        y = tan(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_tan_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] = tan( 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 = tan(x)
86\endverbatim
87The auxillary result is
88\verbatim
89        y = tan(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_tan_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
133/*!
134Compute zero order forward mode Taylor coefficient for result of op = TanOp.
135
136The C++ source code corresponding to this operation is
137\verbatim
138        z = tan(x)
139\endverbatim
140The auxillary result is
141\verbatim
142        y = cos(x)
143\endverbatim
144The value of y is computed along with the value of z.
145
146\copydetails forward_unary2_op_0
147*/
148template <class Base>
149inline void forward_tan_op_0(
150        size_t i_z         ,
151        size_t i_x         ,
152        size_t cap_order   , 
153        Base*  taylor      )
154{
155        // check assumptions
156        CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );
157        CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );
158        CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
159        CPPAD_ASSERT_UNKNOWN( 0 < cap_order );
160
161        // Taylor coefficients corresponding to argument and result
162        Base* x = taylor + i_x * cap_order;
163        Base* z = taylor + i_z * cap_order;  // called z in documentation
164        Base* y = z      -       cap_order;  // called y in documentation
165
166        z[0] = tan( x[0] );
167        y[0] = z[0] * z[0];
168}
169
170/*!
171Compute reverse mode partial derivatives for result of op = TanOp.
172
173The C++ source code corresponding to this operation is
174\verbatim
175        z = tan(x)
176\endverbatim
177The auxillary result is
178\verbatim
179        y = cos(x)
180\endverbatim
181The value of y is computed along with the value of z.
182
183\copydetails reverse_unary2_op
184*/
185
186template <class Base>
187inline void reverse_tan_op(
188        size_t      d            ,
189        size_t      i_z          ,
190        size_t      i_x          ,
191        size_t      cap_order    , 
192        const Base* taylor       ,
193        size_t      nc_partial   ,
194        Base*       partial      )
195{
196        // check assumptions
197        CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );
198        CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );
199        CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
200        CPPAD_ASSERT_UNKNOWN( d < cap_order );
201        CPPAD_ASSERT_UNKNOWN( d < nc_partial );
202
203        // Taylor coefficients and partials corresponding to argument
204        const Base* x  = taylor  + i_x * cap_order;
205        Base* px       = partial + i_x * nc_partial;
206
207        // Taylor coefficients and partials corresponding to first result
208        const Base* z  = taylor  + i_z * cap_order; // called z in doc
209        Base* pz       = partial + i_z * nc_partial;
210
211        // Taylor coefficients and partials corresponding to auxillary result
212        const Base* y  = z  - cap_order; // called y in documentation
213        Base* py       = pz - nc_partial;
214
215        size_t j = d;
216        size_t k;
217        Base base_two(2);
218        while(j)
219        {
220                px[j]   += pz[j];
221                pz[j]   /= Base(j);
222                for(k = 1; k <= j; k++)
223                {       px[k]   += pz[j] * y[j-k] * Base(k);
224                        py[j-k] += pz[j] * x[k] * Base(k);
225                }
226                for(k = 0; k < j; k++)
227                        pz[k] += py[j-1] * z[j-k-1] * base_two;
228       
229                --j;
230        }
231        px[0] += pz[0] * (Base(1) + y[0]);
232}
233
234} // END_CPPAD_NAMESPACE
235# endif
Note: See TracBrowser for help on using the repository browser.