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