主页 > 办公自动化 > 三次样条插值函数求得以后,怎么算出具体的点

三次样条插值函数求得以后,怎么算出具体的点

2023-01-02 17:27来源:m.sf1369.com作者:宇宇

一、三次样条插值函数求得以后,怎么算出具体的点

已知速度曲线v(t) 上的四个数据点下表所示

基本原理:

利用插值(即求过已知有限个数据点的近似函数)的基本原理,用多项式作为研究插值的工具,进行代数插值.其基本问题是:已知函数f (x)在区间[a,b]上n +1个不同点x0,…,xn处的函数值 (i = 0,1,…,n),求一个至多n 次多项式 ψn(x)

使其在给定点处与 f (x)同值,即满足插值条件: ψn(x)= = .

许多工程技术中提出的计算问题对插值函数的光滑性有较高要求,如飞机的机翼外

形,内燃机的进、排气门的凸轮曲线,都要求曲线具有较高的光滑程度,不仅要连续,

而且要有连续的曲率,这就导致了样条插值的产生.

数学上将具有一定光滑性的分段多项式称为样条函数.具体地说,给定区间[a,b]

的一个分划

Δ:

如果函数s(x) 满足:

(i)在每个小区间[ ](i=0,1,…,n)上s(x)是k 次多项式;

(ii)s(x)在[a,b]上具有k −1阶连续导数.

则称s(x)为关于分划Δ 的k 次样条函数,其图形称为k 次样条曲线.

基本思路:

根据插值的基本原理,先对v进行三次样条插值,可以得到许多v(t)的值;然后根据积分的基本原理,分割、近似、求和、取极限,可以求得积分.根据求导原理,因变量的微小变化量与自变量变化量的商,可以求得所求点的导数值.

程序代码:

t0=[0.15 0.16 0.17 0.18];v0=[3.5 1.5 2.5 2.8];

t=0.15:0.0001:0.18;

%三次样条插值;

v=interp1(t0,v0,t,'spline');

v=spline(t0,v0,t);

pp=csape(t0,v0,'second');v=ppval(pp,t)% 使用csape函数;

S=sum(v)*0.0001;%求积分值

T=(v(301)-v(300))/0.0001;%求导数值

Plot(t0,v0,’*’,t,v);

二、样条插值函数会发生龙格现象吗

样条插值的次数只有三次,应该不会发生龙格现象吧

三、样条插值函数在插值节点处的光滑度是什么意思

分段插值: 通常可能指的是直接分段低次线插, 通俗来说 这样出来的线条不是很平滑. 因为在节点上不一定可导.直接hermite插值就和一楼说的差不多三次样条与分段 Hermite 插值的根本区别在于S(x)自身光滑(考虑了二阶倒数),不需要知道 f 的导数值(除了在2个端点可能需要);而Hermite插值依赖于f 在所有插值点的导数值。(S(x)为插值基函数,f为你要插值的函数)

四、求助:求三次样条插值函数的C++程序

#include<iostream>

#include<iomanip>

using namespace std;

const int MAX = 50;

float x[MAX], y[MAX], h[MAX];

float c[MAX], a[MAX], fxym[MAX];

float f(int x1, int x2, int x3){

float a = (y[x3] - y[x2]) / (x[x3] - x[x2]);

float b = (y[x2] - y[x1]) / (x[x2] - x[x1]);

return (a - b)/(x[x3] - x[x1]);

} //求差分

void cal_m(int n){ //用追赶法求解出弯矩向量M……

float B[MAX];

B[0] = c[0] / 2;

for(int i = 1; i < n; i++)

B[i] = c[i] / (2 - a[i]*B[i-1]);

fxym[0] = fxym[0] / 2;

for(i = 1; i <= n; i++)

fxym[i] = (fxym[i] - a[i]*fxym[i-1]) / (2 - a[i]*B[i-1]);

for(i = n-1; i >= 0; i--)

fxym[i] = fxym[i] - B[i]*fxym[i+1];

}

void printout(int n);

int main(){

int n,i; char ch;

do{

cout<<Please put in the number of the dots:;

cin>>n;

for(i = 0; i <= n; i++){

cout<<Please put in X<<i<<':';

cin>>x[i]; //cout<<endl;

cout<<Please put in Y<<i<<':';

cin>>y[i]; //cout<<endl;

}

for(i = 0; i < n; i++) //求 步长

h[i] = x[i+1] - x[i];

cout<<Please 输入边界条件\n 1: 已知两端的一阶导数\n 2:两端的二阶导数已知\n 默认:自然边界条件\n;

int t;

float f0, f1;

cin>>t;

switch(t){

case 1:cout<<Please put in Y0\' Y<<n<<\'\n;

cin>>f0>>f1;

c[0] = 1; a[n] = 1;

fxym[0] = 6*((y[1] - y[0]) / (x[1] - x[0]) - f0) / h[0];

fxym[n] = 6*(f1 - (y[n] - y[n-1]) / (x[n] - x[n-1])) / h[n-1];

break;

case 2:cout<<Please put in Y0\ Y<<n<<\\n;

cin>>f0>>f1;

c[0] = a[n] = 0;

fxym[0] = 2*f0; fxym[n] = 2*f1;

break;

default:cout<<不可用\n;//待定

};//switch

for(i = 1; i < n; i++)

fxym[i] = 6 * f(i-1, i, i+1);

for(i = 1; i < n; i++){

a[i] = h[i-1] / (h[i] + h[i-1]);

c[i] = 1 - a[i];

}

a[n] = h[n-1] / (h[n-1] + h[n]);

cal_m(n);

cout<<\n输出三次样条插值函数:\n;

printout(n);

cout<<Do you to have anther try ? y/n :;

cin>>ch;

}while(ch == 'y' || ch == 'Y');

return 0;

}

void printout(int n){

cout<<setprecision(6);

for(int i = 0; i < n; i++){

cout<<i+1<<: [<<x[i]<< , <<x[i+1]<<]\n<<\t;

/*

cout<<fxym[i]/(6*h[i])<< * (<<x[i+1]<< - x)^3 + <<<< * (x - <<x[i]<<)^3 +

<<(y[i] - fxym[i]*h[i]*h[i]/6)/h[i]<< * (<<x[i+1]<< - x) +

<<(y[i+1] - fxym[i+1]*h[i]*h[i]/6)/h[i]<<(x - <<x[i]<<)\n;

cout<<endl;*/

float t = fxym[i]/(6*h[i]);

if(t > 0)cout<<t<<*(<<x[i+1]<< - x)^3;

else cout<<-t<<*(x - <<x[i+1]<<)^3;

t = fxym[i+1]/(6*h[i]);

if(t > 0)cout<< + <<t<<*(x - <<x[i]<<)^3;

else cout<< - <<-t<<*(x - <<x[i]<<)^3;

cout<<\n\t;

t = (y[i] - fxym[i]*h[i]*h[i]/6)/h[i];

if(t > 0)cout<<+ <<t<<*(<<x[i+1]<< - x);

else cout<<- <<-t<<*(<<x[i+1]<< - x);

t = (y[i+1] - fxym[i+1]*h[i]*h[i]/6)/h[i];

if(t > 0)cout<< + <<t<<*(x - <<x[i]<<);

else cout<< - <<-t<<*(x - <<x[i]<<);

cout<<endl<<endl;

}

cout<<endl;

}

相关推荐

企业办公软件都有哪些?

办公自动化 2024-01-14

数控车床自动编程用什么软件?

办公自动化 2024-01-12

写字间物业管理方案

办公自动化 2023-12-09

自动化的好处和坏处

办公自动化 2023-12-05

单片机有什么特征?

办公自动化 2023-11-27

excel2007教程|excel2007教程下载

办公自动化 2023-11-22