spectral derivative using fft()

Ben Abbott bpabbott at mac.com
Mon Dec 17 18:01:35 CST 2007


On Dec 17, 2007, at 5:39 PM, Gastón Araguás wrote:

> hi,
>
> I want to implement an spectral derivative using fft() and ifft().
> Theoretically it can be done scaling the fft coefficients by the
> factor  (2 pi i w)^n, where n is the derivate order, and applying the
> ifft() to them.
> It is, the derivative of a function f_j(x_j) can be obtained by
> derivation of it's spectral representation, so if we have
>
> f_j = sum_{w=-M} ^{M} e^{2 pi i w j} ftilde(w)
>
> with j = 0, ..., 2M, then the f'_j can be obtained by
>
> f'_j = ( 2 pi i w )*sum_{w=-M} ^{M} e^{2 pi i w j} ftilde(w)
>
> in terms of the fft() and ifft() functions it should be:
> f'_j = ifft( ( 2 pi i w ) * fft( f_j ) )
> with w = -M, ..., M
>
> but it doesn't gives the correct result. I suspect that the problem is
> in the order of the returned fft() coefficients.
> I found that the coef. ftilde(w) are stored in this way:
> [ftilde(0) ftilde(1) ...   ftilde(M-1/2) ftilde(M+1/2) ftilde(-M+1/2)
> ... ftilde(-1)] = fft(f_j)
> or, defining N = 2M+1 it holds
> [ftilde(0) ftilde(1) ...   ftilde(N/2-1) ftilde(N/2) ftilde(-N/2+1)
> ... ftilde(-1)] = fft(f_j)
> is that ok?
>
> Here is my test code (it works ok with this simple function y =
> cos(2*pi*x), but not for example with y = x + cos(2*pi*x) ) :
> N = 2^7;
> h = 1/N;
> x = [0:N-1]*h;
> y = cos(2*pi*x);
> figure; plot (real(y));
> Y = fft( y , N );
> M = (N-1)/2;
> W = (2*pi*i)*[0:M-1/2 0 -M+1/2:-1];
> Y2 = W.*Y;
> y2 = ifft( Y2 );
> figure; plot (real(y2));
> pause;
>
> i hope someone can help, thanks in advanced
> Gastón

At 1st glance, I noticed a problem. You used the following to  
represent the derivative of "f" (I've modified it slightly).

	fp = ifft ( ( 2i * pi  * m ) * fft( f ) );

which is correct for continuous signals with infinite limits (Fourier  
Transform). However, for FFT's the signals are discrete & periodic  
(Discrete Fourier Transforms). So the derivative must be periodic as  
well. I haven't gone through all the details, but the result should  
look something like

	fp = 1i *  ifft ( sin ( 2 * pi * m ) .* fft ( f ) );

I'm likely off by some scale factor, but you get the idea, yes?

Ben


More information about the Help-octave mailing list