What is numpy.fft.rfft and numpy.fft.irfft and its equivalent code in MATLAB

前端 未结 1 928
无人共我
无人共我 2021-01-03 10:33

I am converting a python code into MATLAB and one of the code uses numpy rfft. In the documentation of numpy, it says real input.

Compute the one-dime

相关标签:
1条回答
  • 2021-01-03 11:29

    The real FFT in numpy uses the fact that the fourier transform of a real valued function is so to say "skew-symmetric", that is the value at frequency k is the complex conjugate of the value at frequency N-k for k=1..N-1 (the correct term is Hermitian). Therefore rfft returns only the part of the result that corresponds to nonpositive frequences.

    For an input of size N the rfft function returns the part of the FFT output corresponding to frequences at or below N/2. Therefore the output of rfft is of size N/2+1 if N is even (all frequences from 0 to N/2), or (N+1)/2 if N is odd (all frequences from 0 to (N-1)/2). Observe that the function floor(n/2+1) returns the correct output size for both even and odd input sizes.

    So to reproduce rfft in matlab

    function rfft = rfft(a)
         ffta = fft(a);
         rfft = ffta(1:(floor(length(ffta)/2)+1));
    end
    

    For example

    a = [1,1,1,1,-1,-1,-1,-1];
    rffta = rfft(a)
    

    would produce

    rffta =
    
     Columns 1 through 3:
    
       0.00000 + 0.00000i   2.00000 - 4.82843i   0.00000 + 0.00000i   
    
     Columns 4 through 5:
    
       2.00000 - 0.82843i   0.00000 + 0.00000i
    

    Now compare that with python

    >>> np.fft.rfft(a)
    array([ 0.+0.j        ,  2.-4.82842712j,  0.-0.j        ,  
            2.-0.82842712j,  0.+0.j        ])
    

    Reproducing irfft

    To reproduce basic functionality of irfft you need to recover the missing frequences from rfft output. If the desired output length is even, the output length can be computed from the input length as 2 (m - 1). Otherwise it should be 2 (m - 1) + 1.

    The following code would work.

    function irfft = irfft(x,even=true)
         n = 0; % the output length
         s = 0; % the variable that will hold the index of the highest
                % frequency below N/2, s = floor((n+1)/2)
         if (even)
            n = 2 * (length(x) - 1 );
            s = length(x) - 1;
         else
            n = 2 * (length(x) - 1 )+1;
            s = length(x);
         endif
         xn = zeros(1,n);
         xn(1:length(x)) = x;
         xn(length(x)+1:n) = conj(x(s:-1:2));
         irfft  = ifft(xn);
    end
    

    Now you should have

    >> irfft(rfft(a))
    ans =
    
       1.00000   1.00000   1.00000   1.00000  -1.00000  -1.00000  -1.00000  -1.00000
    

    and also

    abs( irfft(rfft(a)) - a ) < 1e-15
    

    For odd output length you get

    >> irfft(rfft(a(1:7)),even=false)
    ans =
    
       1.0000   1.0000   1.0000   1.0000  -1.0000  -1.0000  -1.0000
    
    0 讨论(0)
提交回复
热议问题