Re: [eigen] inverse unit test

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


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
>>
>
>
>



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/