gifnksm / polynomial-rs

Manipulations and data types that represent polynomial
MIT License
16 stars 10 forks source link

Incorrect polynomial fitment #25

Open x-zvf opened 8 months ago

x-zvf commented 8 months ago

The degree 2 polynomial to $f(0)=3849; f(1)=34331; f(2)=95175$ is incorrectly fitted.

This library returns: $3848 + 15303 x + 15180 x^2 $ The correct result is: $3849 + 15301 x + 15181 x^2 $ Error: $-1 + 2x -1x^2$ This can be verified by res-subsituting the variables. In particular, the error in $f(0)$ is trivial

Wolframalpha gives the correct result

Reproduction

Cargo.toml

[dependencies]
polynomial = "0.2.6"

src/main.rs

use polynomial::Polynomial;
fn main() {
    let xs = vec![0, 1, 2];
    let ys = vec![3849, 34331, 95175];

    let poly = Polynomial::lagrange(&xs, &ys).unwrap();
    println!("{}", poly.pretty("x")); //3848+15303*x+15180*x^2
}

This was found during AOC Day21, and was responsible for quite some hours of debugging :^|

konsumlamm commented 8 months ago

The reason this happens is that you're using integers, so you get rounding errors. Using floats, you get the correct result.

x-zvf commented 8 months ago

Fair enough, although from a user's perspective it does seem weird, that fitting purely integer points (with an integer result) yields rounding errors. Since the only imporant property of the Lagrange-polynomial is that it EXACTLY fits the points, maybe you should consider disallowing the usage of integers with the type system, or at least note this in the documentation