commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gilles Sadowski <gil...@harfang.homelinux.org>
Subject Re: [math] Adding some methods in Precision class (oacm.util)
Date Wed, 19 Sep 2012 17:07:17 GMT
Hello.

> Thanks for your answers. 
> As I said, our solution first uses equals() method, to distinguish wether number are
"strictly" equals (thanks to existing methods) before dividing the difference by the max value
of (x,y).
> 
> So I tested the use case proposed by Luc with our implementation and with Luc's one (see
here after). 
> 
> About the default value (1e-14), I know the tolerance is case-dependant, but some times,
we don't precisely know the order of magnitude (ex : jacobians matrices) and it's quite practical
to have a default value. 
> In our tools, we use this value in the test classes, but also for specific algorithm
convergence threshold.

Yes but the value is a simply a choice, and one that is not driven by
anything related to the implementation. Hence I think that it is more
dangerous than useful to include that "magic" number in CM.
It's safer that users are forced to figure out what would be a good value
for their case.

> 
> If you agree, I'll open a ticket and attach our patch.

Filing a report on JIRA is useful to keep a history but a new patch is not
necessary, as I've already included the code in my working copy (with some
minor changes).
[I'll wait for the report so that the commit can be linked to the issue
number.]


Thanks,
Gilles

> 
> Best regards,
> 
> Yannick
> 
> --
> Here are the results obtained with various methods : CommonsMath equals (one ulp), our
method with a relative 1e-14 threshold, and another method (abs(x1-x2) <= eps * max(abs(x1),abs(x2)
)
> 
> 
> -------------------
> X: 0.0 vs Y: -0.0
> Equals (CM) 		true
> EqualsWithRelativeTol 	true
> EqualsOtherSolution	 false
> -------------------
> X: 0.1 vs Y: 0.1000000000001
> Equals (CM) 		false
> EqualsWithRelativeTol 	false
> EqualsOtherSolution	 false
> -------------------
> X: 1.7976931348623157E308 vs Y: 1.7976931348623157E308
> Equals (CM) 		true
> EqualsWithRelativeTol 	true
> EqualsOtherSolution	 true
> -------------------
> X: 4.9E-324 vs Y: 4.9E-324
> Equals (CM) 		true
> EqualsWithRelativeTol 	true
> EqualsOtherSolution	 false
> -------------------
> X: Infinity vs Y: Infinity
> Equals (CM) 		true
> EqualsWithRelativeTol 	true
> EqualsOtherSolution	 false
> -------------------
> X: NaN vs Y: NaN
> Equals (CM) 		false
> EqualsWithRelativeTol 	false
> EqualsOtherSolution	 false
> -------------------
> X: 0.0 vs Y: 0.0
> Equals (CM) 		true
> EqualsWithRelativeTol 	true
> EqualsOtherSolution	 false
> -------------------
> X: -Infinity vs Y: -Infinity
> Equals (CM) 		true
> EqualsWithRelativeTol 	true
> EqualsOtherSolution	 false
> -------------------
> X: 0.100000000000001 vs Y: 0.1
> Equals (CM) 		false
> EqualsWithRelativeTol 	true
> EqualsOtherSolution	 true
> -------------------
> X: 0.1000000000000011 vs Y: 0.1
> Equals (CM) 		false
> EqualsWithRelativeTol 	false
> EqualsOtherSolution	 false
> 
> 
> 
> -----Message d'origine-----
> De : Gilles Sadowski [mailto:gilles@harfang.homelinux.org] 
> Envoyé : mercredi 19 septembre 2012 16:38
> À : dev@commons.apache.org
> Objet : Re: [math] Adding some methods in Precision class (oacm.util)
> 
> Hi.
> 
> > 
> > > 
> > > This message is about some methods in Precision class, and follows a
> > > discussion about MATH-863
> > > (https://issues.apache.org/jira/browse/MATH-863).
> > > 
> > > Recently, we slightly modified our Precision class, by adding a
> > > specific epsilon value to compute a relative deviation and also some
> > > methods. --- /** Epsilon used for doubles relative comparison */ 
> > > public static final double DOUBLE_COMPARISON_EPSILON = 1.0e-14; ---
> > > 
> > > This value is quite useful to compare two values. It's
> > > approximatively 100 times larger than the previous EPSILON value
> > > (1e-16, the difference between 1. and the next closest value).
> > > 
> > > We also added static methods, to compute a relative difference : if
> > > x1 and x2 are not equal (according to the equals(x1,x2, "1 ulp")
> > > function), then we compute a relative deviation
> > > ("abs(x1-x2)/max(abs(x1),abs(x2))" and see if it's lower than an
> > > epsilon value.
> > 
> > The comparison should probably rather be:
> >   abs(x1-x2) <= eps * max(abs(x1),abs(x2)
> > 
> > The reason for that is that with your implementation when both x1 and x2
> > are 0 (either +0 or -0), then the result would be false, despite the
> > numbers are equal. The division 0/0 leads to a NaN and all comparisons
> > involving NaN return false.
> 
> Unfotunately, that version makes the comparison fail when one of the
> argument is infinite; in that case we get for the proposed code
>   inf / inf < eps  --> false thanks to NaN
> while the above leads to
>   inf <= inf       --> true
> 
> Also, the proposed implementation first checks for strict equality: when the
> arguments are equal, the division is not performed.
> 
> [I wanted to replace the proposed implementation with a call to the existing
> "absolute" comparison method, but because of that problem, it doesn't seem
> possible without adding conditionals.]
> 
> > > 
> > > --- public static boolean equalsWithRelativeTolerance(final double x,
> > > final double y) -> uses the DOUBLE_COMPARISON_EPSILON public static
> > > boolean equalsWithRelativeTolerance(final double x, final double y,
> > > final double eps) ---
> > > 
> > > These kind of methods are used in some of our tools (space dynamic
> > > libraries) to assert equality between values, when we don't know the
> > > order of magnitude.
> > > 
> > > Do you think it's useful for Commons Math users ? Shall I open a
> > > ticket on JIRA and contribute the corresponding code source ?
> > 
> > Yes, along with test cases, including special cases (+/-0, +/-infinity,
> > NaNs, +/-Double.MAX_VALUE, +/-Double.MIN_VALUE ...)
> 
> 
> I think that we should focus on the second version (with an explicit
> tolerance).
> The tolerance is very much case-dependent, so that the default value is not
> widely useful: Why 1e-14 rather than 1e-15 or 1e-13 or even 1e-7 ?
> 
> 
> Best regards,
> Gilles
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Mime
View raw message