1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2003, 2004, 2005, 2007 StatPro Italia srl
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
20/*! \file comparison.hpp
21 \brief floating-point comparisons
22*/
23
24#ifndef quantlib_comparison_hpp
25#define quantlib_comparison_hpp
26
27#include <ql/types.hpp>
28#include <ql/shared_ptr.hpp>
29
30namespace QuantLib {
31
32 /*! Follows somewhat the advice of Knuth on checking for floating-point
33 equality. The closeness relationship is:
34 \f[
35 \mathrm{close}(x,y,n) \equiv |x-y| \leq \varepsilon |x|
36 \wedge |x-y| \leq \varepsilon |y|
37 \f]
38 where \f$ \varepsilon \f$ is \f$ n \f$ times the machine accuracy;
39 \f$ n \f$ equals 42 if not given.
40 */
41 bool close(Real x, Real y);
42 bool close(Real x, Real y, Size n);
43
44 /*! Follows somewhat the advice of Knuth on checking for floating-point
45 equality. The closeness relationship is:
46 \f[
47 \mathrm{close}(x,y,n) \equiv |x-y| \leq \varepsilon |x|
48 \vee |x-y| \leq \varepsilon |y|
49 \f]
50 where \f$ \varepsilon \f$ is \f$ n \f$ times the machine accuracy;
51 \f$ n \f$ equals 42 if not given.
52 */
53 bool close_enough(Real x, Real y);
54 bool close_enough(Real x, Real y, Size n);
55
56
57 // inline definitions
58
59 inline bool close(Real x, Real y) {
60 // we're duplicating the code here instead of calling close(x,y,42)
61 // for optimization; this allows us to make tolerance constexpr
62 // and shave a few more cycles.
63
64 // Deals with +infinity and -infinity representations etc.
65 if (x == y)
66 return true;
67
68 Real diff = std::fabs(x: x-y);
69 constexpr double tolerance = 42 * QL_EPSILON;
70
71 if (x == 0.0 || y == 0.0)
72 return diff < (tolerance * tolerance);
73
74 return diff <= tolerance*std::fabs(x: x) &&
75 diff <= tolerance*std::fabs(x: y);
76 }
77
78 inline bool close(Real x, Real y, Size n) {
79 // Deals with +infinity and -infinity representations etc.
80 if (x == y)
81 return true;
82
83 Real diff = std::fabs(x: x-y), tolerance = n * QL_EPSILON;
84
85 if (x == 0.0 || y == 0.0)
86 return diff < (tolerance * tolerance);
87
88 return diff <= tolerance*std::fabs(x: x) &&
89 diff <= tolerance*std::fabs(x: y);
90 }
91
92 inline bool close_enough(Real x, Real y) {
93 // see close() for a note on duplication
94
95 // Deals with +infinity and -infinity representations etc.
96 if (x == y)
97 return true;
98
99 Real diff = std::fabs(x: x-y);
100 constexpr double tolerance = 42 * QL_EPSILON;
101
102 if (x == 0.0 || y == 0.0) // x or y = 0.0
103 return diff < (tolerance * tolerance);
104
105 return diff <= tolerance*std::fabs(x: x) ||
106 diff <= tolerance*std::fabs(x: y);
107 }
108
109 inline bool close_enough(Real x, Real y, Size n) {
110 // Deals with +infinity and -infinity representations etc.
111 if (x == y)
112 return true;
113
114 Real diff = std::fabs(x: x-y), tolerance = n * QL_EPSILON;
115
116 if (x == 0.0 || y == 0.0)
117 return diff < (tolerance * tolerance);
118
119 return diff <= tolerance*std::fabs(x: x) ||
120 diff <= tolerance*std::fabs(x: y);
121 }
122
123
124
125 //! compare two objects by date
126 /*! There is no generic implementation of this struct.
127 Template specializations will have to be defined for
128 each needed type (see CashFlow for an example.)
129 */
130 template <class T> struct earlier_than;
131
132 /* partial specialization for shared pointers, forwarding to their
133 pointees. */
134 template <class T>
135 struct earlier_than<ext::shared_ptr<T> > {
136 /*! \deprecated Use `auto` or `decltype` instead.
137 Deprecated in version 1.29.
138 */
139 QL_DEPRECATED
140 typedef ext::shared_ptr<T> first_argument_type;
141
142 /*! \deprecated Use `auto` or `decltype` instead.
143 Deprecated in version 1.29.
144 */
145 QL_DEPRECATED
146 typedef ext::shared_ptr<T> second_argument_type;
147
148 /*! \deprecated Use `auto` or `decltype` instead.
149 Deprecated in version 1.29.
150 */
151 QL_DEPRECATED
152 typedef bool result_type;
153
154 bool operator()(const ext::shared_ptr<T>& x,
155 const ext::shared_ptr<T>& y) const {
156 return earlier_than<T>()(*x,*y);
157 }
158 };
159
160}
161
162
163#endif
164

source code of quantlib/ql/math/comparison.hpp