/home/coin/SVN-release/CoinAll-1.1.0/cppad/cppad/near_equal.hpp

Go to the documentation of this file.
00001 # ifndef CPPAD_NEAR_EQUAL_INCLUDED
00002 # define CPPAD_NEAR_EQUAL_INCLUDED
00003 
00004 /* --------------------------------------------------------------------------
00005 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-06 Bradley M. Bell
00006 
00007 CppAD is distributed under multiple licenses. This distribution is under
00008 the terms of the 
00009                     Common Public License Version 1.0.
00010 
00011 A copy of this license is included in the COPYING file of this distribution.
00012 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
00013 -------------------------------------------------------------------------- */
00014 
00015 /*
00016 $begin NearEqual$$
00017 $spell
00018         cppad.hpp
00019         sqrt
00020         cout
00021         endl
00022         Microsoft
00023         std
00024         Cpp
00025         namespace
00026         const
00027         bool
00028 $$
00029 
00030 $section Determine if Two Values Are Nearly Equal$$
00031 
00032 $index NearEqual$$
00033 $index equal, near$$
00034 $index absolute, difference$$
00035 $index relative, difference$$
00036 $index difference, absolute$$
00037 $index difference, relative$$
00038 
00039 $head Syntax$$
00040 
00041 $code # include <cppad/near_equal.hpp>$$
00042 $pre
00043 $$
00044 $syntax%%b% = NearEqual(%x%, %y%, %r%, %a%)%$$
00045 
00046 
00047 $head Purpose$$
00048 Returns true,
00049 if $italic x$$ and $italic y$$ are nearly equal,
00050 and false otherwise.
00051 
00052 $head x$$
00053 The argument $italic x$$ 
00054 has one of the following possible prototypes
00055 $syntax%
00056         const %Type%               &%x%,
00057         const std::complex<%Type%> &%x%, 
00058 %$$
00059 
00060 $head y$$
00061 The argument $italic y$$ 
00062 has one of the following possible prototypes
00063 $syntax%
00064         const %Type%               &%y%,
00065         const std::complex<%Type%> &%y%, 
00066 %$$
00067 
00068 $head r$$
00069 The relative error criteria $italic r$$ has prototype
00070 $syntax%
00071         const %Type% &%r%
00072 %$$
00073 It must be greater than or equal to zero.
00074 The relative error condition is defined as:
00075 $latex \[
00076         | x - y | \leq r ( |x| + |y| ) 
00077 \] $$
00078 
00079 $head a$$
00080 The absolute error criteria $italic a$$ has prototype
00081 $syntax%
00082         const %Type% &%a%
00083 %$$
00084 It must be greater than or equal to zero.
00085 The absolute error condition is defined as:
00086 $latex \[
00087         | x - y | \leq a
00088 \] $$
00089 
00090 $head b$$
00091 The return value $italic b$$ has prototype
00092 $syntax%
00093         bool %b%
00094 %$$
00095 If either $italic x$$ or $italic y$$ is infinite or not a number, 
00096 the return value is false.
00097 Otherwise, if either the relative or absolute error 
00098 condition (defined above) is satisfied, the return value is true.
00099 Otherwise, the return value is false.
00100 
00101 $head Type$$
00102 The type $italic Type$$ must be a
00103 $xref/NumericType/$$.
00104 The routine $xref/CheckNumericType/$$ will generate
00105 an error message if this is not the case.
00106 In addition, the following operations must be defined objects
00107 $italic a$$ and $italic b$$ of type $italic Type$$:
00108 $table
00109 $bold Operation$$     $cnext 
00110         $bold Description$$ $rnext
00111 $syntax%%a% <= %b%$$  $cnext 
00112         less that or equal operator (returns a $code bool$$ object)
00113 $tend
00114 
00115 $head Include Files$$
00116 The file $code cppad/near_equal.hpp$$ is included by $code cppad/cppad.hpp$$
00117 but it can also be included separately with out the rest of 
00118 the $code CppAD$$ routines.
00119 
00120 $head Example$$
00121 $children%
00122         example/near_equal.cpp
00123 %$$
00124 The file $xref/Near_Equal.cpp/$$ contains an example
00125 and test of $code NearEqual$$.
00126 It return true if it succeeds and false otherwise.
00127 
00128 $head Exercise$$
00129 $index exercise, NearEqual$$
00130 Create and run a program that contains the following code:
00131 $codep
00132         using std::complex;
00133         using std::cout;
00134         using std::endl;
00135 
00136         complex<double> one(1., 0), i(0., 1);
00137         complex<double> x = one / i;
00138         complex<double> y = - i;
00139         double          r = 1e-12;
00140         double          a = 0;
00141         bool           ok = CppAD::NearEqual(x, y, r, a);
00142         if( ok )
00143                 cout << "Ok"    << endl;
00144         else    cout << "Error" << endl;
00145 $$
00146 
00147 $end
00148 
00149 */
00150 
00151 # include <complex>
00152 # include <cppad/local/cppad_assert.hpp>
00153 # include <cppad/check_numeric_type.hpp>
00154 
00155 namespace CppAD { // Begin CppAD namespace
00156 
00157 // determine if both x and y are finite values (z1 and z2 are zero).
00158 template <class Type>
00159 bool isfinite(const Type &z1, const Type &z2, const Type &x , const Type &y)
00160 {       Type infinity = Type(1) / z1;
00161         Type nan      = z1      / z2;
00162 
00163         // handle bug where some compilers return true for nan == nan
00164         bool xNan = ( x != x || x == nan );
00165         bool yNan = ( y != y || y == nan );
00166 
00167         // infinite cases
00168         bool xInf = (x == infinity   || x == - infinity);
00169         bool yInf = (x == infinity   || x == - infinity);
00170         
00171         return ! (xNan | yNan | xInf | yInf);
00172 }
00173 
00174 template <class Type>
00175 bool NearEqual(const Type &x, const Type &y, const Type &r, const Type &a)
00176 {
00177         CheckNumericType<Type>();
00178         Type zero(0);
00179 
00180         CPPAD_ASSERT_KNOWN(
00181                 zero <= r,
00182                 "Error in NearEqual: relative error is less than zero"
00183         );
00184         CPPAD_ASSERT_KNOWN(
00185                 zero <= a,
00186                 "Error in NearEqual: absolute error is less than zero"
00187         );
00188 
00189         // check for special cases
00190         if( ! isfinite(zero, zero, x, y) )
00191                 return false;
00192 
00193         Type ax = x;
00194         if( ax <= zero )
00195                 ax = - ax;
00196 
00197         Type ay = y;
00198         if( ay <= zero )
00199                 ay = - ay;
00200 
00201         Type ad = x - y;
00202         if( ad <= zero )
00203                 ad = - ad;
00204 
00205         if( ad <= a )
00206                 return true;
00207 
00208         if( ad <= r * (ax + ay) )
00209                 return true;
00210 
00211         return false;
00212 }
00213 
00214 template <class Type>
00215 bool NearEqual(
00216         const std::complex<Type> &x , 
00217         const std::complex<Type> &y , 
00218         const              Type  &r , 
00219         const              Type  & a )
00220 {
00221         CheckNumericType<Type>();
00222         Type zero(0);
00223 
00224         CPPAD_ASSERT_KNOWN(
00225                 zero <= r,
00226                 "Error in NearEqual: relative error is less than zero"
00227         );
00228         CPPAD_ASSERT_KNOWN(
00229                 zero <= a,
00230                 "Error in NearEqual: absolute error is less than zero"
00231         );
00232 
00233         // check for special cases
00234         if( ! isfinite(zero, zero, x.real(), x.imag()) )
00235                 return false;
00236         if( ! isfinite(zero, zero, y.real(), y.imag()) )
00237                 return false;
00238 
00239         std::complex<Type> d = x - y;
00240 
00241         Type ad = std::abs(d);
00242         if( ad <= a )
00243                 return true;
00244 
00245         Type ax = std::abs(x);
00246         Type ay = std::abs(y);
00247         if( ad <= r * (ax + ay) )
00248                 return true;
00249 
00250         return false;
00251 }
00252 
00253 template <class Type>
00254 bool NearEqual(
00255         const std::complex<Type> &x , 
00256         const              Type  &y , 
00257         const              Type  &r , 
00258         const              Type  & a )
00259 {
00260         return NearEqual(x, std::complex<Type>(y, Type(0)), r, a);
00261 }
00262 
00263 template <class Type>
00264 bool NearEqual(
00265         const              Type  &x , 
00266         const std::complex<Type> &y , 
00267         const              Type  &r , 
00268         const              Type  & a )
00269 {
00270         return NearEqual(std::complex<Type>(x, Type(0)), y, r, a);
00271 }
00272 
00273 } // END CppAD namespace
00274 
00275 # endif

Generated on Sun Nov 14 14:06:33 2010 for Coin-All by  doxygen 1.4.7