CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
near_equal.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_UTILITY_NEAR_EQUAL_HPP
2 # define CPPAD_UTILITY_NEAR_EQUAL_HPP
3 
4 /* --------------------------------------------------------------------------
5 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
6 
7 CppAD is distributed under multiple licenses. This distribution is under
8 the terms of the
9  Eclipse Public License Version 1.0.
10 
11 A copy of this license is included in the COPYING file of this distribution.
12 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
13 -------------------------------------------------------------------------- */
14 
15 /*
16 $begin NearEqual$$
17 $spell
18  cppad.hpp
19  sqrt
20  cout
21  endl
22  Microsoft
23  std
24  Cpp
25  namespace
26  const
27  bool
28 $$
29 
30 $section Determine if Two Values Are Nearly Equal$$
31 $mindex NearEqual near absolute difference relative$$
32 
33 
34 $head Syntax$$
35 
36 $codei%# include <cppad/utility/near_equal.hpp>
37 %$$
38 $icode%b% = NearEqual(%x%, %y%, %r%, %a%)%$$
39 
40 
41 $head Purpose$$
42 Returns true,
43 if $icode x$$ and $icode y$$ are nearly equal,
44 and false otherwise.
45 
46 $head x$$
47 The argument $icode x$$
48 has one of the following possible prototypes
49 $codei%
50  const %Type% &%x%,
51  const std::complex<%Type%> &%x%,
52 %$$
53 
54 $head y$$
55 The argument $icode y$$
56 has one of the following possible prototypes
57 $codei%
58  const %Type% &%y%,
59  const std::complex<%Type%> &%y%,
60 %$$
61 
62 $head r$$
63 The relative error criteria $icode r$$ has prototype
64 $codei%
65  const %Type% &%r%
66 %$$
67 It must be greater than or equal to zero.
68 The relative error condition is defined as:
69 $latex \[
70  | x - y | \leq r ( |x| + |y| )
71 \] $$
72 
73 $head a$$
74 The absolute error criteria $icode a$$ has prototype
75 $codei%
76  const %Type% &%a%
77 %$$
78 It must be greater than or equal to zero.
79 The absolute error condition is defined as:
80 $latex \[
81  | x - y | \leq a
82 \] $$
83 
84 $head b$$
85 The return value $icode b$$ has prototype
86 $codei%
87  bool %b%
88 %$$
89 If either $icode x$$ or $icode y$$ is infinite or not a number,
90 the return value is false.
91 Otherwise, if either the relative or absolute error
92 condition (defined above) is satisfied, the return value is true.
93 Otherwise, the return value is false.
94 
95 $head Type$$
96 The type $icode Type$$ must be a
97 $cref NumericType$$.
98 The routine $cref CheckNumericType$$ will generate
99 an error message if this is not the case.
100 In addition, the following operations must be defined objects
101 $icode a$$ and $icode b$$ of type $icode Type$$:
102 $table
103 $bold Operation$$ $cnext
104  $bold Description$$ $rnext
105 $icode%a% <= %b%$$ $cnext
106  less that or equal operator (returns a $code bool$$ object)
107 $tend
108 
109 $head Include Files$$
110 The file $code cppad/near_equal.hpp$$ is included by $code cppad/cppad.hpp$$
111 but it can also be included separately with out the rest of
112 the $code CppAD$$ routines.
113 
114 $head Example$$
115 $children%
116  example/utility/near_equal.cpp
117 %$$
118 The file $cref near_equal.cpp$$ contains an example
119 and test of $code NearEqual$$.
120 It return true if it succeeds and false otherwise.
121 
122 $head Exercise$$
123 Create and run a program that contains the following code:
124 $codep
125  using std::complex;
126  using std::cout;
127  using std::endl;
128 
129  complex<double> one(1., 0), i(0., 1);
130  complex<double> x = one / i;
131  complex<double> y = - i;
132  double r = 1e-12;
133  double a = 0;
134  bool ok = CppAD::NearEqual(x, y, r, a);
135  if( ok )
136  cout << "Ok" << endl;
137  else cout << "Error" << endl;
138 $$
139 
140 $end
141 
142 */
143 
144 # include <limits>
145 # include <complex>
146 # include <cppad/core/cppad_assert.hpp>
148 
149 namespace CppAD { // Begin CppAD namespace
150 
151 // determine if both x and y are finite values
152 template <class Type>
153 bool near_equal_isfinite(const Type &x , const Type &y)
154 { Type infinity = Type( std::numeric_limits<double>::infinity() );
155 
156  // handle bug where some compilers return true for nan == nan
157  bool xNan = x != x;
158  bool yNan = y != y;
159 
160  // infinite cases
161  bool xInf = (x == infinity || x == - infinity);
162  bool yInf = (x == infinity || x == - infinity);
163 
164  return ! (xNan | yNan | xInf | yInf);
165 }
166 
167 template <class Type>
168 bool NearEqual(const Type &x, const Type &y, const Type &r, const Type &a)
169 {
170  CheckNumericType<Type>();
171  Type zero(0);
172 
174  zero <= r,
175  "Error in NearEqual: relative error is less than zero"
176  );
178  zero <= a,
179  "Error in NearEqual: absolute error is less than zero"
180  );
181 
182  // check for special cases
183  if( ! CppAD::near_equal_isfinite(x, y) )
184  return false;
185 
186  Type ax = x;
187  if( ax <= zero )
188  ax = - ax;
189 
190  Type ay = y;
191  if( ay <= zero )
192  ay = - ay;
193 
194  Type ad = x - y;
195  if( ad <= zero )
196  ad = - ad;
197 
198  if( ad <= a )
199  return true;
200 
201  if( ad <= r * (ax + ay) )
202  return true;
203 
204  return false;
205 }
206 
207 template <class Type>
209  const std::complex<Type> &x ,
210  const std::complex<Type> &y ,
211  const Type &r ,
212  const Type & a )
213 {
214  CheckNumericType<Type>();
215 # ifndef NDEBUG
216  Type zero(0);
217 # endif
218 
220  zero <= r,
221  "Error in NearEqual: relative error is less than zero"
222  );
224  zero <= a,
225  "Error in NearEqual: absolute error is less than zero"
226  );
227 
228  // check for special cases
229  if( ! CppAD::near_equal_isfinite(x.real(), x.imag()) )
230  return false;
231  if( ! CppAD::near_equal_isfinite(y.real(), y.imag()) )
232  return false;
233 
234  std::complex<Type> d = x - y;
235 
236  Type ad = std::abs(d);
237  if( ad <= a )
238  return true;
239 
240  Type ax = std::abs(x);
241  Type ay = std::abs(y);
242  if( ad <= r * (ax + ay) )
243  return true;
244 
245  return false;
246 }
247 
248 template <class Type>
250  const std::complex<Type> &x ,
251  const Type &y ,
252  const Type &r ,
253  const Type & a )
254 {
255  return NearEqual(x, std::complex<Type>(y, Type(0)), r, a);
256 }
257 
258 template <class Type>
260  const Type &x ,
261  const std::complex<Type> &y ,
262  const Type &r ,
263  const Type & a )
264 {
265  return NearEqual(std::complex<Type>(x, Type(0)), y, r, a);
266 }
267 
268 } // END CppAD namespace
269 
270 # endif
#define CPPAD_ASSERT_KNOWN(exp, msg)
Check that exp is true, if not print msg and terminate execution.
Define the CppAD error checking macros (all of which begin with CPPAD_ASSERT_)
AD< Base > abs(const AD< Base > &x)
Definition: abs.hpp:105
bool near_equal_isfinite(const Type &x, const Type &y)
Definition: near_equal.hpp:153
bool NearEqual(const Type &x, const Type &y, const Type &r, const Type &a)
Definition: near_equal.hpp:168