COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
utest-math-checks.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010-2013 von Karman Institute for Fluid Dynamics, Belgium
2 //
3 // This software is distributed under the terms of the
4 // GNU Lesser General Public License version 3 (LGPLv3).
5 // See doc/lgpl.txt and doc/gpl.txt for the license text.
6 
7 #define BOOST_TEST_DYN_LINK
8 #define BOOST_TEST_MODULE
9 
10 #include <iomanip>
11 #include <boost/test/unit_test.hpp>
12 
13 #include "common/Log.hpp"
14 
15 #include "math/Checks.hpp"
16 
17 using namespace std;
18 using namespace boost;
19 
20 using namespace cf3;
21 using namespace cf3::common;
22 using namespace cf3::math;
23 
24 typedef long int lint;
25 
26 // This function is similar to what is implemented in FloatingPoint class
27 // It is based on the original article "Comparison of Floating Point Numbers" by Bruce Dawson
28 // It was adapted to use double precision (a limitation that FloatingPointer does not have)
29 bool AlmostEqual2sComplement(double A, double B, boost::uint64_t maxUlps)
30 {
31  // Make sure maxUlps is non-negative and small enough that the
32  // default NAN won't compare as equal to anything.
33  // assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024);
34 
35  lint aInt = *(lint*)&A;
36  // Make aInt lexicographically ordered as a twos-complement int
37  if (aInt < 0)
38  aInt = 0x80000000 - aInt;
39  // Make bInt lexicographically ordered as a twos-complement int
40  lint bInt = *(lint*)&B;
41  if (bInt < 0)
42  bInt = 0x80000000 - bInt;
43  lint intDiff = (aInt >= bInt) ? (aInt - bInt) : (bInt - aInt);
44 
45 // std::cout << "diff [" << intDiff << "]" << std::endl;
46 
47  if (intDiff <= maxUlps)
48  return true;
49  return false;
50 }
51 
52 
53 BOOST_AUTO_TEST_SUITE( math_checks_test_suite )
54 
55 #define ULP 4
56 
57 // when a real is around 1. then Consts::eps() is
58 // equivalent to the jump to the nearest representable real
59 
60 BOOST_AUTO_TEST_CASE( floating_point_far_from_zero )
61 {
62  std::cout.setf(ios::scientific,ios::floatfield);
63  std::cout.precision(24);
64 
65  const Real a = 1.;
66  const Real b = a + Consts::eps();
67 
68  std::cout << "a [" << a << "] & [" << *(boost::uint64_t*)&a << "]" << std::endl;
69  std::cout << "b [" << b << "] & [" << *(boost::uint64_t*)&b << "]" << std::endl;
70 
71  std::cout << "diff [" << FloatingPoint<Real>(a).diff( FloatingPoint<Real>(b) ) << "]" << std::endl;
72 
74  std::cout << "FP says a and b are equals" << std::endl;
75  else
76  std::cout << "FP says a and b are different" << std::endl;
77 
78  if( AlmostEqual2sComplement(a,b, ULP) )
79  std::cout << "C2 says a and b are equals" << std::endl;
80  else
81  std::cout << "C2 says a and b are different" << std::endl;
82 
83 // BOOST_CHECK_CLOSE( a, b, 0.000001); // in percentage %
84 
85  std::cout << "-----------------------------------" << std::endl;
86 
87 }
88 
89 BOOST_AUTO_TEST_CASE( floating_point_far_from_zero_2 )
90 {
91  std::cout.setf(ios::scientific,ios::floatfield);
92  std::cout.precision(24);
93 
94  const Real a = 10E10;
95  const lint ai = *(lint*)&a;
96 
97  const lint bi = ai+1;
98  const Real b = *(Real*)&bi;
99 
100  std::cout << "a [" << a << "] & [" << *(boost::uint64_t*)&a << "]" << std::endl;
101  std::cout << "b [" << b << "] & [" << *(boost::uint64_t*)&b << "]" << std::endl;
102 
103  std::cout << "diff [" << FloatingPoint<Real>(a).diff( FloatingPoint<Real>(b) ) << "]" << std::endl;
104 
106  std::cout << "FP says a and b are equals" << std::endl;
107  else
108  std::cout << "FP says a and b are different" << std::endl;
109 
110  if( AlmostEqual2sComplement(a,b, ULP) )
111  std::cout << "C2 says a and b are equals" << std::endl;
112  else
113  std::cout << "C2 says a and b are different" << std::endl;
114 
115 // BOOST_CHECK_CLOSE( a, b, 0.000001); // in percentage %
116 
117  std::cout << "-----------------------------------" << std::endl;
118 
119 }
120 
121 BOOST_AUTO_TEST_CASE( floating_point_near_zero )
122 {
123  std::cout.setf(ios::scientific,ios::floatfield);
124  std::cout.precision(24);
125 
126  const Real a = 0.0;
127  const lint ai = *(lint*)&a;
128 
129  const lint bi = ai+1;
130 // const Real b = *(Real*)&bi;
131 
132 // const Real b = Consts::real_min(); // 2.2..E-308
133 // const Real b = Consts::eps(); // 2.2..E-16
134  const Real b = Consts::eps() * Consts::real_min(); // 2.2..E-16 * 2.2..E-308
135 
136  std::cout << "a [" << a << "] & [" << *(boost::uint64_t*)&a << "]" << std::endl;
137  std::cout << "b [" << b << "] & [" << *(boost::uint64_t*)&b << "]" << std::endl;
138 
139  std::cout << "diff [" << FloatingPoint<Real>(a).diff( FloatingPoint<Real>(b) ) << "]" << std::endl;
140 
142  std::cout << "FP says a and b are equals" << std::endl;
143  else
144  std::cout << "FP says a and b are different" << std::endl;
145 
146  if( AlmostEqual2sComplement(a,b, ULP) )
147  std::cout << "C2 says a and b are equals" << std::endl;
148  else
149  std::cout << "C2 says a and b are different" << std::endl;
150 
151 // BOOST_CHECK_CLOSE( a, b, 0.000001); // in percentage %
152 
153  std::cout << "-----------------------------------" << std::endl;
154 
155 }
156 
158 
159 BOOST_AUTO_TEST_SUITE_END()
#define ULP
external boost library namespace
Basic Classes for Mathematical applications used by COOLFluiD.
STL namespace.
bool almost_equals(const FloatingPoint &rhs, const size_t ulps) const
bool diff(const mesh::Mesh &a, const mesh::Mesh &b, const Uint max_ulps)
Calculates the difference between two meshes.
Definition: MeshDiff.cpp:128
long int lint
unsigned __int64 uint64_t
Definition: stdint.h:90
Top-level namespace for coolfluid.
Definition: Action.cpp:18
BOOST_AUTO_TEST_CASE(floating_point_far_from_zero)
Real real_min()
Definition of the minimum number representable with the chosen precision.
Definition: Consts.hpp:38
Most basic kernel library.
Definition: Action.cpp:19
bool AlmostEqual2sComplement(double A, double B, boost::uint64_t maxUlps)
Send comments to:
COOLFluiD Web Admin