[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Secrets FFTs revealed!!



Peter Brooker wrote:
>
  <snip>
> 
> Divide the interval into N sections. t~t_i = i*T/N
> Then,
> f( t_i ) = sum_n(A_n*exp(j*2*pi*n*t_i/T))
>           = sum_n(A_n*exp(j*2*pi*n*i*(T/N)/T))
>           = sum_n( A_n*exp(j*2*pi*n*i/N) ) , n=0,1,...
> 
> This is exactly what is found in the IDL manual under the section for
> FFT. The only difference is that t has been replaced by u and A_n has
> been replaced by F(u). Note that the period T has dropped out. Also note
> that  t has been replaced by t_i = i*T/N. In order for this to happen,
> the interval over which t is defined must be from [0,T]. This is
> different from the definition of t being defined over the interval
> [-T/2,T/2]. Perhaps this is why b_n = -bb_n.
> 
> ********UNFORTUNATELY IT IS WRONG****************
> 
> What is wrong is the values of n in the sum. IDL does not use the values
> of n=0,1,2,... IDL actually uses n= -N/2+1, -N/2+2, ...-1,0,1,...,N/2
> The reason for doing this must have to do with FFT theory. Note also
> that the number of values of n is N.

Great job on the ref but I have always found it hard to read ASCII
equations. :o)

The input to the FFT should include BOTH the positive and negative
frequencies. So if you have a function of N+1 points, then you want to
supply the FFT with 2N points (or if you have a function of N/2 + 1
points you supply it with N points. The "+1"th point is the Nyquist
point.

Say you have the following real function (e.g. an interferogram):

           ZPD         Nyquist point
            |               |
            |      +ve      |
            |<---optical--->|
            |     delays    |
            V               |
                            |
            |               |
            |               |
            ||    |         V
            |||  |||  ||     
            |||||||||||||||||
            |||  |||  ||     
            ||    |
            |
            |

where ZPD == zero path difference. If you want to FFT this function to a
spectrum, the input to the FFT should be:

           ZPD         Nyquist point
            |               |
            |      +ve      |      -ve
            |<---optical--->|<---optical--->
            |     delays    |     delays
            V               |
                            |
            |               |
            |               |
            ||    |         V         |    |
            |||  |||  ||         ||  |||  ||
            ||||||||||||||||||||||||||||||||
            |||  |||  ||         ||  |||  ||
            ||    |                   |    |
            |
            |

where the function values at negative optical delays are simply the
reflected positive ones. Note that neither the Nyquist point nor the ZPD
point is reflected - the reflection occurs *around* the Nyquist point.
The ZPD (or zero frequency point) is unique and the Nyquist point is
ambiguous, i.e. it contains both +ve and -ve frequency info.

The IDL FFT documentation mentions the storage of the negative
frequencies. It's just that given a real function (e.g. something
measured), one simply repeats the +ve frequency values into -ve
frequencies.

So, I don't think the documentation is wrong but the most I would be
willing to bet is a beer or two (due to my lack of understanding, not
RSI's).

Here a section of the header to my fft_to_interferogram.pro mentioning
the reflection. Check out the input/output array sizes in the example
section:


; PROCEDURE:
;       The input spectrum is reflected about it highest frequency
;       (largest wavenumber). The spectrum is FFT'd and the
;       resultant interval is scaled by the input spectrum wavenumber
;       interval.
;
;       The interferogram is then shifted so that the ZPD occurs at the
;       centre (like a measured IFG) and the redundant most negative
;       Nyquist point is placed at the end of the interferogram array.
;
; EXAMPLE:
;       Given a spectrum:
;
;         IDL> HELP, spc, v
;         SPC             FLOAT     = Array[12445]
;         V               FLOAT     = Array[12445]
; 
;       The Fourier transform can be found by typing:
;
;         IDL> PRINT, fft_to_interferogram( spc, v, ifg, opd )
;                1
;
;       resulting in an interferogram and optical delay grid:
;
;         IDL> HELP, ifg, opd
;         IFG             DOUBLE    = Array[24889]
;         OPD             DOUBLE    = Array[24889]
;

and here's the code snippet that actually does the reflection, FFT'ing.
Take note of the bounds of the REVERSE'd protion of "spectrum" - no zero
frequency (point 0) and no Nyquist frequency (point n_spectrum_pts-1)
reflection:

;------------------------------------------------------------------------------
;                -- Fourier transform the input spectrum --
;------------------------------------------------------------------------------

; --------------------
; Reflect the spectrum
; --------------------

  spectrum_to_fft = TEMPORARY( [ spectrum, REVERSE( spectrum[ 1:
n_spectrum_pts - 2 ] ) ] )


; ----------------
; FFT the spectrum
; ----------------

  interferogram = FFT( TEMPORARY( spectrum_to_fft ), /DOUBLE, /INVERSE )


cheers,

paulv
-- 
Paul van Delst           Ph:  (301) 763-8000 x7274 
CIMSS @ NOAA/NCEP        Fax: (301) 763-8545
Rm.202, 5200 Auth Rd.    Email: pvandelst@ncep.noaa.gov
Camp Springs MD 20746