Skip to Content.
Sympa Menu

cgal-discuss - Re: [cgal-discuss] error in comparing CORE Expr values

Subject: CGAL users discussion list

List archive

Re: [cgal-discuss] error in comparing CORE Expr values


Chronological Thread 
  • From: Stefan Schirra <>
  • To:
  • Subject: Re: [cgal-discuss] error in comparing CORE Expr values
  • Date: Thu, 19 Sep 2019 11:27:18 +0200
  • Authentication-results: mail2-smtp-roc.national.inria.fr; spf=None ; spf=Pass ; spf=None
  • Ironport-phdr: 9a23:ylCgSRJiGOyJSkKeA9mcpTZWNBhigK39O0sv0rFitYgeKPzxwZ3uMQTl6Ol3ixeRBMOHsqkC0bKd6v2oGTRZp8rY6jZaKN0EfiRGoP1epxYnDs+BBB+zB9/RRAt+Iv5/UkR49WqwK0lfFZW2TVTTpnqv8WxaQU2nZkJ6KevvB4Hdkdm82fys9J3PeQVIgye2ba9vIBmsogjdq8cbjZF8JqotxRfFv3tFcPlSyW90OF6fhRnx6tqu8JJ57yhcp/ct/NNcXKvneKg1UaZWByk8PWAv483ruxjDTQ+R6XYZT24bjBlGDRXb4R/jRpv+vTf0ueR72CmBIM35Vqs0Vii476dqUxDnliEKPCMk/W7Ni8xwiKVboA+9pxF63oXZbp2ZOOZ4c6jAe94RWGhPUdtLVyFZH42ycYUPAeoCM+hWoYbyqFkBogexCwS3GOPiySVFimPq0aA00eksFxzN0gw6H9IJtXTZtMj7NLsMXuC71qbIyyjIYe5K1jf96YjIaAohruuRVr93asrR1VIvGB/FjlWRs4zlJSiY1uUWs2iU9eZvSfmvh3Q6qwF3ozij38IshZPGho0I1F/L7jh5wJw6JdGiVUF0f8epHZ1NvC+ZL4t7Wt4uTm51tCogxbALtoS3cDYExZg92hLSbeGMfZKS7RL5TumRJC91hHJ7d7K7gBa/6UygyvDzV8auzFZKqTBFnsPQuXAWzRDT986HSvpk8kekwzmP2B3c5f9fLkApj6rbJIQtzaMumZYLsETDGDH5mFnugaOLeUgo5/Kk5uvob7n8uJOROZV4hhzmPqQrgMO/AOA4MgYUX2ic/OSxzKbj/VHiQLpWjv02k7PZsIrBKMQava65DBVZ3Zo46xqlEjem1tUYkWACLF1fdxKIkpbmNErTIPDiAvezmUmjnylzy/DcIrLhGonNLmTEkLr5Ybl95FRTyA4qwd9C5pJUEa0OIO/oWk/qr9HYFR84Mwmsw+n9Etl914UeWXiOAqCDKq/Sv0WItaoTJLyHa4YR/Tr8MPM4/OXGjHkjmFZbc7P684EQbSWDAvloKkPRWnHsg80bGC9epRYlR+zrkkeqUCVcIX2pGb8653Q+AY2qAI3eXI/rjLHXj3TzJYFfem0TUgPEKnzvbYjRA65dOhLXGddol3k/bZbkToYg0R+0swqgluhmNeWS8TZeqJTikd186OHenwwo+np4ApbEij3ffyRPhmoNAgQO8uVnu0UnlwWCyqc+iOceCNpSovZAXQs3P4PGwKp2BoKqA1+TTpKyUF+jB+6eL3QxQ9Y2mY5cZ1ttEsmllFbIxGy3Bb5QkrWECJE+77jTmXT8dZ5w

Hi,

On 18.09.2019 15:33, Peter Palfrader wrote:
Hi!

I have encountered what seems like a strange issue:

Consider this code snippet:
] std::cout << "v1: " << v1 << std::endl;
] std::cout << "v2: " << v2 << std::endl;
] std::cout << "v1 < v2: " << (v1 < v2 ? "yes" : "no") << std::endl;
which prints this:
] v1: 0.49770
] v2: 0.01047
] v1 < v2: yes

I'm not sure what is going on, but I don't think that 0.49770 is
less than 0.01047. :)

This is with libcgal13 (as shipped in Debian 10[1] and Ubuntu 18.04). The
attached piece of code constructs v1 and v2. Compiling with clang++ (or g++)
produces this effect:

| weasel@waschbaer:~$ clang++ cgal0_1.cpp -o cgal -lgmpxx -lgmp
-lboost_thread -lCGAL_Core -lCGAL
| weasel@waschbaer:~$ ./cgal
| v1: 0.49770
| v2: 0.01047
| v1 < v2: yes


If you multiply all the constants (not unity) by 100, nothing changes:
| v1: 49.7703
| v2: 1.04670
| v1 < v2: yes

Once you multiply them by 10000: (cf. cgal0_2.cpp).
| v1: 4977.03
| v2: 104.670
| v1 < v2: no

Something's fishy here.

Cheers,
Peter

1. Versions of packages libcgal13:amd64 depends on:
libboost-thread1.67.0 1.67.0-13
libc6 2.28-10
libgcc1 1:8.3.0-6
libgmp10 2:6.1.2+dfsg-4
libstdc++6 8.3.0-6
zlib1g 1:1.2.11.dfsg-1


WARNING: This is a partial answer, not a solution.

Apparently, the problem is with the floating-point filter (FPF). CORE "checks" whether the interval of the FPF allows for deciding the sign and if so reports the sign of the approximation. The FPF maintains three values, an approximation fpVal, and maxAbs and ind, such that maxAbs * ind * 2^{-53} is an error bound for the approximation. Unfortunately the interval for v1-v2 is incorrect (because the interval for v1 is incorrect). The actual bigFloat approximation for v1-v2 is correct and has the correct sign, but its sign is not used in the < operation.

An excerpt from the code:

inline int ExprRep::getSign() {
if (ffVal.isOK())
return ffVal.sign();
else
return getExactSign();
}

If you add

std::cout << "ex.sign of v1-v2: " << (v1-v2).Rep()->getExactSign() << std::endl;

you'll get the correct sign!

The intervals for v1, v2, and v1-v2 are

v1: Filter=[fpVal=0,maxAbs=2.22507e-308,ind=13]
v2: Filter=[fpVal=0.010467,maxAbs=6.57198e+10,ind=23]
v1-v2: Filter=[fpVal=-0.010467,maxAbs=6.57198e+10,ind=24]

and you see, the interval for v1 is wrong since it does not contain the actual value.


Tracing this back a bit we see after


NT e_f4c1f8 = e_ed6940 / e_ed68a0; // -4.00000 // tree-height: 13

e_ed6940: -6.56405e-17
e_ed6940: Filter=[fpVal=-1.12323e-16,maxAbs=1.02754e+08,ind=18]
e_ed68a0: 1.64101e-17
e_ed68a0: Filter=[fpVal=2.80266e-17,maxAbs=139.598,ind=6]
e_f4c1f8: -4.00000
e_f4c1f8: Filter=[fpVal=inf,maxAbs=0,ind=0]

So we have approximation infinity, but error 0 (IMHO this is strange!) for e_....

If we set the error to infiƄity in operator/ for FPF in CORE/Filter.h

filteredFp operator/ (const filteredFp& x) const {
if (x.fpVal == 0.0)
core_error("possible zero divisor!", __FILE__, __LINE__, false);
double xxx = core_abs(x.fpVal) / x.maxAbs - (x.ind+1)*CORE_EPS + DBL_MIN;
if (xxx > 0) {
double val = fpVal / x.fpVal;
double maxVal = ( core_abs(val) + maxAbs / x.maxAbs) / xxx + DBL_MIN;
return filteredFp(val, maxVal, 1 + core_max(ind, x.ind + 1));
} else
// return filteredFp(getDoubleInfty(), 0.0, 0);
return filteredFp(getDoubleInfty(), getDoubleInfty(), 1); // NEW
}

it works.

May be this information helps to find the real bug and to design a bug fix.


Best regards


Stefan






Archive powered by MHonArc 2.6.18.

Top of Page