Skip to content

Commit 3c70a54

Browse files
authored
feat: Add Neville's Algorithm (#6842)
* feat: Add Neville's algorithm for polynomial interpolation * Update Neville.java * style: Fix linter formatting issues. * Handled Div by Zero Case * Update NevilleTest.java * Update Neville.java * Update NevilleTest.java * Update Neville.java
1 parent 14a0de4 commit 3c70a54

File tree

2 files changed

+130
-0
lines changed

2 files changed

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

0 commit comments

Comments
 (0)