Global variable settings affecting robustness and precision - READ!.
Namespace:
ceometric.VectorGeometryAssembly: ceometric.VectorGeometry (in ceometric.VectorGeometry.dll) Version: 1.8.0.0 (1.8.0.0)
Syntax
C# |
---|
public struct Global |
Visual Basic (Declaration) |
---|
Public Structure Global |
Visual C++ |
---|
public value class Global |
Remarks
Floating point arithmetic is not exact. Errors occur due to
CopyC#
Although one would expect that a point p always lies on pl, the output is
'100000 of 100000 tests failed!'. This simple example shows that a geometric test relying
on floating point arithmetic is generally futile if the test depends on an exact result.
A formally correct solution could be the implementation of exact arithmetic which on the other hand slows all
computations significantly down. The decimal data type decimal does not address this problem since it is a
slow finite precision 128 bit data type but still not exact.
In many cases the results obtained using exact arithmetic may not be of practical use as well: if the input
data does not have infinite precision, tests will fail at large.
This library addresses this problem in three ways by
CopyC#
The result looks fine: '0 of 100000 tests failed!'. But then again,
CopyC#
outputs: '70511 of 100000 tests failed!'. This happens because we only
allow a tiny absolute error of 1e-12. Since the double value type has a precision of 15-16 decimal digits,
a bound of 1e-12 works well with coordinates between 0 and 1. Setting Global.MaxRandom = 1e9 generates coordinates
up to a billion with a precision of only 6-7 decimal digits. Obviously, the absolute epsilon is too restrictive in this
case. Increasing the absolute epsilon value is not a good choice. It is better to do a relative comparison in addition:
CopyC#
The outputs is '8 of 100000 tests failed!'.
The AlmostEquals method
In your own computations, you can easily benefit from the absolute and relative comparison concept of this library.
When comparing two double precision values a and b, write
CopyC#
rather than
CopyC#
You can still influence the result of the comparison adjusting the AbsoluteEpsilon and
RelativeEpsilon fields while you increase the robustness and scalability of your algorithms at the same time.
- finite precision
- round off errors

public void TestPlaneContainsPoint() { Global.AbsoluteEpsilon = 0; // set all error bound to zero to Global.RelativeEpsilon = 0; // enforce exact comparison Global.MaxRandom = 1e0; // produce random values between [0...1] int err = 0; int n = 100000 for ( int i = n; i > 0; i-- ) { Plane pl = Plane.RandomPlane(); Point p = pl.RandomPointOnPlane(); // this point should always lie on the plane! if ( !pl.Contains(p) ) err++; } Console.WriteLine(err + " of " + n + " tests failed!"); }
- implementing robust algorithms
- normalizing data when advantageous
- implementing an absolute AND a relative delta comparison
or
Math.Abs((a - b) / b) > RelativeEpsilon else. Let's give TestPlaneContainsPoint a second chance:
... Global.AbsoluteEpsilon = 1e-12; Global.RelativeEpsilon = 0; // set this value zero for absolute epsilon comparison only! Global.MaxRandom = 1e0; // produce random values between [0...1] ...

... Global.AbsoluteEpsilon = 1e-12; Global.RelativeEpsilon = 0; // set this value zero for absolute epsilon comparison only! Global.MaxRandom = 1e9; // produce random values between [0...1000000000] ...

... Global.AbsoluteEpsilon = 1e-12; Global.RelativeEpsilon = 1e-12; Global.MaxRandom = 1e9; // produce random values between [0...1000000000] ...

...
if (Global.AlmostEquals(a, b)) ...
...

...
if (a == b) ...
...