Repository: opencv/opencv
File: modules/core/test/test_math.cpp (C++)

Code before:

TEST(Core_SolveCubic, regression_27748)
{
    // a is extremely small relative to others (approx 1.8e-19 ratio),
    // causing instability in standard cubic formula.
    double a = 1.56041e-17;
    double b = 84.4504;
    double c = -96.795;
    double d = 13.6826;

    Mat coeffs = (Mat_<double>(1, 4) << a, b, c, d);
    Mat roots;

    // We expect the solver to detect the negligible 'a' and solve as quadratic:
    // 84.4504x^2 - 96.795x + 13.6826 = 0
    // Discriminant ~ 4745.8
    // Roots approx: 0.156, 0.990

    int n = solveCubic(coeffs, roots);

    EXPECT_GE(n, 2); // Should find at least 2 real roots (as quadratic)

    for(int i = 0; i < n; i++)
    {
        double r = roots.at<double>(i);
        EXPECT_NEAR(r, 0.5, 1.0);
    }
}

TEST(Core_SolvePoly, regression_5599)
{
    // x^4 - x^2 = 0, roots: 1, -1, 0, 0
    cv::Mat coefs = (cv::Mat_<float>(1,5) << 0, 0, -1, 0, 1 );
    {
        cv::Mat r;
        double prec;
        prec = cv::solvePoly(coefs, r);
        EXPECT_LE(prec, 1e-6);
        EXPECT_EQ(4u, r.total());
        //std::cout << "Preciseness = " << prec << std::endl;
        //std::cout << "roots:\n" << r << "\n" << std::endl;
        ASSERT_EQ(CV_32FC2, r.type());
        checkRoot<float>(r, 1, 0);
        checkRoot<float>(r, -1, 0);
        checkRoot<float>(r, 0, 0);
        checkRoot<float>(r, 0, 0);
    }
    // x^2 - 2x + 1 = 0,  roots: 1, 1
    coefs = (cv::Mat_<float>(1,3) << 1, -2, 1 );
    {
        cv::Mat r;

Review comment (suggestion):
It means that roots are validated in +-1 range. It's too much. See documentation: https://google.github.io/googletest/reference/assertions.html#EXPECT_NEAR

Code after:

TEST(Core_SolveCubic, regression_27748)
{
    // a is extremely small relative to others (approx 1.8e-19 ratio),
    // causing instability in standard cubic formula.
    double a = 1.56041e-17;
    double b = 84.4504;
    double c = -96.795;
    double d = 13.6826;

    Mat coeffs = (Mat_<double>(1, 4) << a, b, c, d);
    Mat roots;

    int n = solveCubic(coeffs, roots);

    // Expecting quadratic behavior (2 roots)
    EXPECT_GE(n, 2);

    // Verify roots satisfy the FULL cubic equation
    for(int i = 0; i < n; i++)
    {
        double x = roots.at<double>(i);
        double val = a*x*x*x + b*x*x + c*x + d;
        // Check residual is small
        EXPECT_LE(fabs(val), 1e-6) << "Root " << x << " does not satisfy the equation";
    }
}

TEST(Core_SolvePoly, regression_5599)
{
    // x^4 - x^2 = 0, roots: 1, -1, 0, 0
    cv::Mat coefs = (cv::Mat_<float>(1,5) << 0, 0, -1, 0, 1 );
    {
        cv::Mat r;
        double prec;
        prec = cv::solvePoly(coefs, r);
        EXPECT_LE(prec, 1e-6);
        EXPECT_EQ(4u, r.total());
        //std::cout << "Preciseness = " << prec << std::endl;
        //std::cout << "roots:\n" << r << "\n" << std::endl;
        ASSERT_EQ(CV_32FC2, r.type());
        checkRoot<float>(r, 1, 0);
        checkRoot<float>(r, -1, 0);
        checkRoot<float>(r, 0, 0);
        checkRoot<float>(r, 0, 0);
    }
    // x^2 - 2x + 1 = 0,  roots: 1, 1
    coefs = (cv::Mat_<float>(1,3) << 1, -2, 1 );
    {
        cv::Mat r;
        double prec;