CppAD: A C++ Algorithmic Differentiation Package
20130918
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_ABS_INCLUDED 00003 # define CPPAD_ABS_INCLUDED 00004 00005 /* -------------------------------------------------------------------------- 00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-12 Bradley M. Bell 00007 00008 CppAD is distributed under multiple licenses. This distribution is under 00009 the terms of the 00010 Eclipse 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 ------------------------------------------------------------------------------- 00018 $begin abs$$ 00019 $spell 00020 fabs 00021 Vec 00022 std 00023 faq 00024 Taylor 00025 Cpp 00026 namespace 00027 const 00028 abs 00029 $$ 00030 00031 $index abs, AD$$ 00032 $index fabs, AD$$ 00033 $index absolute, AD value$$ 00034 $index value, AD absolute$$ 00035 00036 $section AD Absolute Value Function$$ 00037 00038 $head Syntax$$ 00039 $icode%y% = abs(%x%) 00040 %$$ 00041 $icode%y% = fabs(%x%)%$$ 00042 00043 00044 $head Purpose$$ 00045 Evaluates the absolute value function. 00046 00047 $head x$$ 00048 The argument $icode x$$ has one of the following prototypes 00049 $codei% 00050 const AD<%Base%> &%x% 00051 const VecAD<%Base%>::reference &%x% 00052 %$$ 00053 00054 $head y$$ 00055 The result $icode y$$ has prototype 00056 $codei% 00057 AD<%Base%> %y% 00058 %$$ 00059 00060 00061 $head Operation Sequence$$ 00062 This is an AD of $icode Base$$ 00063 $cref/atomic operation/glossary/Operation/Atomic/$$ 00064 and hence is part of the current 00065 AD of $icode Base$$ 00066 $cref/operation sequence/glossary/Operation/Sequence/$$. 00067 00068 $head Complex Types$$ 00069 The function $code abs$$ is not defined for the AD type sequences 00070 above $code std::complex<float>$$ or $code std::complex<double>$$ 00071 because the complex $code abs$$ function is not complex differentiable 00072 (see $cref/complex types faq/Faq/Complex Types/$$). 00073 00074 $head Derivative$$ 00075 CppAD defines the derivative of the $code abs$$ function is 00076 the $cref sign$$ function; i.e., 00077 $latex \[ 00078 {\rm abs}^{(1)} ( x ) = {\rm sign} (x ) = 00079 \left\{ \begin{array}{rl} 00080 +1 & {\rm if} \; x > 0 \\ 00081 0 & {\rm if} \; x = 0 \\ 00082 -1 & {\rm if} \; x < 0 00083 \end{array} \right. 00084 \] $$ 00085 This used to be different; 00086 see $cref/old derivative/abs/Old Derivative/$$ below. 00087 00088 $head Example$$ 00089 $children% 00090 example/abs.cpp 00091 %$$ 00092 The file 00093 $cref abs.cpp$$ 00094 contains an example and test of this function. 00095 It returns true if it succeeds and false otherwise. 00096 00097 $head Old Derivative$$ 00098 The derivative of the absolute value function is one for 00099 $latex x > 0$$ and minus one for $latex x < 0$$. 00100 CppAD used to compute its directional derivative 00101 what $latex x = 0$$. 00102 $pre 00103 00104 $$ 00105 The function corresponding to the argument $icode x$$ 00106 and the result $icode y$$ are represented 00107 by their Taylor coefficients; i.e., 00108 $latex \[ 00109 \begin{array}{rcl} 00110 X(t) & = & x^{(0)} (t) + x^{(1)} t + \cdots + x^{(p)} t^p 00111 \\ 00112 Y(t) & = & y^{(0)} (t) + y^{(1)} t + \cdots + y^{(p)} t^p 00113 \end{array} 00114 \] $$ 00115 Note that $latex x^{(0)} = X(0)$$ is the value of $icode x$$ and 00116 $latex y^{(0)} = Y(0)$$ is the value of $icode y$$. 00117 In the equations above, the order $latex p$$ is specified 00118 by a call to $cref Forward$$ or $cref Reverse$$ as follows: 00119 $codei% 00120 %f%.Forward(%p%, %dx%) 00121 %f%.Reverse(%p%+1, %w%) 00122 %$$ 00123 If all of the Taylor coefficients of $latex X(t)$$ are zero, 00124 we define $latex k = p$$. 00125 Otherwise, we define $latex k$$ to be the minimal index such that 00126 $latex x^{(k)} \neq 0$$. 00127 Note that if $latex x \neq 0$$, $latex k = 0$$. 00128 The Taylor coefficient representation of $latex Y(t)$$ 00129 (and hence it's derivatives) are computed as 00130 $latex \[ 00131 y^{(\ell)} 00132 = 00133 \left\{ \begin{array}{ll} 00134 x^{(\ell)} & {\rm if} \; x^{(k)} > 0 \\ 00135 0 & {\rm if} \; x^{(k)} = 0 \\ 00136 - x^{(\ell)} & {\rm if} \; x^{(k)} < 0 00137 \end{array} \right. 00138 \] $$ 00139 00140 $end 00141 ------------------------------------------------------------------------------- 00142 */ 00143 00144 // BEGIN CppAD namespace 00145 namespace CppAD { 00146 00147 template <class Base> 00148 AD<Base> AD<Base>::Abs (void) const 00149 { 00150 AD<Base> result; 00151 result.value_ = abs(value_); 00152 CPPAD_ASSERT_UNKNOWN( Parameter(result) ); 00153 00154 if( Variable(*this) ) 00155 { // add this operation to the tape 00156 CPPAD_ASSERT_UNKNOWN( NumRes(AbsOp) == 1 ); 00157 CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 ); 00158 ADTape<Base> *tape = tape_this(); 00159 00160 // corresponding operand address 00161 tape->Rec_.PutArg(taddr_); 00162 // put operator in the tape 00163 result.taddr_ = tape->Rec_.PutOp(AbsOp); 00164 // make result a variable 00165 result.tape_id_ = tape->id_; 00166 } 00167 return result; 00168 } 00169 00170 template <class Base> 00171 inline AD<Base> abs(const AD<Base> &x) 00172 { return x.Abs(); } 00173 00174 template <class Base> 00175 inline AD<Base> abs(const VecAD_reference<Base> &x) 00176 { return abs( x.ADBase() ); } 00177 00178 } // END CppAD namespace 00179 00180 # endif