如何用MATLAB计算傅里叶系数

时间:2013-02-22 16:28:28

标签: fft matlab

我正在尝试使用MATLAB计算波形的傅里叶系数。可以使用以下公式计算系数:

enter image description here

enter image description here

选择T为1,得到ω= 2pi。

但是我在执行积分方面遇到了问题。函数是三角波(如果我没有误,可以使用sawtooth(t,0.5)生成)以及方波。

我尝试过以下代码(对于三角波):

    function [ a0,am,bm ] = test( numTerms )
            b_m = zeros(1,numTerms);
            w=2*pi;
            for i = 1:numTerms
                    f1 = @(t) sawtooth(t,0.5).*cos(i*w*t);
                    f2 = @(t) sawtooth(t,0.5).*sin(i*w*t);
                    am(i) = 2*quad(f1,0,1);
                    bm(i) = 2*quad(f2,0,1);
            end
    end

然而,它并没有达到我所需的价值附近。 b_m系数给出a  当m是从正项开始的奇数交替时,三角波应该是1 / m ^ 2和-1 / m ^ 2。

对我来说,主要问题是我不太明白积分在MATLAB中是如何工作的,我不确定我选择的方法是否有效。

编辑: 为了肯定,这是我想要在确定系数时编写函数的形式:

enter image description here

以下是使用fft的尝试:

    function [ a0,am,bm ] = test( numTerms )
            T=2*pi;
            w=1;
            t = [0:0.1:2];
            f = fft(sawtooth(t,0.5));
            am = real(f);
            bm = imag(f);
            func = num2str(f(1));
            for i = 1:numTerms
                    func = strcat(func,'+',num2str(am(i)),'*cos(',num2str(i*w),'*t)','+',num2str(bm(i)),'*sin(',num2str(i*w),'*t)');
            end
            y = inline(func);
            plot(t,y(t));
    end

2 个答案:

答案 0 :(得分:3)

在我看来,您的问题是sawtooth返回mathworks documentation所说的问题:

  

锯齿(t,width)生成一个修正的三角波,其中宽度(标量参数在0和1之间)确定最大值出现的0到2π之间的点。函数在0到2π宽度的区间从-1增加到1,然后在2π宽度的区间内从1到-1线性减小到2π。因此,参数0.5指定标准三角波,关于时间瞬间π对称,峰 - 峰幅度为1.锯齿(t,1)等效于锯齿(t)。

所以我猜你问题的部分

在你做出回应之后,我进一步研究了它。在我看来它是quad函数;不太准确!我重新解决了这个问题:

    function [ a0,am,bm ] = sotest( t, numTerms )
      bm = zeros(1,numTerms);
      am = zeros(1,numTerms);
      % 2L = 1
      L = 0.5;
      for ii = 1:numTerms
        am(ii) = (1/L)*quadl(@(x) aCos(x,ii,L),0,2*L);
        bm(ii) = (1/L)*quadl(@(x) aSin(x,ii,L),0,2*L);
      end
      ii = 0;
      a0 = (1/L)*trapz( t, t.*cos((ii*pi*t)/L) );  
      % now let's test it
      y = ones(size(t))*(a0/2);
      for ii=1:numTerms
        y = y + am(ii)*cos(ii*2*pi*t);
        y = y + bm(ii)*sin(ii*2*pi*t);
      end
      figure; plot( t, y);
    end

    function a = aCos(t,n,L)
      a = t.*cos((n*pi*t)/L);
    end

    function b = aSin(t,n,L)
      b = t.*sin((n*pi*t)/L);
    end

然后我称之为:

[ a0,am,bm ] = sotest( t, 100 );

我得到了:

Fourier Series

甜度!!!

我真正改变的是从quadquadl.我通过使用trapz来解决这个问题,直到我使用的时间向量没有足够的分辨率,我相信这是一个数字问题,而不是一些基本问题。希望这有帮助!

答案 1 :(得分:0)

要对代码进行故障排除,我会绘制您正在使用的函数并调查,四元函数如何对它们进行采样。您可能正在对它们进行欠采样,因此请确保最小步长小于函数周期至少10倍。

我建议使用内置于Matlab的FFT。 FFT不仅是计算频谱的最有效方法(它是n * log(n),取决于数组的长度n,而n ^ 2中的积分依赖),它还会自动为您提供频率点您的(等间隔)时间数据支持。如果您自己计算积分(如果数据点不是等间距则可能需要),您可能会计算未解析的频率数据(在时间间隔上的间距小于1 /,即超出“傅立叶极限”)。