0、插值的概念
简单来讲插值就是定义一个在特定点取给定值的函数的过程。
1、解决的问题

已知函数在某些点上的函数值,要求得一个函数使其通过这些点,或进一步确定在其他点的函数值。即由给定的几个初始点,能够把其余的点求出来,从而拟合成一条光滑的曲线。
2、插值的定义:
设 在 上有定义, 是 上的 个互异点,且 在这些点上的函数值为 。若存在 ,使 , 则称 为 的插值函数。
这时有人就懵了,既然知道 ,那为什么还要求 ,这不是多此一举吗?原因如下:
- 可能我们不知道
,只知道它上面的一些点,这时需要来估计 ; 本身太复杂,希望找到一个更方便计算的函数 。
称为被插值函数, 称为插值函数 称为插值区间 称为插值条件- 求
的方法称为插值法
一、拉格朗日插值法
1、定理:
当插值节点互异时,且节点数目为 ,则满足插值条件的 次插值多项式存在且唯一。
即有
2、线性插值(n=1)
已知插值节点为 ,且 在其上的函数值为 。求 ,使 .
为过 的直线
,这很容易的出来,详细过程不多说了。
将 记为 , 记为 ,则有
称 , 为基函数。
3、抛物线插值(n=2)
求 ,使 。那么
设 ,其中
, 满足插值条件。
先求 ,设 又由 ,将A的值回代得 ,
同理可得: , 
3、拉格朗日插值多项式
定理:满足插值条件 的 次拉格朗日插值多项式为:
,其中 
特殊的:n=1为线性插值,n=2为抛物线插值。
下面是我自己写的C++代码
C++代码为:
#include<iostream>
#include<vector>
#include"Larange.h"
using namespace std;
int main()
{
double x[] = { 0, 3, 5, 7, 9, 11, 12, 13, 14, 15 };
double y[] = { 0, 1.2, 1.7, 2.0, 2.1, 2.0, 1.8, 1.2, 1.0, 1.6 };
int length = sizeof(x) / sizeof(x[0]);
vector<double> arrX, arrY;
for (int i = 0; i < length; i++) {
arrX.push_back(x[i]);
arrY.push_back(y[i]);
}
int length1 = arrX.size();
double X;
cout << "请输入待求解的插值点的X值,待解X = " ;
cin >> X;
cout << endl;
double result = Larange(arrX, arrY, length, X);
cout << "lagrange法求得的X对应的函数值为,y = " << result << endl;
cout << "Hello World !" << endl;
}
头文件 的代码,也就是拉格朗日算法实现部分代码为:
#pragma once
#include<vector>
using namespace std;
double Larange(vector<double> &arrX, vector<double> &arrY, int &length, double &X) {
double yResult = 0; //计算结果初始化
vector<double> LResult; //将每个基函数存储起来
for (int i = 0; i < length; i++) {
double Molecule = 1.0; //分子累乘积
double Denominator = 1.0; //分母累乘积
for (int j = 0; j < length; j++) {
if (i == j)
continue; // i!=j
Molecule *= (X - arrX[j]);
Denominator *= (arrX[i] - arrX[j]);
}
double L = Molecule / Denominator;
LResult.push_back(L);
}
for (int i = 0; i < length; i++) {
yResult += arrY[i] * LResult[i];
}
return yResult;
}
关于matlab的拉格朗日算法代码,由于matlab中有它的函数,所以不再多说了。 |