CppAD: A C++ Algorithmic Differentiation Package 20110419
abs_op.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_ABS_OP_INCLUDED
00003 # define CPPAD_ABS_OP_INCLUDED
00004 
00005 /* --------------------------------------------------------------------------
00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-10 Bradley M. Bell
00007 
00008 CppAD is distributed under multiple licenses. This distribution is under
00009 the terms of the 
00010                     Common Public License Version 1.0.
00011 
00012 A copy of this license is included in the COPYING file of this distribution.
00013 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
00014 -------------------------------------------------------------------------- */
00015 
00016 
00017 CPPAD_BEGIN_NAMESPACE
00018 /*!
00019 \file abs_op.hpp
00020 Forward and reverse mode calculations for z = abs(x).
00021 */
00022 
00023 
00024 /*!
00025 Compute forward mode Taylor coefficient for result of op = AbsOp.
00026 
00027 The C++ source code corresponding to this operation is
00028 \verbatim
00029         z = abs(x)
00030 \endverbatim
00031 
00032 \copydetails forward_unary1_op
00033 */
00034 template <class Base>
00035 inline void forward_abs_op(
00036         size_t j           ,
00037         size_t i_z         ,
00038         size_t i_x         ,
00039         size_t nc_taylor   , 
00040         Base*  taylor      )
00041 {
00042         size_t k;
00043         static Base zero(0);
00044 
00045         // check assumptions
00046         CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 );
00047         CPPAD_ASSERT_UNKNOWN( NumRes(AbsOp) == 1 );
00048         CPPAD_ASSERT_UNKNOWN( i_x < i_z );
00049         CPPAD_ASSERT_UNKNOWN( j < nc_taylor );
00050 
00051         // Taylor coefficients corresponding to argument and result
00052         Base* x = taylor + i_x * nc_taylor;
00053         Base* z = taylor + i_z * nc_taylor;
00054 
00055         // order that decides positive, negative or zero
00056         k = 0;
00057         while( (k < j) & (x[k] == zero) )
00058                 k++; 
00059 
00060         if( GreaterThanZero(x[k]) )
00061                 z[j]  = x[j];
00062         else if( LessThanZero(x[k]) )
00063                 z[j] = -x[j]; 
00064         else    z[j] = zero;
00065 }
00066 
00067 /*!
00068 Compute zero order forward mode Taylor coefficient for result of op = AbsOp.
00069 
00070 The C++ source code corresponding to this operation is
00071 \verbatim
00072         z = abs(x)
00073 \endverbatim
00074 
00075 \copydetails forward_unary1_op_0
00076 */
00077 template <class Base>
00078 inline void forward_abs_op_0(
00079         size_t i_z         ,
00080         size_t i_x         ,
00081         size_t nc_taylor   , 
00082         Base*  taylor      )
00083 {
00084 
00085         // check assumptions
00086         CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 );
00087         CPPAD_ASSERT_UNKNOWN( NumRes(AbsOp) == 1 );
00088         CPPAD_ASSERT_UNKNOWN( i_x < i_z );
00089         CPPAD_ASSERT_UNKNOWN( 0 < nc_taylor );
00090 
00091         // Taylor coefficients corresponding to argument and result
00092         Base y0 = *(taylor + i_x * nc_taylor);
00093         Base* z = taylor + i_z * nc_taylor;
00094 
00095         if( LessThanZero(y0) )
00096                 z[0]  = - y0;
00097         else    z[0] = y0; 
00098 }
00099 /*!
00100 Compute reverse mode partial derivatives for result of op = AbsOp.
00101 
00102 The C++ source code corresponding to this operation is
00103 \verbatim
00104         z = abs(x)
00105 \endverbatim
00106 
00107 \copydetails reverse_unary1_op
00108 */
00109 
00110 template <class Base>
00111 inline void reverse_abs_op(
00112         size_t      d            ,
00113         size_t      i_z          ,
00114         size_t      i_x          ,
00115         size_t      nc_taylor    , 
00116         const Base* taylor       ,
00117         size_t      nc_partial   ,
00118         Base*       partial      )
00119 {       size_t j, k;    
00120         static Base zero(0);
00121 
00122 
00123         // check assumptions
00124         CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 );
00125         CPPAD_ASSERT_UNKNOWN( NumRes(AbsOp) == 1 );
00126         CPPAD_ASSERT_UNKNOWN( i_x < i_z );
00127         CPPAD_ASSERT_UNKNOWN( d < nc_taylor );
00128         CPPAD_ASSERT_UNKNOWN( d < nc_partial );
00129 
00130         // Taylor coefficients and partials corresponding to argument
00131         const Base* x  = taylor  + i_x * nc_taylor;
00132         Base* px       = partial + i_x * nc_partial;
00133 
00134         // Taylor coefficients and partials corresponding to result
00135         Base* pz       = partial +    i_z * nc_partial;
00136 
00137         // order that decides positive, negative or zero
00138         k = 0;
00139         while( (k < d) & (x[k] == zero) )
00140                 k++; 
00141 
00142         if( GreaterThanZero(x[k]) )
00143         {       // partial of z w.r.t y is +1
00144                 for(j = k; j <= d; j++)
00145                         px[j] += pz[j];
00146         }
00147         else if( LessThanZero(x[k]) )
00148         {       // partial of z w.r.t y is -1
00149                 for(j = k; j <= d; j++)
00150                         px[j] -= pz[j];
00151         }
00152 }
00153 
00154 CPPAD_END_NAMESPACE
00155 # endif