CppAD: A C++ Algorithmic Differentiation Package
20130102
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_NAN_INCLUDED 00003 # define CPPAD_NAN_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 $begin nan$$ 00017 $spell 00018 hasnan 00019 cppad 00020 hpp 00021 CppAD 00022 isnan 00023 bool 00024 const 00025 $$ 00026 00027 $section Obtain Nan or Determine if a Value is Nan$$ 00028 00029 $index isnan$$ 00030 $index hasnan$$ 00031 $index nan$$ 00032 00033 $head Syntax$$ 00034 $codei%# include <cppad/nan.hpp> 00035 %$$ 00036 $icode%s% = nan(%z%) 00037 %$$ 00038 $icode%b% = isnan(%s%) 00039 %$$ 00040 $icode%b% = hasnan(%v%)%$$ 00041 00042 $head Purpose$$ 00043 It obtain and check for the value not a number $code nan$$. 00044 The IEEE standard specifies that a floating point value $icode a$$ 00045 is $code nan$$ if and only if the following returns true 00046 $codei% 00047 %a% != %a% 00048 %$$ 00049 Some systems do not get this correct, so we also use the fact that 00050 zero divided by zero should result in a $code nan$$. 00051 To be specific, if a value is not equal to itself or 00052 if it is equal to zero divided by zero, it is considered to be a $code nan$$. 00053 00054 $head Include$$ 00055 The file $code cppad/nan.hpp$$ is included by $code cppad/cppad.hpp$$ 00056 but it can also be included separately with out the rest of 00057 the $code CppAD$$ routines. 00058 00059 $subhead Macros$$ 00060 $index macro, nan$$ 00061 $index macro, isnan$$ 00062 $index nan, macro$$ 00063 $index isnan, macro$$ 00064 Some C++ compilers use preprocessor symbols called $code nan$$ 00065 and $code isnan$$. 00066 These preprocessor symbols will no longer be defined after 00067 this file is included. 00068 00069 $head nan$$ 00070 This routine returns a $code nan$$ with the same type as $icode z$$. 00071 00072 $subhead z$$ 00073 The argument $icode z$$ has prototype 00074 $codei% 00075 const %Scalar% &%z% 00076 %$$ 00077 and its value is zero 00078 (see $cref/Scalar/nan/Scalar/$$ for the definition of $icode Scalar$$). 00079 00080 $subhead s$$ 00081 The return value $icode s$$ has prototype 00082 $codei% 00083 %Scalar% %s% 00084 %$$ 00085 It is the value $code nan$$ for this floating point type. 00086 00087 $head isnan$$ 00088 This routine determines if a scalar value is $code nan$$. 00089 00090 $subhead s$$ 00091 The argument $icode s$$ has prototype 00092 $codei% 00093 const %Scalar% %s% 00094 %$$ 00095 00096 $subhead b$$ 00097 The return value $icode b$$ has prototype 00098 $codei% 00099 bool %b% 00100 %$$ 00101 It is true if the value $icode s$$ is $code nan$$. 00102 00103 $head hasnan$$ 00104 This routine determines if a 00105 $cref SimpleVector$$ has an element that is $code nan$$. 00106 00107 $subhead v$$ 00108 The argument $icode v$$ has prototype 00109 $codei% 00110 const %Vector% &%v% 00111 %$$ 00112 (see $cref/Vector/nan/Vector/$$ for the definition of $icode Vector$$). 00113 00114 $subhead b$$ 00115 The return value $icode b$$ has prototype 00116 $codei% 00117 bool %b% 00118 %$$ 00119 It is true if the vector $icode v$$ has a $code nan$$. 00120 00121 $head Scalar$$ 00122 The type $icode Scalar$$ must support the following operations; 00123 $table 00124 $bold Operation$$ $cnext $bold Description$$ $rnext 00125 $icode%a% / %b%$$ $cnext 00126 division operator (returns a $icode Scalar$$ object) 00127 $rnext 00128 $icode%a% == %b%$$ $cnext 00129 equality operator (returns a $code bool$$ object) 00130 $rnext 00131 $icode%a% != %b%$$ $cnext 00132 not equality operator (returns a $code bool$$ object) 00133 $tend 00134 Note that the division operator will be used with $icode a$$ and $icode b$$ 00135 equal to zero. For some types (e.g. $code int$$) this may generate 00136 an exception. No attempt is made to catch any such exception. 00137 00138 $head Vector$$ 00139 The type $icode Vector$$ must be a $cref SimpleVector$$ class with 00140 elements of type $icode Scalar$$. 00141 00142 $head Parallel Mode$$ 00143 $index parallel, user_atomic$$ 00144 $index user_atomic, parallel$$ 00145 The function $code isnan$$ uses static variables. 00146 Hence for each type $icode Scalar$$, 00147 the first call to 00148 $codei% 00149 %b% = isnan(%s%) 00150 %$$ 00151 must not be $cref/parallel/ta_in_parallel/$$ execution mode; 00152 see $code isnan$$ in $cref/parallel_ad/parallel_ad/isnan/$$. 00153 00154 $head Memory Allocation$$ 00155 This function is called by CppAD even if it is not 00156 explicitly referenced by the users code. 00157 Hence any corresponding memory allocation for a static value 00158 of type $icode Scalar$$ my be preformed. 00159 00160 $children% 00161 example/nan.cpp 00162 %$$ 00163 $head Example$$ 00164 The file $cref nan.cpp$$ 00165 contains an example and test of this routine. 00166 It returns true if it succeeds and false otherwise. 00167 00168 $end 00169 */ 00170 00171 # include <cstddef> 00172 # include <cppad/local/cppad_assert.hpp> 00173 00174 // needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL 00175 # include <cppad/thread_alloc.hpp> 00176 00177 # ifdef nan 00178 # undef nan 00179 # endif 00180 # ifdef isnan 00181 # undef isnan 00182 # endif 00183 00184 namespace CppAD { // BEGIN CppAD namespace 00185 00186 template <class Scalar> 00187 inline Scalar nan(const Scalar &zero) 00188 { return zero / zero; 00189 } 00190 00191 template <class Scalar> 00192 inline bool isnan(const Scalar &s) 00193 { CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; 00194 static Scalar scalar_nan = nan( Scalar(0) ); 00195 return (s != s) | (s == scalar_nan); 00196 } 00197 00198 template <class Vector> 00199 bool hasnan(const Vector &v) 00200 { 00201 typedef typename Vector::value_type Scalar; 00202 00203 bool found_nan; 00204 size_t i; 00205 i = v.size(); 00206 found_nan = false; 00207 while(i--) 00208 found_nan |= isnan(v[i]); 00209 return found_nan; 00210 } 00211 00212 } // End CppAD namespace 00213 00214 # endif