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:gil...@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-unsubscr...@commons.apache.org > For additional commands, e-mail: dev-h...@commons.apache.org > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > For additional commands, e-mail: dev-h...@commons.apache.org > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org