mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 07:13:02 +04:00
74fbfc2343
core: fix solveCubic numerical instability via coefficient normalization (fixes #27748) #28117 Summary This PR fixes numerical instability in `cv::solveCubic` when the leading coefficient `a` is non-zero but extremely small relative to other coefficients (Issue #27748). It introduces a **normalization step** that scales all coefficients by their maximum magnitude before solving. This ensures robust detection of when the equation should degenerate to a quadratic solver, without breaking valid cubic equations that happen to have small coefficients (e.g., scaled by 1e-9). The Problem (Issue #27748) The previous implementation checked `if (a == 0)` to decide whether to use the cubic or quadratic formula. - When `a` is extremely small (e.g., 1e-17) but not exactly zero, and other coefficients are normal (e.g., 5.0), the standard cubic formula suffers from catastrophic cancellation and overflow, producing incorrect roots (e.g., 1e14). The Fix 1. Normalization: The solver now finds `max_coeff = max(|a|, |b|, |c|, |d|)` and scales all coefficients by `1.0 / max_coeff`. 2. Relative Threshold: It then checks `if (abs(a) < epsilon)` on the *normalized* coefficients. Why this is better than previous attempts In a previous attempt (PR #28057), a simple absolute check `abs(a) < epsilon` was proposed. That approach was rejected because it failed for scaled equations. Fixes #27748