Skip to content

Commit 0fed69b

Browse files
committed
feat(maths): Add Neville's algorithm for interpolation
1 parent b9c118f commit 0fed69b

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/**
2+
* @file
3+
* @brief Implementation of Neville's Algorithm for polynomial interpolation.
4+
* @details Neville's algorithm is an iterative method to find the value of a
5+
* polynomial that passes through a given set of n+1 points. It evaluates the
6+
* polynomial at a specific point `x` without needing to compute the
7+
* polynomial's coefficients. For more details, see:
8+
* https://en.wikipedia.org/wiki/Neville%27s_algorithm
9+
* @author [Mitrajit Ghorui](https://github.com/KeyKyrios)
10+
*/
11+
12+
#include <cassert> /// for assert
13+
#include <iostream> /// for IO operations
14+
#include <stdexcept> /// for std::invalid_argument
15+
#include <vector> /// for std::vector
16+
#include <cmath> /// for fabs
17+
18+
/**
19+
* @namespace maths
20+
* @brief Mathematical algorithms
21+
*/
22+
namespace maths {
23+
/**
24+
* @namespace nevilles_algorithm
25+
* @brief Functions for Neville's Algorithm
26+
*/
27+
namespace nevilles_algorithm {
28+
/**
29+
* @brief Evaluates the interpolating polynomial at a specific point.
30+
* @param x_coords Vector of x-coordinates of the given points.
31+
* @param y_coords Vector of y-coordinates of the given points.
32+
* @param target The x-coordinate at which to evaluate the polynomial.
33+
* @returns The interpolated y-value at the target x-coordinate.
34+
* @throws std::invalid_argument if input vectors are empty or have mismatched
35+
* sizes.
36+
*/
37+
double interpolate(const std::vector<double>& x_coords,
38+
const std::vector<double>& y_coords, double target) {
39+
if (x_coords.empty() || y_coords.empty()) {
40+
throw std::invalid_argument("Input vectors cannot be empty.");
41+
}
42+
if (x_coords.size() != y_coords.size()) {
43+
throw std::invalid_argument(
44+
"x and y coordinate vectors must be the same size.");
45+
}
46+
47+
int n = x_coords.size();
48+
std::vector<double> p = y_coords; // Initialize p with y values
49+
50+
for (int k = 1; k < n; ++k) {
51+
for (int i = 0; i < n - k; ++i) {
52+
p[i] = ((target - x_coords[i + k]) * p[i] +
53+
(x_coords[i] - target) * p[i + 1]) /
54+
(x_coords[i] - x_coords[i + k]);
55+
}
56+
}
57+
58+
return p[0];
59+
}
60+
} // namespace nevilles_algorithm
61+
} // namespace maths
62+
63+
/**
64+
* @brief Self-test implementations
65+
* @returns void
66+
*/
67+
static void test() {
68+
// Test 1: Linear interpolation y = 2x + 1
69+
// Points (0, 1), (2, 5). Target x=1, expected y=3.
70+
std::vector<double> x1 = {0, 2};
71+
std::vector<double> y1 = {1, 5};
72+
double target1 = 1;
73+
double expected1 = 3.0;
74+
assert(fabs(maths::nevilles_algorithm::interpolate(x1, y1, target1) - expected1) < 1e-9);
75+
std::cout << "Linear test passed." << std::endl;
76+
77+
// Test 2: Quadratic interpolation y = x^2
78+
// Points (0, 0), (1, 1), (3, 9). Target x=2, expected y=4.
79+
std::vector<double> x2 = {0, 1, 3};
80+
std::vector<double> y2 = {0, 1, 9};
81+
double target2 = 2;
82+
double expected2 = 4.0;
83+
assert(fabs(maths::nevilles_algorithm::interpolate(x2, y2, target2) - expected2) < 1e-9);
84+
std::cout << "Quadratic test passed." << std::endl;
85+
86+
// Test 3: Negative numbers y = x^2 - 2x + 1
87+
// Points (-1, 4), (0, 1), (2, 1). Target x=1, expected y=0.
88+
std::vector<double> x3 = {-1, 0, 2};
89+
std::vector<double> y3 = {4, 1, 1};
90+
double target3 = 1;
91+
double expected3 = 0.0;
92+
assert(fabs(maths::nevilles_algorithm::interpolate(x3, y3, target3) - expected3) < 1e-9);
93+
std::cout << "Negative numbers test passed." << std::endl;
94+
95+
std::cout << "All tests have successfully passed!" << std::endl;
96+
}
97+
98+
/**
99+
* @brief Main function
100+
* @returns 0 on exit
101+
*/
102+
int main() {
103+
test(); // run self-test implementations
104+
return 0;
105+
}

0 commit comments

Comments
 (0)