source: trunk/cppad/local/div_op.hpp @ 2625

Last change on this file since 2625 was 2625, checked in by bradbell, 7 years ago

Change comment so end of group is included in doxygen processing
(do not know why works without this command at end).

ad_assign.hpp: fix doxygen brief description.
ad_ctor.hpp: fix doxygen brief description.

  • Property svn:keywords set to Id
File size: 11.2 KB
Line 
1/* $Id: div_op.hpp 2625 2012-12-23 14:34:12Z bradbell $ */
2# ifndef CPPAD_DIV_OP_INCLUDED
3# define CPPAD_DIV_OP_INCLUDED
4
5/* --------------------------------------------------------------------------
6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-12 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
16CPPAD_BEGIN_NAMESPACE
17/*!
18\defgroup div_op_hpp div_op.hpp
19\{
20\file div_op.hpp
21Forward and reverse mode calculations for z = x / y.
22*/
23
24// --------------------------- Divvv -----------------------------------------
25/*!
26Compute forward mode Taylor coefficients for result of op = DivvvOp.
27
28The C++ source code corresponding to this operation is
29\verbatim
30        z = x / y
31\endverbatim
32In the documentation below,
33this operations is for the case where both x and y are variables
34and the argument \a parameter is not used.
35
36\copydetails forward_binary_op
37*/
38
39template <class Base>
40inline void forward_divvv_op(
41        size_t        d           , 
42        size_t        i_z         ,
43        const addr_t* arg         ,
44        const Base*   parameter   ,
45        size_t        nc_taylor   ,
46        Base*         taylor      )
47{
48        // check assumptions
49        CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 );
50        CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 );
51        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
52        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
53        CPPAD_ASSERT_UNKNOWN( d < nc_taylor );
54
55        // Taylor coefficients corresponding to arguments and result
56        Base* x = taylor + arg[0] * nc_taylor;
57        Base* y = taylor + arg[1] * nc_taylor;
58        Base* z = taylor + i_z    * nc_taylor;
59
60
61        // Using CondExp, it can make sense to divide by zero,
62        // so do not make it an error.
63        size_t k;
64        z[d] = x[d];
65        for(k = 1; k <= d; k++)
66                z[d] -= z[d-k] * y[k];
67        z[d] /= y[0];
68}
69
70
71/*!
72Compute zero order forward mode Taylor coefficients for result of op = DivvvOp.
73
74The C++ source code corresponding to this operation is
75\verbatim
76        z = x / y
77\endverbatim
78In the documentation below,
79this operations is for the case where both x and y are variables
80and the argument \a parameter is not used.
81
82\copydetails forward_binary_op_0
83*/
84
85template <class Base>
86inline void forward_divvv_op_0(
87        size_t        i_z         ,
88        const addr_t* arg         ,
89        const Base*   parameter   ,
90        size_t        nc_taylor   ,
91        Base*         taylor      )
92{
93        // check assumptions
94        CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 );
95        CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 );
96        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
97        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
98
99        // Taylor coefficients corresponding to arguments and result
100        Base* x = taylor + arg[0] * nc_taylor;
101        Base* y = taylor + arg[1] * nc_taylor;
102        Base* z = taylor + i_z    * nc_taylor;
103
104        z[0] = x[0] / y[0];
105}
106
107/*!
108Compute reverse mode partial derivatives for result of op = DivvvOp.
109
110The C++ source code corresponding to this operation is
111\verbatim
112        z = x / y
113\endverbatim
114In the documentation below,
115this operations is for the case where both x and y are variables
116and the argument \a parameter is not used.
117
118\copydetails reverse_binary_op
119*/
120
121template <class Base>
122inline void reverse_divvv_op(
123        size_t        d           , 
124        size_t        i_z         ,
125        const addr_t* arg         ,
126        const Base*   parameter   ,
127        size_t        nc_taylor   ,
128        const Base*   taylor      ,
129        size_t        nc_partial  ,
130        Base*         partial     )
131{
132        // check assumptions
133        CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 );
134        CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 );
135        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
136        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
137        CPPAD_ASSERT_UNKNOWN( d < nc_taylor );
138        CPPAD_ASSERT_UNKNOWN( d < nc_partial );
139
140        // Arguments
141        const Base* y  = taylor + arg[1] * nc_taylor;
142        const Base* z  = taylor + i_z    * nc_taylor;
143
144        // Partial derivatives corresponding to arguments and result
145        Base* px = partial + arg[0] * nc_partial;
146        Base* py = partial + arg[1] * nc_partial;
147        Base* pz = partial + i_z    * nc_partial;
148
149        // Using CondExp, it can make sense to divide by zero
150        // so do not make it an error.
151
152        size_t k;
153        // number of indices to access
154        size_t j = d + 1;
155        while(j)
156        {       --j;
157                // scale partial w.r.t. z[j]
158                pz[j] /= y[0];
159
160                px[j] += pz[j];
161                for(k = 1; k <= j; k++)
162                {       pz[j-k] -= pz[j] * y[k];
163                        py[k]   -= pz[j] * z[j-k];
164                }       
165                py[0] -= pz[j] * z[j];
166        }
167}
168
169// --------------------------- Divpv -----------------------------------------
170/*!
171Compute forward mode Taylor coefficients for result of op = DivpvOp.
172
173The C++ source code corresponding to this operation is
174\verbatim
175        z = x / y
176\endverbatim
177In the documentation below,
178this operations is for the case where x is a parameter and y is a variable.
179
180\copydetails forward_binary_op
181*/
182
183template <class Base>
184inline void forward_divpv_op(
185        size_t        d           , 
186        size_t        i_z         ,
187        const addr_t* arg         ,
188        const Base*   parameter   ,
189        size_t        nc_taylor   ,
190        Base*         taylor      )
191{
192        // check assumptions
193        CPPAD_ASSERT_UNKNOWN( NumArg(DivpvOp) == 2 );
194        CPPAD_ASSERT_UNKNOWN( NumRes(DivpvOp) == 1 );
195        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
196        CPPAD_ASSERT_UNKNOWN( d < nc_taylor );
197
198        // Taylor coefficients corresponding to arguments and result
199        Base* y = taylor + arg[1] * nc_taylor;
200        Base* z = taylor + i_z    * nc_taylor;
201
202        // Paraemter value
203        Base x = parameter[ arg[0] ];
204
205        // Using CondExp, it can make sense to divide by zero,
206        // so do not make it an error.
207        size_t k;
208# if USE_CPPAD_FORWARD0SWEEP
209        z[d] = Base(0);
210# else
211        if( d == 0 )
212                z[d] = x;
213        else    z[d] = Base(0);
214# endif
215        for(k = 1; k <= d; k++)
216                z[d] -= z[d-k] * y[k];
217        z[d] /= y[0];
218
219}
220
221/*!
222Compute zero order forward mode Taylor coefficient for result of op = DivpvOp.
223
224The C++ source code corresponding to this operation is
225\verbatim
226        z = x / y
227\endverbatim
228In the documentation below,
229this operations is for the case where x is a parameter and y is a variable.
230
231\copydetails forward_binary_op_0
232*/
233
234template <class Base>
235inline void forward_divpv_op_0(
236        size_t        i_z         ,
237        const addr_t* arg         ,
238        const Base*   parameter   ,
239        size_t        nc_taylor   ,
240        Base*         taylor      )
241{
242        // check assumptions
243        CPPAD_ASSERT_UNKNOWN( NumArg(DivpvOp) == 2 );
244        CPPAD_ASSERT_UNKNOWN( NumRes(DivpvOp) == 1 );
245        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
246
247        // Paraemter value
248        Base x = parameter[ arg[0] ];
249
250        // Taylor coefficients corresponding to arguments and result
251        Base* y = taylor + arg[1] * nc_taylor;
252        Base* z = taylor + i_z    * nc_taylor;
253
254        z[0] = x / y[0];
255}
256
257/*!
258Compute reverse mode partial derivative for result of op = DivpvOp.
259
260The C++ source code corresponding to this operation is
261\verbatim
262        z = x / y
263\endverbatim
264In the documentation below,
265this operations is for the case where x is a parameter and y is a variable.
266
267\copydetails reverse_binary_op
268*/
269
270template <class Base>
271inline void reverse_divpv_op(
272        size_t        d           , 
273        size_t        i_z         ,
274        const addr_t* arg         ,
275        const Base*   parameter   ,
276        size_t        nc_taylor   ,
277        const Base*   taylor      ,
278        size_t        nc_partial  ,
279        Base*         partial     )
280{
281        // check assumptions
282        CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 );
283        CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 );
284        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
285        CPPAD_ASSERT_UNKNOWN( d < nc_taylor );
286        CPPAD_ASSERT_UNKNOWN( d < nc_partial );
287
288        // Arguments
289        const Base* y = taylor + arg[1] * nc_taylor;
290        const Base* z = taylor + i_z    * nc_taylor;
291
292        // Partial derivatives corresponding to arguments and result
293        Base* py = partial + arg[1] * nc_partial;
294        Base* pz = partial + i_z    * nc_partial;
295
296        // Using CondExp, it can make sense to divide by zero so do not
297        // make it an error.
298
299        size_t k;
300        // number of indices to access
301        size_t j = d + 1;
302        while(j)
303        {       --j;
304                // scale partial w.r.t z[j]
305                pz[j] /= y[0];
306
307                for(k = 1; k <= j; k++)
308                {       pz[j-k] -= pz[j] * y[k];
309                        py[k]   -= pz[j] * z[j-k];
310                }       
311                py[0] -= pz[j] * z[j];
312        }
313}
314
315
316// --------------------------- Divvp -----------------------------------------
317/*!
318Compute forward mode Taylor coefficients for result of op = DivvvOp.
319
320The C++ source code corresponding to this operation is
321\verbatim
322        z = x / y
323\endverbatim
324In the documentation below,
325this operations is for the case where x is a variable and y is a parameter.
326
327\copydetails forward_binary_op
328*/
329
330template <class Base>
331inline void forward_divvp_op(
332        size_t        d           , 
333        size_t        i_z         ,
334        const addr_t* arg         ,
335        const Base*   parameter   ,
336        size_t        nc_taylor   ,
337        Base*         taylor      )
338{
339        // check assumptions
340        CPPAD_ASSERT_UNKNOWN( NumArg(DivvpOp) == 2 );
341        CPPAD_ASSERT_UNKNOWN( NumRes(DivvpOp) == 1 );
342        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
343        CPPAD_ASSERT_UNKNOWN( d < nc_taylor );
344
345        // Taylor coefficients corresponding to arguments and result
346        Base* x = taylor + arg[0] * nc_taylor;
347        Base* z = taylor + i_z    * nc_taylor;
348
349        // Parameter value
350        Base y = parameter[ arg[1] ];
351
352        // Using CondExp and multiple levels of AD, it can make sense
353        // to divide by zero so do not make it an error.
354        z[d] = x[d] / y;
355}
356
357
358/*!
359Compute zero order forward mode Taylor coefficients for result of op = DivvvOp.
360
361The C++ source code corresponding to this operation is
362\verbatim
363        z = x / y
364\endverbatim
365In the documentation below,
366this operations is for the case where x is a variable and y is a parameter.
367
368\copydetails forward_binary_op_0
369*/
370
371template <class Base>
372inline void forward_divvp_op_0(
373        size_t        i_z         ,
374        const addr_t* arg         ,
375        const Base*   parameter   ,
376        size_t        nc_taylor   ,
377        Base*         taylor      )
378{
379        // check assumptions
380        CPPAD_ASSERT_UNKNOWN( NumArg(DivvpOp) == 2 );
381        CPPAD_ASSERT_UNKNOWN( NumRes(DivvpOp) == 1 );
382        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
383
384        // Parameter value
385        Base y = parameter[ arg[1] ];
386
387        // Taylor coefficients corresponding to arguments and result
388        Base* x = taylor + arg[0] * nc_taylor;
389        Base* z = taylor + i_z    * nc_taylor;
390
391        z[0] = x[0] / y;
392}
393
394/*!
395Compute reverse mode partial derivative for result of op = DivvpOp.
396
397The C++ source code corresponding to this operation is
398\verbatim
399        z = x / y
400\endverbatim
401In the documentation below,
402this operations is for the case where x is a variable and y is a parameter.
403
404\copydetails reverse_binary_op
405*/
406
407template <class Base>
408inline void reverse_divvp_op(
409        size_t        d           , 
410        size_t        i_z         ,
411        const addr_t* arg         ,
412        const Base*   parameter   ,
413        size_t        nc_taylor   ,
414        const Base*   taylor      ,
415        size_t        nc_partial  ,
416        Base*         partial     )
417{
418        // check assumptions
419        CPPAD_ASSERT_UNKNOWN( NumArg(DivvpOp) == 2 );
420        CPPAD_ASSERT_UNKNOWN( NumRes(DivvpOp) == 1 );
421        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
422        CPPAD_ASSERT_UNKNOWN( d < nc_taylor );
423        CPPAD_ASSERT_UNKNOWN( d < nc_partial );
424
425        // Argument values
426        Base  y = parameter[ arg[1] ];
427
428        // Partial derivatives corresponding to arguments and result
429        Base* px = partial + arg[0] * nc_partial;
430        Base* pz = partial + i_z    * nc_partial;
431
432        // Using CondExp, it can make sense to divide by zero
433        // so do not make it an error.
434
435        // number of indices to access
436        size_t j = d + 1;
437        while(j)
438        {       --j;
439                px[j] += pz[j] / y;
440        }
441}
442
443/*! \} */
444CPPAD_END_NAMESPACE
445# endif
Note: See TracBrowser for help on using the repository browser.