Skip to content

Commit e6cf4b0

Browse files
committed
feat: Add Neville's algorithm for polynomial interpolation
1 parent d5289b9 commit e6cf4b0

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
Neville.java
2+
package com.thealgorithms.maths;
3+
4+
/**
5+
* In numerical analysis, Neville's algorithm is an algorithm used for
6+
* polynomial interpolation. Given n+1 points, there is a unique polynomial
7+
* of degree at most n that passes through all the points. Neville's
8+
* algorithm computes the value of this polynomial at a given point.
9+
*
10+
* <p>
11+
* Wikipedia: https://en.wikipedia.org/wiki/Neville%27s_algorithm
12+
*
13+
* @author Mitrajit Ghorui(KeyKyrios)
14+
*/
15+
public final class Neville {
16+
private Neville() {
17+
}
18+
19+
/**
20+
* Evaluates the polynomial that passes through the given points at a specific x-coordinate.
21+
*
22+
* @param x The x-coordinates of the points. Must be the same length as y.
23+
* @param y The y-coordinates of the points. Must be the same length as x.
24+
* @param target The x-coordinate at which to evaluate the polynomial.
25+
* @return The interpolated y-value at the target x-coordinate.
26+
* @throws IllegalArgumentException if the lengths of x and y arrays are different,
27+
* or if the arrays are empty.
28+
*/
29+
public static double interpolate(double[] x, double[] y, double target) {
30+
if (x.length != y.length) {
31+
throw new IllegalArgumentException("x and y arrays must have the same length.");
32+
}
33+
if (x.length == 0) {
34+
throw new IllegalArgumentException("Input arrays cannot be empty.");
35+
}
36+
37+
int n = x.length;
38+
double[] p = new double[n];
39+
System.arraycopy(y, 0, p, 0, n); // Initialize p with y values
40+
41+
for (int k = 1; k < n; k++) {
42+
for (int i = 0; i < n - k; i++) {
43+
p[i] = ((target - x[i + k]) * p[i] + (x[i] - target) * p[i + 1]) / (x[i] - x[i + k]);
44+
}
45+
}
46+
47+
return p[0];
48+
}
49+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.thealgorithms.maths;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
public class NevilleTest {
9+
10+
@Test
11+
public void testInterpolateLinear() {
12+
// Test with a simple linear function y = 2x + 1
13+
// Points (0, 1) and (2, 5)
14+
double[] x = {0, 2};
15+
double[] y = {1, 5};
16+
// We want to find y when x = 1, which should be 3
17+
double target = 1;
18+
double expected = 3.0;
19+
assertEquals(expected, Neville.interpolate(x, y, target), 1e-9);
20+
}
21+
22+
@Test
23+
public void testInterpolateQuadratic() {
24+
// Test with a quadratic function y = x^2
25+
// Points (0, 0), (1, 1), (3, 9)
26+
double[] x = {0, 1, 3};
27+
double[] y = {0, 1, 9};
28+
// We want to find y when x = 2, which should be 4
29+
double target = 2;
30+
double expected = 4.0;
31+
assertEquals(expected, Neville.interpolate(x, y, target), 1e-9);
32+
}
33+
34+
@Test
35+
public void testInterpolateWithNegativeNumbers() {
36+
// Test with y = x^2 - 2x + 1
37+
// Points (-1, 4), (0, 1), (2, 1)
38+
double[] x = {-1, 0, 2};
39+
double[] y = {4, 1, 1};
40+
// We want to find y when x = 1, which should be 0
41+
double target = 1;
42+
double expected = 0.0;
43+
assertEquals(expected, Neville.interpolate(x, y, target), 1e-9);
44+
}
45+
46+
@Test
47+
public void testMismatchedArrayLengths() {
48+
double[] x = {1, 2};
49+
double[] y = {1};
50+
double target = 1.5;
51+
assertThrows(IllegalArgumentException.class, () -> {
52+
Neville.interpolate(x, y, target);
53+
});
54+
}
55+
56+
@Test
57+
public void testEmptyArrays() {
58+
double[] x = {};
59+
double[] y = {};
60+
double target = 1;
61+
assertThrows(IllegalArgumentException.class, () -> {
62+
Neville.interpolate(x, y, target);
63+
});
64+
}
65+
}

0 commit comments

Comments
 (0)