Skip to content

Fixed division bug in max_inscribed_ball causing test_max_ball failure#454

Open
Shorya777 wants to merge 3 commits intoGeomScale:developfrom
Shorya777:bugfix/fix-max-inscribed-ball-division
Open

Fixed division bug in max_inscribed_ball causing test_max_ball failure#454
Shorya777 wants to merge 3 commits intoGeomScale:developfrom
Shorya777:bugfix/fix-max-inscribed-ball-division

Conversation

@Shorya777
Copy link
Copy Markdown

@Shorya777 Shorya777 commented Feb 21, 2026

Fixes - #453

This PR resolves the numerical instability reported in #453 by introducing a safeguarded division helper to prevent divisions by extremely small values during the interior-point iterations of max_inscribed_ball.

Implementation
Added a helper function:

template <typename NT>
inline NT safe_div(NT num, NT denom) {
    constexpr NT eps = NT(1e-12);
    if (std::abs(denom) < eps)
        denom = (denom >= 0 ? eps : -eps);
    return num / denom;
}

The unstable division was replaced with guarded divisions using safe_div, ensuring that denominators do not approach zero.

Testing
test_max_ball now passes.

volesti-bug-solved

@Dev-sh21
Copy link
Copy Markdown

Hey @Shorya777 , in calcstep line 45, it seems the grouping of the division has changed during refactoring.
The original code was ((v4/v2) - v5) / v3, but the new line is (v4/v2) - (v5/v3),
earlier v3 was dividing the entire numerator, but now its just dividing v5
This would change the mathematical result of the iteration

just verify pls

@Dev-sh21
Copy link
Copy Markdown

also
@Shorya777 ,

using std::max(denom, eps) is risky if denom is negative. In optimization edge cases, if the denominator is a small negative number, safe_div will flip its sign to positive eps, leading to incorrect directional updates, a better approach would be to using the ternary operation something like

(denom >= 0 ? std::max(denom, eps) : std::min(denom, -eps)) to preserve the sign

just verify pls

@Shorya777
Copy link
Copy Markdown
Author

Hey @Shorya777 , in calcstep line 45, it seems the grouping of the division has changed during refactoring. The original code was ((v4/v2) - v5) / v3, but the new line is (v4/v2) - (v5/v3), earlier v3 was dividing the entire numerator, but now its just dividing v5 This would change the mathematical result of the iteration

just verify pls

yeah I fixed it now! I just saw that because of it test_max_ball_sparse was failing but now it's okay.
every test is passing now.

@Shorya777
Copy link
Copy Markdown
Author

also @Shorya777 ,

using std::max(denom, eps) is risky if denom is negative. In optimization edge cases, if the denominator is a small negative number, safe_div will flip its sign to positive eps, leading to incorrect directional updates, a better approach would be to using the ternary operation something like

(denom >= 0 ? std::max(denom, eps) : std::min(denom, -eps)) to preserve the sign

just verify pls

yeah I think that would be a problem. Working on it.

@Shorya777
Copy link
Copy Markdown
Author

Hi @vissarion and @TolisChal, I would appreciate your feedback on this PR when you have time. Please let me know if any adjustments are needed.

Copy link
Copy Markdown
Contributor

@Akash504-ai Akash504-ai left a comment

Choose a reason for hiding this comment

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

Thanks for addressing this and correcting the formula, with the fixes in place and tests passing...this looks good.

Copy link
Copy Markdown
Member

@vissarion vissarion left a comment

Choose a reason for hiding this comment

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

Thanks for this PR.

Could you please explain why did you decide to use NT(1e-12)? Is it part of some experimentation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants