mathnet / mathnet-numerics

Math.NET Numerics
http://numerics.mathdotnet.com
MIT License
3.49k stars 897 forks source link

Rounding issues in Vector Storage #941

Open amastrobera opened 2 years ago

amastrobera commented 2 years ago

Hello,

I have used some of your Vector<double> class. It has problems with the function Equals. The result is some vector of doubles are equal but this function returns false. This affects pretty much all my functions with points/vectors.

If you see this line you will notice that the rounding of type T is not handled.

I would have done this instead

 if ( Math.Round(At(index) - other.At(index), 9) != 0)

And I would have added a file with constants like MAX_DECIMAL_PRECISION = 9 instead of that magic number.

But I don't know much about C# and I don't know to add the restriction on type T to have the operator - defined, or create an interface which has that operator declared.

Arlofin commented 1 year ago

T is generic (at least at compile time), hence the non-generic Math.Round function cannot be used. For the same reason, the - operator is not defined. The implementation is idiomatic for C# as it uses the generic Equals method. Even in your specific example with double precision floating numbers I would not advise to rely on the Equals method as floats are not meant to be compared for equality. Comparing up to a certain number of digits (as you suggest) is not equality, it is approximation.

cdrnet commented 1 year ago

We do have some functionality in the Precision type that goes into this direction, like Precision.AlmostEqual which also works on vectors - do these not work for your use case?