Issues with close() and close_enough()

Posted by Simon Shakeshaft on
URL: http://quantlib.414.s1.nabble.com/Issues-with-close-and-close-enough-tp8064.html

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


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users

comparison.hpp.patch (1K) Download Attachment