对于一组数据,通常可以用多项式来拟合,当然对于有周期规律的数据,我们也可以用傅里叶级数来拟合。
傅里叶级数公式形式如下:
当我们确定好n之后,关键就是求出A0、an、bn和w即可。
由于有待求系数在非线性函数cos和sin中,我们用非线性最优化方法来求解。
matlab代码如下:
clear all;close all;clc; n=7; %傅里叶级数的阶数 x = (0:0.1:5)'; y = x - x.^2+ 10*cos(2*x).*sin(x)+5*cos(2*x); %构造一个模型 % y = [zeros(25,1);ones(26,1)]; %试试阶跃 plot(x,y,'ro') epsilon = 1e-6; epsilon_inv = 1/epsilon; pre=rand(2*n+2,1); for i=1:500 %非线性迭代优化 f0 = func(pre,x,n); g = y - f0; %数值计算雅克比 for k = 1:length(pre) x_ = pre; x_(k) = pre(k) + epsilon; jac(:, k) = (func(x_,x,n) - f0) .* epsilon_inv; end J = jac; delta = inv(J'*J + eye(2*n+2))*J'* g; pcur = pre+delta; if norm(delta) <1e-16 break; end pre = pcur; end hold on; x=0:0.01:5; plot(x,func(pre,x,n),'g.'); legend('待拟合数据','傅里叶拟合结果') function y=func(a,x,n) %傅里叶级数函数 y=a(1); for i=1:n y= y + a(i*2)*cos(i*x*a(end)) + a(i*2+1)*sin(i*x*a(end)); end end
结果如下:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
感兴趣的朋友还可以和多项式拟合比较一下,下面是和6阶做的对比,代码我就不贴了,明显傅里叶拟合效果更好些(当然,如果多项式堆阶数效果应该也还可以)。