Skip to content
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

Bugfix: Early exit in eigen_solve method #1412

Merged
merged 23 commits into from
Sep 26, 2024

Conversation

jcs15c
Copy link
Contributor

@jcs15c jcs15c commented Sep 17, 2024

Summary

  • This PR is a bugfix. It removes an unnecessary early termination criterion in the numerics::eigen_solve method.
  • A test for the primal::OrientedBoundingBox( const PointType* pts ) constructor has been added, which utilizes this method.

The numerics::eigen_solve method uses the power method to find eigenvalues and eigenvectors for an NxN matrix. At each step, a random vector is created and then made orthonormal to previously found eigenvectors. If this randomly created vector is (numerically) already in the span of previously found eigenvectors, it has zero magnitude, and the algorithm will terminate early with an error status.

While this event has mathematically zero chance of occurring, it occurs numerically in roughly 0.05% of runs of the existing numerics_eigen_solve test, resulting in a fail state.

This behavior has been modified so that if the resulting vector has (near-) zero magnitude, it is instead discarded and a new one is generated.

Discussion

This behavior was originally observed through repeated calls to the primal::OrientedBoundingBox( const PointType* pts ) constructor as a part of a winding number algorithm, which would occasionally return erroneous results on Release or terminate entirely on Debug. Further investigation revealed that no test in the OBB testing suite used this constructor. Although the actual likelihood of failing such a test in this way is very low, as was the case with the existing numerics_eigen_solve tests, a test has been added.

@jcs15c jcs15c added bug Something isn't working Core Issues related to Axom's 'core' component Primal Issues related to Axom's 'primal component labels Sep 17, 2024
@jcs15c jcs15c self-assigned this Sep 17, 2024
Copy link
Member

@kennyweiss kennyweiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jcs15c for this nice bugfix!

I have a few questions/concern though, possibly/likely outside the scope of this bugfix:

  • if the point distribution truly has fewer than k dimensions, e.g. we're given 3D points that lie on a plane (2D affine space) or a line (1D affine space) and the user requests K=3 eigenvalues/vectors, will the code still find the right answer? Seems like it should, but perhaps we should add a test since one use case is to build an OBB over a triangle.
  • similarly, there is a second normalize and check in step 3 -- does that always do the right thing for data that lives in a lower dimensional subspace? I think so too, but it might also be worth checking
  • (almost definitely outside the scope of this PR): I noticed that we're only testing this function for k==N. Should we have tests for $0 < k<N$ or $k>N$? I suppose the higher level question is whether the parameter k is useful, or if it can always be assumed to be N
    • EDIT: I think we do want to keep the k parameter for eigen_solve, but I also think we should have tests for this. It does not have to be in this PR though. I created Improve testing of eigen_solve #1414 to track this.

Minor: There is a typo in the doxygen comment for eigen_solve:

- * \param [out] lambdas pointer to k eigenvales in order by size
+ * \param [out] lambdas pointer to k eigenvalues in order by size

Please also update the RELEASE_NOTES to reflect this bugfix

{
return 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice fix!

Bonus points: this was also a memory leak for temp!

@jcs15c
Copy link
Contributor Author

jcs15c commented Sep 18, 2024

@kennyweiss I've added some discussion of the eigen_solve method in the relevant issue, but your idea to check lower-dimensional subspaces for the OBB is a good one. Fortunately, degenerate axes of the OBB are already properly handled by the current implementation. I've updated the test accordingly.

@jcs15c jcs15c marked this pull request as ready for review September 18, 2024 15:55
@kennyweiss kennyweiss merged commit bb0dbfb into develop Sep 26, 2024
13 checks passed
@kennyweiss kennyweiss deleted the bugfix/spainhour/eigen_solve_error branch September 26, 2024 07:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Core Issues related to Axom's 'core' component Primal Issues related to Axom's 'primal component
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants