快速傅里叶变换 算法与实现

强烈推荐李家同教授
Communications engineering essentials for computer scientists and electrical engineers
一书

该部分关于离散傅里叶变换的讲解是我目前见过最好的
讲得十分清楚,严谨又不过分深入
直觉和物理动机也很明确
对于工程应用完全足够

书籍下载地址
https://wwe.lanzoui.com/iQDrpwh0mgh
快速傅里叶变换的算法原理
在书本的74-75页

function fft_seq = fft_my(input_seq)
%% 此函数用于某个采样点序列的计算快速傅里叶变换
% 输入参数:
% 输入采样点序列: input_seq 
% 
% 输出参数:
% 输入序列的快速傅里叶变换: fft_seq

    num = length(input_seq); % 输入序列的长度
    % 判断输入序列的点数,如果不是2的n次幂,就输出错误信息
    if (log2(num) ~= floor(log2(num)))
        error('输入点数不是2的n次幂,无法进行快速傅里叶变换');
    end
    
    fft_seq = zeros(1,num);

    
    input_odd = input_seq(1:2:num)'; %输入序列的半个序列
    input_even = input_seq(2:2:num)';
    
    C = zeros(1,length(input_odd));
    B = C;
    
    omega_n = exp(-1j*2*pi/num);
    omega_half_n = exp(-1j*4*pi/num);
    
    base_vec = omega_half_n * ones(1, length(input_odd)); 
   
    % 计算快速傅里叶变换的代码
    %如果序列只有两个值
     if (num == 2)
         fft_seq(1) = input_seq(1) + input_seq(2);
         fft_seq(2) = input_seq(1) - input_seq(2);
         
     else
         % 计算分治向量 B C
         for i = 1:length(input_odd)
             
             if (i~=1)
                 step = i-1;
                 power_vec = (0: step: (num-2) *step/2);
                 inner_vec = base_vec.^power_vec;
                 B(i) = inner_vec * input_odd;
                 C(i) = inner_vec * input_even;
             
             else
                 B(i) =   ones(1, length(input_odd)) * input_odd;
                 C(i) =   ones(1, length(input_even)) * input_even;
             
             end
             
         end                  
                           
         for i = 1:(num/2)
             fft_seq(i) = B(i) + omega_n^(i-1) * C(i);
             fft_seq(i+num/2) = B(i) + omega_n^(num/2+i-1) * C(i);
            
             
         end
     end
     

     
end

你可能感兴趣的:(马特拉布,算法)