On Thu, Jun 10, 2010 at 1:05 AM, Benoit Jacob <
jacob.benoit.1@xxxxxxxxx> wrote:
> 2010/6/9 Hauke Heibel <
hauke.heibel@xxxxxxxxxxxxxx>:
>> Maybe this simple hack is all we need:
>>
>> static inline bool isApprox(const Scalar& x, const Scalar& y, const
>> RealScalar& prec)
>> {
>> return (ei_abs(x - y) <= std::min(ei_abs(x), ei_abs(y)) * prec ||
>> ei_abs(x - y) < NumTraits<Scalar>::epsilon());
>> }
>
> No, that is not correct to do in such generality (at the level of
> isApprox), because it would imply that
>
> isApprox(1e-10, 1e-30) == true
>
> even though these values are very different (one is 1e+20 bigger than
> the other). Our FP fuzzy compares are completely 'relative', they do
> not declare any particular order of magnitude to be 'negligible'.
>
> But you are right: any comparison of the form
>
> VERIFY_IS_APPROX(something_near_zero, something_else_near_zero)
>
> is inherently bogus, since, as you noted, it fails when these values
> are actually exactly zero. The fix is going to look what you suggest
> above, except that it must be local to this unit-test and not
> generalized to isApprox(). In the particular context of the unit test,
> we have a good frame of reference to compare the difference with,
> namely, let's just compare it with 1. So, replace
>
> VERIFY_IS_APPROX(x, y)
>
> by
>
> VERIFY_IS_MUCH_SMALLER_THAN( x-y, 1)
>
> Cheers,
> Benoit
>
>>
>> - Hauke
>>
>> On Thu, Jun 10, 2010 at 12:43 AM, Hauke Heibel
>> <
hauke.heibel@xxxxxxxxxxxxxx> wrote:
>>> On MSVC the inverse unit test fails here:
>>>
>>> //Second: a rank one matrix (not invertible, except for 1x1 matrices)
>>> VectorType v3 = VectorType::Random(rows);
>>> MatrixType m3 = v3*v3.transpose(), m4(rows,cols);
>>> m3.computeInverseAndDetWithCheck(m4, det, invertible);
>>> VERIFY( rows==1 ? invertible : !invertible );
>>> VERIFY_IS_APPROX(det, m3.determinant());
>>> m3.computeInverseWithCheck(m4, invertible);
>>> VERIFY( rows==1 ? invertible : !invertible );
>>>
>>> We expect a determinant of 0 since the matrix is not invertible and
>>> then this check fails
>>>
>>> VERIFY_IS_APPROX(det, m3.determinant());
>>>
>>> VERIFY_IS_APPROX will always fail in case one of the two parameters is
>>> zero and in case both values are small it is likely to fail as well
>>> because
>>>
>>> abs(x-y) <= min(abs(x),abs(y)) * 1e-3
>>>
>>> here, we take the minimal value and make it even smaller.
>>>
>>> Here are some nice comparison methods we might try to adapt:
>>>
http://www.boost.org/doc/libs/1_32_0/boost/test/floating_point_comparison.hpp
>>>
>>> - Hauke
>>>
>>
>>
>>
>
>
>