CppAD: A C++ Algorithmic Differentiation Package
20130918
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_SIGN_INCLUDED 00003 # define CPPAD_SIGN_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 sign$$ 00019 $spell 00020 Dirac 00021 Vec 00022 std 00023 faq 00024 Taylor 00025 Cpp 00026 namespace 00027 const 00028 $$ 00029 00030 $index sign, AD$$ 00031 00032 $section Sign Function$$ 00033 00034 $head Syntax$$ 00035 $icode%y% = sign(%x%)%$$ 00036 00037 00038 $head Purpose$$ 00039 Evaluates the $code sign$$ function which is defined by 00040 $latex \[ 00041 {\rm sign} (x ) = 00042 \left\{ \begin{array}{rl} 00043 +1 & {\rm if} \; x > 0 \\ 00044 0 & {\rm if} \; x = 0 \\ 00045 -1 & {\rm if} \; x < 0 00046 \end{array} \right. 00047 \] $$ 00048 00049 00050 $head x$$ 00051 The argument $icode x$$ has one of the following prototypes 00052 $codei% 00053 const AD<%Base%> &%x% 00054 const VecAD<%Base%>::reference &%x% 00055 %$$ 00056 00057 $head y$$ 00058 The result $icode y$$ has prototype 00059 $codei% 00060 AD<%Base%> %y% 00061 %$$ 00062 00063 $head Operation Sequence$$ 00064 This is an AD of $icode Base$$ 00065 $cref/atomic operation/glossary/Operation/Atomic/$$ 00066 and hence is part of the current 00067 AD of $icode Base$$ 00068 $cref/operation sequence/glossary/Operation/Sequence/$$. 00069 00070 $head Complex Types$$ 00071 The $code sign$$ function is not defined for the AD type sequences 00072 above $code std::complex<float>$$ or $code std::complex<double>$$ 00073 because these are not $cref/ordered types/base_ordered/Ordered Type/$$. 00074 00075 $head Derivative$$ 00076 CppAD computes the derivative of the $code sign$$ function as zero for all 00077 argument values $icode x$$. 00078 The correct mathematical derivative is different and 00079 is given by 00080 $latex \[ 00081 {\rm sign}{(1)} (x) = 2 \delta (x) 00082 \] $$ 00083 where $latex \delta (x)$$ is the Dirac Delta function. 00084 00085 $head Example$$ 00086 $children% 00087 example/sign.cpp 00088 %$$ 00089 The file 00090 $cref sign.cpp$$ 00091 contains an example and test of this function. 00092 It returns true if it succeeds and false otherwise. 00093 00094 $end 00095 ------------------------------------------------------------------------------- 00096 */ 00097 00098 // BEGIN CppAD namespace 00099 namespace CppAD { 00100 00101 template <class Base> 00102 AD<Base> AD<Base>::Sign (void) const 00103 { 00104 AD<Base> result; 00105 result.value_ = sign(value_); 00106 CPPAD_ASSERT_UNKNOWN( Parameter(result) ); 00107 00108 if( Variable(*this) ) 00109 { // add this operation to the tape 00110 CPPAD_ASSERT_UNKNOWN( NumRes(SignOp) == 1 ); 00111 CPPAD_ASSERT_UNKNOWN( NumArg(SignOp) == 1 ); 00112 ADTape<Base> *tape = tape_this(); 00113 00114 // corresponding operand address 00115 tape->Rec_.PutArg(taddr_); 00116 // put operator in the tape 00117 result.taddr_ = tape->Rec_.PutOp(SignOp); 00118 // make result a variable 00119 result.tape_id_ = tape->id_; 00120 } 00121 return result; 00122 } 00123 00124 template <class Base> 00125 inline AD<Base> sign(const AD<Base> &x) 00126 { return x.Sign(); } 00127 00128 template <class Base> 00129 inline AD<Base> sign(const VecAD_reference<Base> &x) 00130 { return sign( x.ADBase() ); } 00131 00132 } // END CppAD namespace 00133 00134 # endif