Skip to content

linear_algebra/polynom_for_points: ZeroDivisionError on valid points containing x=0 (Gaussian elimination without pivoting) #14817

Description

@aimasteracc

Description

linear_algebra/src/polynom_for_points.py::points_to_polynomial crashes with ZeroDivisionError for valid inputs that include a point with x = 0. It solves the interpolation system with Gaussian elimination without pivoting, so a zero on the diagonal divides by zero:

for count in range(x):
    for number in range(x):
        if count == number:
            continue
        fraction = matrix[number][count] / matrix[count][count]   # /0 when matrix[count][count] == 0
        ...

matrix[count][count] = coordinates[count][0] ** (x - (count + 1)). When an x-coordinate is 0, that diagonal entry is 0 ** positive = 0, so the very first elimination step divides by zero. The input passes every validation in the function (non-empty, all pairs length-2, distinct points, distinct x-values) — it is a genuinely fittable set — and then crashes in the solver.

Steps to reproduce (verified)

from linear_algebra.src.polynom_for_points import points_to_polynomial

points_to_polynomial([[0, 1], [1, 2], [2, 5]])   # f(x) = x^2 + 1 passes through these
# -> ZeroDivisionError: division by zero

points_to_polynomial([[0, 0], [1, 1], [2, 4]])    # f(x) = x^2
# -> ZeroDivisionError: division by zero

The existing doctests only use x-values 1, 2, 3, so the x = 0 case is uncovered.

Expected behavior

For [[0, 1], [1, 2], [2, 5]] it should return the fitting polynomial (f(x)=x^2*1.0+x^1*0.0+x^0*1.0), not crash. Any set of points with distinct x-values has a unique interpolating polynomial.

Actual behavior

ZeroDivisionError whenever any point has x = 0 (and generally whenever a zero pivot appears on the diagonal during elimination).

Suggested fix

Use partial pivoting: before each elimination step, swap in a row whose matrix[r][count] is non-zero (largest magnitude). This removes the zero-pivot crash and also improves numerical stability. A doctest with an x = 0 point (e.g. points_to_polynomial([[0, 1], [1, 2], [2, 5]])) should be added to cover it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions