source: MML/trunk/machine/SOLEIL/common/toolbox/ezyfit/ezyfit/ezfft.m @ 4

Last change on this file since 4 was 4, checked in by zhangj, 10 years ago

Initial import--MML version from SOLEIL@2013

File size: 6.2 KB
Line 
1function [w,e] = ezfft(varargin)
2%EZFFT  Easy to use Power Spectrum
3%   EZFFT(T,U) plots the power spectrum of the signal U(T) , where T is a
4%   'time' and U is a real signal (T can be considered as a space
5%   coordinate as well). If T is a scalar, then it is interpreted as the
6%   'sampling time' of the signal U.  If T is a vector, then it is
7%   interpreted as the 'time' itself. In this latter case, T must be
8%   equally spaced (as obtained by LINSPACE for instance), and it must
9%   have the same length as U. If T is not specified, then a 'sampling
10%   time' of unity (1 second for instance) is taken. Windowing
11%   (appodization) can be applied to reduce border effects (see below).
12%
13%   [W,E] = EZFFT(T,U) returns the power spectrum E(W), where E is the
14%   energy density and W the pulsation 'omega'.  W is *NOT* the frequency:
15%   the frequency is W/(2*pi). If T is considered as a space coordinate,
16%   W is a wave number (usually noted K = 2*PI/LAMBDA, where LAMBDA is a
17%   wavelength).
18%
19%   EZFFT(..., 'Property1', 'Property2', ...) specifies the properties:
20%    'hann'    applies a Hann appodization window to the data (reduces
21%              aliasing).
22%    'disp'    displays the spectrum (by default if no output argument)
23%    'freq'    the frequency f is displayed instead of the pulsation omega
24%              (this applies for the display only: the output argument
25%              remains the pulsation omega, not the frequency f).
26%    'space'   the time series is considered as a space series. This simply
27%              renames the label 'omega' by 'k' (wave number) in the plot,
28%              but has no influence on the computation itself.
29%    'handle'  returns a handle H instead of [W,E] - it works only if the
30%              properties 'disp' is also specified. The handle H is useful
31%              to change the line properties (color, thickness) of the
32%              plot (see the example below).
33%
34%   The length of the vectors W and E is N/2, where N is the length of U
35%   (this is because U is assumed to be a real signal.) If N is odd, the
36%   last point of U and T are ignored. If U is not real, only its real part
37%   is considered.
38%
39%       W(1) is always 0.  E(1) is the energy density of the average of U
40%         (when plotted in log coordinates, the first point is W(2), E(2)).
41%       W(2) is the increment of pulsation, Delta W, given by 2*PI/Tmax
42%       W(end), the highest measurable pulsation, is PI/DT, where DT is the
43%          sampling time (Nyquist theorem).
44%
45%   Parseval Theorem (Energy conservation):
46%   For every signal U, the 'energy' computed in the time domain and in the
47%   frequency domain are equal,
48%       MEAN(U.^2) == SUM(E)*W(2)
49%   where W(2) is the pulsation increment Delta W.
50%   Note that, depending on the situation considered, the physical 'energy'
51%   is usually defined as 0.5*MEAN(U.^2). Energy conservation only applies
52%   if no appodization of the signal (windowing) is used. Otherwise, some
53%   energy is lost in  the appodization, so the spectral energy is lower
54%   than the actual one.
55%
56%   As for FFT, the execution time depends on the length of the signal.
57%   It is fastest for powers of two.
58%
59%   Example 1:  simple display of a power spectrum
60%      t = linspace(0,400,2000);
61%      u = 0.2 + 0.7*sin(2*pi*t/47) + cos(2*pi*t/11);
62%      ezfft(t,u);
63%
64%   Example 2:  how to change the color of the plot
65%      h = ezfft(t,u,'disp','handle');
66%      set(h,'Color','red');
67%
68%   Example 3:  how to use the output of ezfft
69%      [w,e] = ezfft(t,u,'hann');
70%      loglog(w,e,'b*');
71%
72%   See also FFT
73
74
75%   F. Moisy, moisy_at_fast.u-psud.fr
76%   Revision: 1.01,  Date: 2008/11/20
77%   This function is part of the EzyFit Toolbox
78
79
80% History:
81% 2008/11/19: v1.00, first version.
82% 2008/11/20: v1.01, includes property 'space'. Help text improved
83
84
85error(nargchk(1,inf,nargin));
86
87if nargin==1
88    u=varargin{1};
89    dt=1;
90else
91    dt=varargin{1};
92    u=varargin{2};
93end
94
95if length(dt)>1
96    if length(u)~=length(dt)
97        error('Vectors T and U should be of equal length.');
98    end
99    dt = abs(dt(2)-dt(1));
100end
101
102% works only with vectors of even length
103if mod(length(u),2)~=0;
104    u=u(1:(end-1));
105end
106
107u=real(u);
108
109% works with line vector (otherwise transpose it)
110if size(u,2)==1
111    u=u';
112end
113
114% signal appodization with a Hann window
115if any(strcmpi(varargin,'hann'))
116    u=u.*hann(length(u))';
117end
118
119n = length(u)/2;  % length of the output fft (half the signal length)
120w = linspace(0,pi,n)/dt;   % output pulsation
121
122e = abs(fft(u)).^2;   % power spectrum
123e = 2*e(1:n) / (2*n)^2 / w(2);  % normalisation
124e(1)=e(1)/2;    % mode w=0 was counted twice is the previous line
125
126% display
127if nargout==0 || any(strncmpi(varargin,'disp',1))
128    if any(strncmpi(varargin,'freq',1)) && any(strncmpi(varargin,'space',1))
129        error('Properties ''freq'' and ''space'' cannot be specified simultaneously');
130    elseif any(strncmpi(varargin,'freq',1)) && ~any(strncmpi(varargin,'space',1))
131        hh=loglog(w/(2*pi),2*pi*e);
132        xlabel('f = \omega / 2\pi');
133        ylabel('E(f)');
134    elseif ~any(strncmpi(varargin,'freq',1)) && any(strncmpi(varargin,'space',1))
135        hh=loglog(w,e);
136        xlabel('k');
137        ylabel('E(k)');
138    else
139        hh=loglog(w,e);
140        xlabel('\omega');
141        ylabel('E(\omega)');
142    end
143end
144
145% output
146if nargout>0 && any(strncmpi(varargin,'handle',4)) && any(strncmpi(varargin,'disp',1))
147    w=hh;
148    clear e
149    return
150end
151
152if nargout==0
153    clear w e
154end
155
156
157function y=hann(n)
158%HANN  Window Hann function
159%   Y = HANN(N) returns a N-point Hann function (usually N is a power of
160%   2), ie a discretization of Y(X) = (1 - COS (2*PI*X))/2.
161%
162%   The HANN function is used to window (apodize) finite samples of signal
163%   in order to avoid high frequency oscillations in Fourier transform.
164%
165%   Example:  plot(hann(128));
166%
167%   F. Moisy
168%   Revision: 1.03,  Date: 2006/03/03
169%
170%   See also FFT.
171
172% History:
173% 2004/09/17: v1.00, first version.
174% 2005/23/02: v1.01, cosmetics
175% 2005/09/03: v1.02, id.
176% 2006/03/03: v1.03, bug fixed 0:n-1
177
178error(nargchk(1,1,nargin));
179y=0.5*(1-cos(2*pi*(0:n-1)/(n-1)))';
180
Note: See TracBrowser for help on using the repository browser.