Sure, I agree, the EPSILON was there for an example, so where the rest of
the macros.
I dont want to introduce a macro with a hard limit into a library, Im just
pointing out that when is an exact float test really appropriate?

An example:

   osg::Matrix m1, m2;

   m1.makeRotate(osg::PI_2, osg::Vec3(1,0,0), osg::PI_2, osg::Vec3(0,0,1),
osg::PI_2, osg::Vec3(0,1,0));
   m2 = m1;
   m1.invert(m1);

   std::cerr << m1*m2 << std::endl;
   std::cerr << "Matrix I: " << (I.isIdentity() ? 1 : 0) << std::endl;


{
       1 -4.44089e-016 4.71028e-016 0
       -4.44089e-016 1 -4.71028e-016 0
       -4.71028e-016 4.71028e-016 1 0
       0 0 0 1
}

Matrix I: 0


Now, for most cases I would call I an Identity matrix, and I think even Dr.
Goldbergs would agree?
But for the reasons of limited resolution, it is not, when considering the
equality test.

For example, if I for some reason I would calculate a color for two
materials, and color1 ends up being within 1e-16 close to color2 and

So this would be the effect: color1-color2 = vec4(1e-12,1e-12,1e-12,1e-12);


If I then use color1 and color2 in two separate Materials, lets say for
Diffuse color.

During a test of equality (StateSorting), these two colors are considered
different and are therefore not merged. But for most applications they ARE
equal, which in this case would mean
that the State sorter failed to recognize that.

Couldn't that cause a problem?
My point is, for most scientific applications (read simulators dynamic
systems)

float a,b;

if (a==b)

is considered to be somewhat banned.
Im not saying its wrong, it all depends on what you want to test. But from
browsing the net on the topic, and from personal experience the use of
"exact equality tests" for floats is not recommended.

A compressed version of Goldbergs article (with a reference to it):
http://www.boyet.com/Articles/FloatingPointEquality.html

Cheerio

Anders


On 2/26/07, Mathias Froehlich <[EMAIL PROTECTED]> wrote:


Hi,

On Monday 26 February 2007 09:23, Anders Backman wrote:
> I just got stuck on something I been worried about for quite some time
> regarding the Math library in osg:
>
>         bool Matrix::isIdentity() const
>         {
>             return _mat[0][0]==1.0f && _mat[0][1]==0.0f &&
> _mat[0][2]==0.0f&&  _mat[0][3]==
> 0.0f &&
>                    _mat[1][0]==0.0f && _mat[1][1]==1.0f &&
> _mat[1][2]==0.0f&&  _mat[1][3]==
> 0.0f &&
>                    _mat[2][0]==0.0f && _mat[2][1]==0.0f &&
> _mat[2][2]==1.0f&&  _mat[2][3]==
> 0.0f &&
>                    _mat[3][0]==0.0f && _mat[3][1]==0.0f &&
> _mat[3][2]==0.0f&&  _mat[3][3]==
> 1.0f;
>         }
>
> Is there a specific reason for not using epsilon tests for a float? I
can
> think of quite a few situations when this would fail.
> I guess, there is only one situation when this would succeed for sure,
and
> that is after a call to makeIdentity().
>
>
> This also goes for quite some of the Vec3, Vec4, Quat code too.
> All comparisons such as:
>
> inline bool operator == (const Vec3f& v) const { return _v[0]==v._v[0]
&&
> _v[1]==v._v[1] && _v[2]==v._v[2]; }
>
> Would effectively fail in most situations, as comparing floats directly
is
> something that is not recomended.
>
>
> Instead something like the following should be used:
>
>
> #define EPSILON 1E-16
> #define EQUAL(A,B) (abs((A)-(B)) < EPSILON)
>
> inline bool operator == (const Vec3f& v) const { return
> EQUAL(_v[0]-v._v[0]) && EQUAL(_v[1]-v._v[1]) && EQUAL(_v[2]-v._v[2]); }'
Well, that is wrong too.

In effect you are making fixed point arithmethic from floating point
arithmethic.
Somehow more correct would be:
#define EQUAL(A,B) (abs((A)-(B)) <=
std::numeric_limits<double>::epsilon()*max(abs(a), abs(b)))
But even that is not the real trueth...
See Goldbergs excelent paper 'what every sceintist should know about
floating
point arithmetics' (just google for that).
Doing that right is highly dependent on the application you need.
Due to error accumulation your proposed bound is too hard, since this test
only checks for roundoff in the representation, not roundoff that happens
when operating on such numbers.

I cannot speak for osg, but from my point of view the implemented method
is
perfect. If you want to have an 'equal up to floating point precision'
test I
would prefer having a new set of methods that do not test for exact
equality.
From my experience with that kind of stuff, you should not hard code that
EPSILON here - may be provide a sensible default value but no hardcoding
...

   Greetings

        Mathias

--
Dr. Mathias Fröhlich, science + computing ag, Software Solutions
Hagellocher Weg 71-75, D-72070 Tuebingen, Germany
Phone: +49 7071 9457-268, Fax: +49 7071 9457-511
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/




--


________________________________________________________________
Anders Backman               Email:    [EMAIL PROTECTED]
HPC2N/VRlab                  Phone:    +46 (0)90-786 9936
Umea university              Cellular: +46 (0)70-392 64 67
S-901 87 UMEA SWEDEN         Fax:      +46 90-786 6126
                              http://www.cs.umu.se/~andersb
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/

Reply via email to