• 自建的离散傅里叶变换matlab程序实现及其与matlab自带函数比较举例


    自建的离散傅里叶变换matlab程序实现及其与matlab自带函数比较举例

    matlab中有自带的离散傅里叶变换程序,即fft程序,但该程序是封装的,无法看到源码。为了比较清楚的了解matlab自带的实现过程,本文通过自建程序实现matlab程序,并与matlab自带的fft进行比较计算。

    一、离散傅里叶变换的计算公式

    在计算离散傅里叶变换的时候,通常会用到:
    { X ( k ) = ∑ n = 1 N [ x ( n ) ⋅ exp ⁡ ( − i ⋅ 2 π ( k − 1 ) ( n − 1 ) N ) ] s . t . { 1 ≤ k ≤ N } (1) \left\{

    X(k)=n=1N[x(n)exp(i2π(k1)(n1)N)]s.t.{1kN}" role="presentation">X(k)=n=1N[x(n)exp(i2π(k1)(n1)N)]s.t.{1kN}
    \right. \tag1 X(k)=n=1N[x(n)exp(i2πN(k1)(n1))]s.t.{1kN}(1)进行求解。
    但有时会遇到所求解的向量长度N和变换过程中的长度K,大小不同。此时,会遇到 N ≤ K N\le K NK的情况,和N>K的两种情况。

    (1) 当 N ≤ K N\le K NK时,则需要对向量 x x x补零后,再离散傅里叶变换计算。计算公式为:

    { X ( k ) = ∑ n = 1 N p a d d e d [ x ( n ) ⋅ exp ⁡ ( − i ⋅ 2 π ( k − 1 ) ( n − 1 ) N p a d d e d ) ] s . t . { 1 ≤ k ≤ N p a d d e d } (2) \left\{

    X(k)=n=1Npadded[x(n)exp(i2π(k1)(n1)Npadded)]s.t.{1kNpadded}" role="presentation">X(k)=n=1Npadded[x(n)exp(i2π(k1)(n1)Npadded)]s.t.{1kNpadded}
    \right. \tag2 X(k)=n=1Npadded[x(n)exp(i2πNpadded(k1)(n1))]s.t.{1kNpadded}(2)
    易知: N ≤ N p a d d e d = K N \le {N_{padded}}=K NNpadded=K.

    (2) 当N>K时,,则需要对向量 x x x截断后,再离散傅里叶变换计算。计算公式为:

    { X ( k ) = ∑ n = 1 N t r u n c a t e d [ x ( n ) ⋅ exp ⁡ ( − i ⋅ 2 π ( k − 1 ) ( n − 1 ) N t r u n c a t e d ) ] s . t . { 1 ≤ k ≤ N t r u n c a t e d } (3) \left\{

    X(k)=n=1Ntruncated[x(n)exp(i2π(k1)(n1)Ntruncated)]s.t.{1kNtruncated}" role="presentation">X(k)=n=1Ntruncated[x(n)exp(i2π(k1)(n1)Ntruncated)]s.t.{1kNtruncated}
    \right. \tag3 X(k)=n=1Ntruncated[x(n)exp(i2πNtruncated(k1)(n1))]s.t.{1kNtruncated}(3)
    易知: N > N t r u n c a t e d = K N > {N_{truncated}}=K N>Ntruncated=K.

    二、基于上述理论编写myfft函数(matlab编程)

    将自建的离散傅里叶变换的函数命名为myfft,编写程序如下:

    function X=myfft(x,K)
    % myfft函数根据傅里叶变换公式编写的离散傅里叶变换程序
    % 输入
    %     x:向量x
    %     K: 变换后的向量X的长度
    
    % 输出
    %    X: 经过傅里叶变换得到的向量
    
    % 变换依据:
    % 对于长度为N的输入向量x,其离散傅里叶变换是长度为N的向量X,其具有元素:
    %                    N
    %      X(k) =       sum  x(n)*exp(-j*2*pi*(k-1)*(n-1)/N), 1 <= k <= N.
    %                   n=1
    %  myfft(x,K) 是一个K点的FFT,如果x小于K点,则补零后进行傅里叶变换;如果x大于K点,则截断后傅里叶变换。
    
    %  by zddh and zsm
    %  2023.10.24
    
    N=length(x)
    
    %% 1.如果x小于K点,补零运算
    if N<=K
        x_padded=[x,zeros(1,K-N)];   %补零
        N_padded=length(x_padded);   %补零后的长度
        X=zeros(1,N_padded);         
    for k=1:K
        for n=1:N_padded
        temp1=x_padded(n)*exp(-i*2*pi*(k-1)*(n-1)/N_padded);
        X(k)=X(k)+temp1;
        end
    end
    %% 2.如果x大于K点,则截断计算
    else
       warning('K值小于N,则截断后进行傅里叶变换')
    x_truncated=x(1:K);
    N_truncated=length(x_truncated);
    X=zeros(1,N_truncated)
    for k=1:K
        for n=1:N_truncated
        temp2=x_truncated(n)*exp(-i*2*pi*(k-1)*(n-1)/N_truncated);
        X(k)=X(k)+temp2;
        end
    end
    end
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    三、自建的函数和matlab自带函数比较举例

    (1) 编写程序

    clc
    clear all
    close all
    %% 1.构造将要变换的向量
    dt=0.1
    t=0:dt:10*pi;
    x=sin(t)
    N=length(x);
    figure(1)
    plot(t,x,'lineWidth',2)
    
    %% 2.自建的离散傅里叶变换求解
    K=200
    X=myfft(x,K)
    %% 3.matlab自带函数求解
    X0=fft(x,K)
    
    
    %% 4.比较
    D_value=X-X0;
    
    figure(2)
    subplot(211)
    plot(abs(X),'LineWidth',2)
    hold on
    plot(abs(X0),'LineWidth',2)
    legend('myfft','matlabfft')
    title('自建myfft和matlab自带函数fft比较')
    
    subplot(212)
    plot(abs(D_value),'LineWidth',2)
    title('|X-X0|')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    (2)运行结果

    图1 生成的x向量
    图1 生成的x向量

    图2 使用两种方法结果比较
    图2 使用两种方法结果
    通过对图2两个子图观察比较可知,本文所编写的myfft函数和matlab自带的fft函数之间的误差非常小,在 1 0 − 12 10^{-12} 1012量级,同时验证了程序的理论公式(1)、(2)和(3).

  • 相关阅读:
    Kotlin语法学习(四)_空指针检查
    按键中断实验
    使用C语言实现循环单链表(带头节点)
    Vue3.0(八):网络请求库axios
    手把手入门Egg.js
    C 嵌入式系统设计模式 20:队列模式
    【Linux系列】深入理解 CURL 命令及其在网络请求中的应用
    成人本科毕业论文怎么写?分享自己的经验
    想要精通算法和SQL的成长之路 - 全排列
    .Net 6 WebAPI 使用JWT进行 授权认证配置
  • 原文地址:https://blog.csdn.net/qq_18937049/article/details/134020078