source: trunk/cppad/local/sinh_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: 6.4 KB
Line 
1/* $Id: sinh_op.hpp 3301 2014-05-24 05:20:21Z bradbell $ */
2# ifndef CPPAD_SINH_OP_INCLUDED
3# define CPPAD_SINH_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 sinh_op.hpp
20Forward and reverse mode calculations for z = sinh(x).
21*/
22
23
24/*!
25Compute forward mode Taylor coefficient for result of op = SinhOp.
26
27The C++ source code corresponding to this operation is
28\verbatim
29        z = sinh(x)
30\endverbatim
31The auxillary result is
32\verbatim
33        y = cosh(x)
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_sinh_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(SinhOp) == 1 );
51        CPPAD_ASSERT_UNKNOWN( NumRes(SinhOp) == 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* s = taylor + i_z * cap_order;
59        Base* c = s      -       cap_order;
60
61
62        // rest of this routine is identical for the following cases:
63        // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op
64        // (except that there is a sign difference for hyperbolic case).
65        size_t k;
66        if( p == 0 )
67        {       s[0] = sinh( x[0] );
68                c[0] = cosh( x[0] );
69                p++;
70        }
71        for(size_t j = p; j <= q; j++)
72        {
73                s[j] = Base(0);
74                c[j] = Base(0);
75                for(k = 1; k <= j; k++)
76                {       s[j] += Base(k) * x[k] * c[j-k];
77                        c[j] += Base(k) * x[k] * s[j-k];
78                }
79                s[j] /= Base(j);
80                c[j] /= Base(j);
81        }
82}
83/*!
84Compute forward mode Taylor coefficient for result of op = SinhOp.
85
86The C++ source code corresponding to this operation is
87\verbatim
88        z = sinh(x)
89\endverbatim
90The auxillary result is
91\verbatim
92        y = cosh(x)
93\endverbatim
94The value of y, and its derivatives, are computed along with the value
95and derivatives of z.
96
97\copydetails forward_unary2_op_dir
98*/
99template <class Base>
100inline void forward_sinh_op_dir(
101        size_t q           ,
102        size_t r           ,
103        size_t i_z         ,
104        size_t i_x         ,
105        size_t cap_order   , 
106        Base*  taylor      )
107{       
108        // check assumptions
109        CPPAD_ASSERT_UNKNOWN( NumArg(SinhOp) == 1 );
110        CPPAD_ASSERT_UNKNOWN( NumRes(SinhOp) == 2 );
111        CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
112        CPPAD_ASSERT_UNKNOWN( 0 < q );
113        CPPAD_ASSERT_UNKNOWN( q < cap_order );
114
115        // Taylor coefficients corresponding to argument and result
116        size_t num_taylor_per_var = (cap_order-1) * r + 1;
117        Base* x = taylor + i_x * num_taylor_per_var;
118        Base* s = taylor + i_z * num_taylor_per_var;
119        Base* c = s      -       num_taylor_per_var;
120
121
122        // rest of this routine is identical for the following cases:
123        // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op
124        // (except that there is a sign difference for the hyperbolic case).
125        size_t m = (q-1) * r + 1;
126        for(size_t ell = 0; ell < r; ell++)
127        {       s[m+ell] = Base(q) * x[m + ell] * c[0];
128                c[m+ell] = Base(q) * x[m + ell] * s[0];
129                for(size_t k = 1; k < q; k++)
130                {       s[m+ell] += Base(k) * x[(k-1)*r+1+ell] * c[(q-k-1)*r+1+ell];
131                        c[m+ell] += Base(k) * x[(k-1)*r+1+ell] * s[(q-k-1)*r+1+ell];
132                }
133                s[m+ell] /= Base(q);
134                c[m+ell] /= Base(q);
135        }
136}
137
138/*!
139Compute zero order forward mode Taylor coefficient for result of op = SinhOp.
140
141The C++ source code corresponding to this operation is
142\verbatim
143        z = sinh(x)
144\endverbatim
145The auxillary result is
146\verbatim
147        y = cosh(x)
148\endverbatim
149The value of y is computed along with the value of z.
150
151\copydetails forward_unary2_op_0
152*/
153template <class Base>
154inline void forward_sinh_op_0(
155        size_t i_z         ,
156        size_t i_x         ,
157        size_t cap_order   , 
158        Base*  taylor      )
159{
160        // check assumptions
161        CPPAD_ASSERT_UNKNOWN( NumArg(SinhOp) == 1 );
162        CPPAD_ASSERT_UNKNOWN( NumRes(SinhOp) == 2 );
163        CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
164        CPPAD_ASSERT_UNKNOWN( 0 < cap_order );
165
166        // Taylor coefficients corresponding to argument and result
167        Base* x = taylor + i_x * cap_order;
168        Base* s = taylor + i_z * cap_order;  // called z in documentation
169        Base* c = s      -       cap_order;  // called y in documentation
170
171        s[0] = sinh( x[0] );
172        c[0] = cosh( x[0] );
173}
174/*!
175Compute reverse mode partial derivatives for result of op = SinhOp.
176
177The C++ source code corresponding to this operation is
178\verbatim
179        z = sinh(x)
180\endverbatim
181The auxillary result is
182\verbatim
183        y = cosh(x)
184\endverbatim
185The value of y is computed along with the value of z.
186
187\copydetails reverse_unary2_op
188*/
189
190template <class Base>
191inline void reverse_sinh_op(
192        size_t      d            ,
193        size_t      i_z          ,
194        size_t      i_x          ,
195        size_t      cap_order    , 
196        const Base* taylor       ,
197        size_t      nc_partial   ,
198        Base*       partial      )
199{
200        // check assumptions
201        CPPAD_ASSERT_UNKNOWN( NumArg(SinhOp) == 1 );
202        CPPAD_ASSERT_UNKNOWN( NumRes(SinhOp) == 2 );
203        CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
204        CPPAD_ASSERT_UNKNOWN( d < cap_order );
205        CPPAD_ASSERT_UNKNOWN( d < nc_partial );
206
207        // Taylor coefficients and partials corresponding to argument
208        const Base* x  = taylor  + i_x * cap_order;
209        Base* px       = partial + i_x * nc_partial;
210
211        // Taylor coefficients and partials corresponding to first result
212        const Base* s  = taylor  + i_z * cap_order; // called z in doc
213        Base* ps       = partial + i_z * nc_partial;
214
215        // Taylor coefficients and partials corresponding to auxillary result
216        const Base* c  = s  - cap_order; // called y in documentation
217        Base* pc       = ps - nc_partial;
218
219        // rest of this routine is identical for the following cases:
220        // reverse_sin_op, reverse_cos_op, reverse_sinh_op, reverse_cosh_op.
221        size_t j = d;
222        size_t k;
223        while(j)
224        {
225                ps[j]   /= Base(j);
226                pc[j]   /= Base(j);
227                for(k = 1; k <= j; k++)
228                {
229                        px[k]   += ps[j] * Base(k) * c[j-k];
230                        px[k]   += pc[j] * Base(k) * s[j-k];
231       
232                        ps[j-k] += pc[j] * Base(k) * x[k];
233                        pc[j-k] += ps[j] * Base(k) * x[k];
234
235                }
236                --j;
237        }
238        px[0] += ps[0] * c[0];
239        px[0] += pc[0] * s[0];
240}
241
242} // END_CPPAD_NAMESPACE
243# endif
Note: See TracBrowser for help on using the repository browser.