matlab练习程序(傅里叶拟合)

对于一组数据,通常可以用多项式来拟合,当然对于有周期规律的数据,我们也可以用傅里叶级数来拟合。

傅里叶级数公式形式如下:

当我们确定好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阶做的对比,代码我就不贴了,明显傅里叶拟合效果更好些(当然,如果多项式堆阶数效果应该也还可以)。

posted @ 2022-03-12 18:11  Dsp Tian  阅读(4690)  评论(3编辑  收藏  举报