Skip to content

Commit 0d40c84

Browse files
Add Linear Interpolation (#500)
1 parent ca813d5 commit 0d40c84

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

src/math/interpolation.rs

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/// In mathematics, linear interpolation is a method of curve fitting
2+
/// using linear polynomials to construct new data points within the range of a discrete set of known data points.
3+
/// Formula: y = y0 + (x - x0) * (y1 - y0) / (x1 - x0)
4+
/// Source: https://en.wikipedia.org/wiki/Linear_interpolation
5+
/// point0 and point1 are a tuple containing x and y values we want to interpolate between
6+
pub fn linear_interpolation(x: f64, point0: (f64, f64), point1: (f64, f64)) -> f64 {
7+
point0.1 + (x - point0.0) * (point1.1 - point0.1) / (point1.0 - point0.0)
8+
}
9+
10+
/// In numerical analysis, the Lagrange interpolating polynomial
11+
/// is the unique polynomial of lowest degree that interpolates a given set of data.
12+
///
13+
/// Source: https://en.wikipedia.org/wiki/Lagrange_polynomial
14+
/// Source: https://mathworld.wolfram.com/LagrangeInterpolatingPolynomial.html
15+
/// x is the point we wish to interpolate
16+
/// defined points are a vector of tuples containing known x and y values of our function
17+
pub fn lagrange_polynomial_interpolation(x: f64, defined_points: &Vec<(f64, f64)>) -> f64 {
18+
let mut defined_x_values: Vec<f64> = Vec::new();
19+
let mut defined_y_values: Vec<f64> = Vec::new();
20+
21+
for (x, y) in defined_points {
22+
defined_x_values.push(*x);
23+
defined_y_values.push(*y);
24+
}
25+
26+
let mut sum = 0.0;
27+
28+
for y_index in 0..defined_y_values.len() {
29+
let mut numerator = 1.0;
30+
let mut denominator = 1.0;
31+
for x_index in 0..defined_x_values.len() {
32+
if y_index == x_index {
33+
continue;
34+
}
35+
denominator *= defined_x_values[y_index] - defined_x_values[x_index];
36+
numerator *= x - defined_x_values[x_index];
37+
}
38+
39+
sum += numerator / denominator * defined_y_values[y_index];
40+
}
41+
sum
42+
}
43+
44+
#[cfg(test)]
45+
mod tests {
46+
47+
use std::assert_eq;
48+
49+
use super::*;
50+
#[test]
51+
fn test_linear_intepolation() {
52+
let point1 = (0.0, 0.0);
53+
let point2 = (1.0, 1.0);
54+
let point3 = (2.0, 2.0);
55+
56+
let x1 = 0.5;
57+
let x2 = 1.5;
58+
59+
let y1 = linear_interpolation(x1, point1, point2);
60+
let y2 = linear_interpolation(x2, point2, point3);
61+
62+
assert_eq!(y1, x1);
63+
assert_eq!(y2, x2);
64+
assert_eq!(
65+
linear_interpolation(x1, point1, point2),
66+
linear_interpolation(x1, point2, point1)
67+
);
68+
}
69+
70+
#[test]
71+
fn test_lagrange_polynomial_interpolation() {
72+
// defined values for x^2 function
73+
let defined_points = vec![(0.0, 0.0), (1.0, 1.0), (2.0, 4.0), (3.0, 9.0)];
74+
75+
// check for equality
76+
assert_eq!(lagrange_polynomial_interpolation(1.0, &defined_points), 1.0);
77+
assert_eq!(lagrange_polynomial_interpolation(2.0, &defined_points), 4.0);
78+
assert_eq!(lagrange_polynomial_interpolation(3.0, &defined_points), 9.0);
79+
80+
//other
81+
assert_eq!(
82+
lagrange_polynomial_interpolation(0.5, &defined_points),
83+
0.25
84+
);
85+
assert_eq!(
86+
lagrange_polynomial_interpolation(2.5, &defined_points),
87+
6.25
88+
);
89+
}
90+
}

src/math/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ mod gaussian_elimination;
1717
mod gcd_of_n_numbers;
1818
mod greatest_common_divisor;
1919
mod interest;
20+
mod interpolation;
2021
mod karatsuba_multiplication;
2122
mod lcm_of_n_numbers;
2223
mod linear_sieve;
@@ -67,6 +68,7 @@ pub use self::greatest_common_divisor::{
6768
greatest_common_divisor_stein,
6869
};
6970
pub use self::interest::{compound_interest, simple_interest};
71+
pub use self::interpolation::{lagrange_polynomial_interpolation, linear_interpolation};
7072
pub use self::karatsuba_multiplication::multiply;
7173
pub use self::lcm_of_n_numbers::lcm;
7274
pub use self::linear_sieve::LinearSieve;

0 commit comments

Comments
 (0)