-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix accuracy in angle computation #224
Conversation
Also, there are many other functions that compute unnecessary cross products and those computations should be reviewed in a separate PR. |
Add that test? 😉 |
@pllim Working on it right now. Patience, my friend. |
@pllim See second commit |
Codecov ReportBase: 65.09% // Head: 65.09% // No change to project coverage 👍
Additional details and impacted files@@ Coverage Diff @@
## master #224 +/- ##
=======================================
Coverage 65.09% 65.09%
=======================================
Files 8 8
Lines 1252 1252
=======================================
Hits 815 815
Misses 437 437 Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not worthy to review this but I appreciate you adding a test. 😸
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also wish there was a way to partition changes made due to PEP8 changes and actual code changes. The PEP8 changes make it harder to see the code changes. Two separate PRs?
dot_qd(A, B, &ab); | ||
c_qd_mul(aa.x, bb.x, aabb); | ||
|
||
if (aabb[0] < -0.0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this part where the product of the dot products of each vector is computed. In principle each dot product should be positive (or zero), but never negative, and yet there is a test for a negative value. If there is a way for the dot product to be negative through a bug, then both might be negative. And what does this have to do with normalizing with regard to the dot of A and B? I am missing something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And what does this have to do with normalizing with regard to the dot of A and B? I am missing something.
It has nothing to do with normalizing with regard to the dot of A and B. Yes, you are missing the comment above the function:
normalized_dot_qd returns dot product of normalized input vectors.
The original code was doing this:
Anormalized = A / SQRT(A.A)
Bnormalized = B / SQRT(B.B)
AB = Anormalized.Bnormalized
Modified code does this:
AB = A.B / SQRT((A.A)*(B.B))
This reduces the number of calls to the SQRT function - the one that has the tendency t introduce those random bits in the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I was missing something.
There are no PEP8 changes here. Unfortunately some lines had trailing white spaces and my editor strips those spaces on Save. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks Stupendous To Me
dot_qd(A, B, &ab); | ||
c_qd_mul(aa.x, bb.x, aabb); | ||
|
||
if (aabb[0] < -0.0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I was missing something.
This PR is an alternative to #223 and it builds upon it. While I kept significant simplifications in the vector formulas (dot product of two cross products) proposed by @perrygreenfield in #223, I also reduced the number of calls to the
sqrt
function to normalize the cross products entering the dot product.This was done because it turns out that the main source of "erratic values" in the 2nd double in the quad comes from the
sqrt
function. I have tried to keep the same algorithm and increase accuracy of computations but it still did not solve the issue completely: it only reduced the occurrence of these erratic values but did not eliminate them.On the other hand, a complete replacement of the algorithm in the
sqrt
function with the Heron's method resulted in a much more stable algorithm (albeit it is likely slower than the original multiply-add algorithm). I kept the checks that @perrygreenfield introduced for the case when the 1st double is +/- 1 but do not usefabs
as values smaller than 1 in magnitude could still be legitimate values.Also, the formula for computing conjugate angles was slightly improved in the accuracy.
I have arrived at the conclusion that the "erratic values" are not due to bugs in the
qd
library but rather a limitation of the accuracy of quad numbers: the original paper by the authors of theqd
library says that at least 212 bits should be significant. This means that quad numbers have about 64 significant digits, in agreement with observed magnitudes of the erratic values in the second double (<1e-65). Instead on relying on a hard-coded value, this PR usesepsilon()
value provided by the quad library (which is hardcoded though).Closes #222