Hi,
I believe there is an issue in the close() function in comparison.hpp
e.g. close(0.0, std::numeric_limits<double>::min(), 42) returns false.
The issue is here:
return diff <= tolerance*std::fabs(x) &&
diff <= tolerance*std::fabs(y);
if x (or y) is zero then this reduces to
return diff <= 0 &&
diff <= tolerance*std::fabs(y)
which is true iif y == 0 (tolerance > 0).
[yes, there are other issues when comparing small FP numbers as well…]
I've attached a suggested patch. The patch also checks for Null<Real> being passed and the function returns false in the case either, or both arguments are Null<Real>, although it’s possible that a throw may be better (see later useage.)
There is also a direct equality test to deal with +/-infinity FP representations.
A quick wildcard search through the project files shows:
Find all "close(*0*)", Wildcards, Subfolders, Find Results 1, "Current Project"
\QuantLib-1.2\ql\experimental\callablebonds\callablebond.cpp(126): bool isZeroCouponBond = (coupons.size() == 1 && close(coupons[0], 0.0));
\QuantLib-1.2\ql\math\solvers1d\bisection.hpp(65): if (std::fabs(dx) < xAccuracy || (close(fMid, 0.0)))
\QuantLib-1.2\ql\math\solvers1d\brent.hpp(74): if (std::fabs(xMid) <= xAcc1 || (close(froot, 0.0)))
\QuantLib-1.2\ql\math\solvers1d\falseposition.hpp(77): if (std::fabs(del) < xAccuracy || (close(froot, 0.0)))
\QuantLib-1.2\ql\math\solvers1d\ridder.hpp(63): if (close(s, 0.0))
\QuantLib-1.2\ql\math\solvers1d\ridder.hpp(75): if (close(froot, 0.0))
\QuantLib-1.2\ql\math\solvers1d\secant.hpp(69): if (std::fabs(dx) < xAccuracy || (close(froot, 0.0)))
\QuantLib-1.2\ql\math\solver1d.hpp(102): if (close(fxMax_,0.0))
\QuantLib-1.2\ql\math\solver1d.hpp(104): else if (close(fxMax_, 0.0)) {
\QuantLib-1.2\ql\math\solver1d.hpp(118): if (close(fxMin_, 0.0))
\QuantLib-1.2\ql\math\solver1d.hpp(120): if (close(fxMax_, 0.0))
\QuantLib-1.2\ql\math\solver1d.hpp(189): if (close(fxMin_, 0.0))
\QuantLib-1.2\ql\math\solver1d.hpp(193): if (close(fxMax_, 0.0))
\QuantLib-1.2\ql\methods\finitedifferences\tridiagonaloperator.cpp(101): QL_REQUIRE(!close(bet, 0.0),
\QuantLib-1.2\ql\methods\finitedifferences\tridiagonaloperator.cpp(108): QL_ENSURE(!close(bet, 0.0), "division by zero");
\QuantLib-1.2\ql\models\marketmodels\correlations\expcorrelations.cpp(97): if (close(gamma,1.0)) {
\QuantLib-1.2\ql\pricingengines\blackcalculator.cpp(80): if (close(strike_, 0.0)) {
\QuantLib-1.2\ql\pricingengines\blackcalculator.cpp(297): if (close(maturity, 0.0)) return 0.0;
Matching lines: 18 Matching files: 10 Total files searched: 1799
and also
Find all "close(*null*)", Wildcards, Subfolders, Find Results 1, "Current Project"
C:\SharedLibs\QuantLib-1.2\ql\index.hpp(99): missingFixing= forceOverwrite || close(currentValue,nullValue);
[nullValue = Null<Real>();]
Matching lines: 1 Matching files: 1 Total files searched: 1799
The last one can probably be corrected as missingFixing= forceOverwrite || (currentValue==Null<Real>()); [and remove the declaration of nullValue.]
Best Regards,
Simon
| Free forum by Nabble | Edit this page |