2022-08-25 16:37:27 +08:00
|
|
|
|
static double domega(const double* const xn, const unsigned int n, const unsigned int k, const double x);
|
2022-08-25 15:55:52 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 拉格朗日插值算法。
|
2022-08-25 16:00:29 +08:00
|
|
|
|
* 算法说明:https://blacktea.vip.cpolar.top/OrgLion-Writes/NotePublic/src/branch/master/Algorithm/DSP/拉格朗日插值.md
|
2022-08-25 15:55:52 +08:00
|
|
|
|
*
|
|
|
|
|
* @param xn 输入:已知采样点的 x 坐标。
|
|
|
|
|
* @param yn 输入:已知采样点的 y 坐标。
|
|
|
|
|
* @param n 输入:采样点数。
|
|
|
|
|
* @param x 输入:插值点 x 坐标。
|
|
|
|
|
* @return double 输出:插值点的 y 坐标值。
|
|
|
|
|
*/
|
2022-08-25 16:37:27 +08:00
|
|
|
|
double Lagrange(const double* const xn, const double* const yn, const unsigned int n, const double x) {
|
2022-08-25 15:55:52 +08:00
|
|
|
|
unsigned int i;
|
|
|
|
|
double l = 0.0;
|
|
|
|
|
|
|
|
|
|
for (i=0; i<n; i++)
|
|
|
|
|
l += yn[i]*domega(xn, n, i, x);
|
|
|
|
|
|
|
|
|
|
return l;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-25 16:37:27 +08:00
|
|
|
|
static double domega(const double* const xn, const unsigned int n, const unsigned int k, const double x) {
|
2022-08-25 15:55:52 +08:00
|
|
|
|
unsigned int i;
|
|
|
|
|
double omega=1.0;
|
|
|
|
|
double omega_deri = 1.0;
|
|
|
|
|
|
|
|
|
|
for (i=0; i<n; i++) {
|
|
|
|
|
if (i==k)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
omega *= (x-xn[i]);
|
|
|
|
|
omega_deri *= (xn[k] - xn[i]);
|
|
|
|
|
}
|
|
|
|
|
return omega/omega_deri;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Demo */
|
|
|
|
|
static double Xn[] = {0, 0.3000, 0.6000, 0.9000, 1.2000, 1.5000, 1.8000, 2.1000, 2.4000, 2.7000, 3.0000};
|
|
|
|
|
static double Yn[] = {2.0000, 2.3780, 3.9440, 7.3460, 13.2320, 22.2500, 35.0480, 52.2740, 74.5760, 102.6020, 137.0000};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 拉格朗日插值示例。
|
|
|
|
|
*
|
|
|
|
|
* @return int
|
|
|
|
|
*/
|
|
|
|
|
int main(void) {
|
|
|
|
|
double out = 0.0;
|
|
|
|
|
out = Lagrange(Xn, Yn, 11, 1.5);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|