www.gusucode.com > Matlab动力系统和时间序列分析工具箱 > Matlab动力系统和时间序列分析工具箱/lab432/toolbox/time_frec_distribution.m
function varargout = time_frec_distribution(varargin) % time_frec_distribution creates time-frecuency distribution of time series % [tfd,t,f]=time_frec_distribution(x,giu_mode,method,param); % Parameters: % x - data vector or structure with fields % .data - data vector % .time - time vector % gui_mode - 'gui' or 'silent' (no gui) % method - % 1 - Born-Jordan distribution % 2 - Binomial distribution % 3 - quasi-Wigner distribution % 4 - Levin distribution % 5 - Rihaczek distribution % 6 - Page distribution % 7 - Margenau-Hill distribution % 8 - Spectrogram % 9 - Short-time Fourier Transform % For methods 1-3 param is a length of rectangular lag window on the autocorr. function (even) % For methods 4-7 no parameters required % For methods 8-9 param is a duration of gaussian window (odd) % % Based on DiscreteTFD % Jeffrey O'Neill <jeffo@bu.edu> % 8 St. Mary's Street % Boston, MA 02135 % Last Modified by GUIDE v2.5 22-Oct-2004 17:03:50 % last modified 8.01.04 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @time_frec_distribution_OpeningFcn, ... 'gui_OutputFcn', @time_frec_distribution_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT % --- Executes just before time_frec_distribution is made visible. function time_frec_distribution_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to time_frec_distribution (see VARARGIN) % Choose default command line output for time_frec_distribution global tfdDATA handles.output = hObject; guidata(hObject, handles); set(hObject,'name','Time-frequency distribution '); set([handles.t_fsw handles.e_l_fsw],'visible','off'); if isempty(varargin) error('Not enought input parameters'); end if isa(varargin{1},'struct') tfdDATA.data=varargin{1}; else tfdDATA.data.data=varargin{1}; tfdDATA.data.time=1:length(varargin{1}); end if rem(length(tfdDATA.data.data),2)==0 set(handles.e_l_tsw,'string',num2str(length(tfdDATA.data.data))); else set(handles.e_l_tsw,'string',num2str(length(tfdDATA.data.data)-1)); end if length(varargin)>1 if strcmp(varargin{2},'gui')|strcmp(varargin{2},'silent') tfdDATA.gui_mode=varargin{2}; else warning('Wrong value of ''gui_mode'' parameter. ''gui_mode'' set to ''gui'''); tfdDATA.gui_mode='gui'; end else tfdDATA.gui_mode='gui'; end tfdDATA.autocalc=0; if length(varargin)>2 set(handles.method,'value',varargin{3}); end if length(varargin)>=3 switch varargin{3} % method case {1,2,3} set([handles.t_fsw handles.e_l_fsw],'visible','off'); set([handles.t_tsw handles.t_l_tsw handles.e_l_tsw ],'visible','on'); if length(varargin)>3 tfdDATA.autocalc=1; set(handles.e_l_tsw,'string',num2str(varargin{4})); end case {4,5,6,7} set([handles.t_fsw handles.e_l_fsw],'visible','off'); set([handles.t_tsw handles.t_l_tsw handles.e_l_tsw ],'visible','off'); tfdDATA.autocalc=1; case {8,9} set([handles.t_fsw handles.e_l_fsw],'visible','on'); set([handles.t_tsw handles.t_l_tsw handles.e_l_tsw ],'visible','off'); if length(varargin)>3 tfdDATA.autocalc=1; set(handles.e_l_fsw,'string',num2str(varargin{4})); end end end % UIWAIT makes time_frec_distribution wait for user response (see UIRESUME) % uiwait(handles.figure1); % --- Outputs from this function are returned to the command line. function varargout = time_frec_distribution_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure global tfdDATA tfdOUT if tfdDATA.autocalc compute_Callback(handles.compute, [], handles); varargout{1} =tfdOUT.tfd; varargout{2} =tfdOUT.t; varargout{3} =tfdOUT.f; if strcmp(tfdDATA.gui_mode,'silent') try close(handles.figure); catch end end else uiwait; try varargout{1} =tfdOUT.tfd; varargout{2} =tfdOUT.t; varargout{3} =tfdOUT.f; catch end end % --- Executes on button press in cancel. function cancel_Callback(hObject, eventdata, handles) % hObject handle to cancel (see GCBO) % handles structure with handles and user data (see GUIDATA) close(gcf); % --- Executes on button press in compute. function compute_Callback(hObject, eventdata, handles) % hObject handle to compute (see GCBO) % handles structure with handles and user data (see GUIDATA) global tfdDATA tfdOUT I=get(handles.method,'value'); w=str2num(get(handles.e_l_fsw,'string')); wlen=str2num(get(handles.e_l_tsw,'string')); Dt=diff(tfdDATA.data.time); if max(Dt-mean(Dt))>1e-10 warndlg('Time instants is not equally spaced. Frequency scale is wrong.','Warning'); end fs=1/Dt(1); nfreq=length(tfdDATA.data.data); switch I case 1 [tfd, t, f] = born_jordan2(tfdDATA.data.data, fs, nfreq, wlen); case 2 [tfd, t, f] = binomial2(tfdDATA.data.data, fs, nfreq, wlen); case 3 [tfd, t, f] = qwigner2(tfdDATA.data.data, fs, nfreq, wlen); case 4 [tfd, t, f] = levin2(tfdDATA.data.data, fs, nfreq); case 5 [tfd, t, f] = rihaczek2(tfdDATA.data.data, fs, nfreq); case 6 [tfd, t, f] = page2(tfdDATA.data.data, fs, nfreq); case 7 [tfd, t, f] = margenau_hill2(tfdDATA.data.data, fs, nfreq); case 8 [tfd,t,f] = spec2(tfdDATA.data.data,fs,nfreq,1,w,'short'); case 9 [tfd,t,f] = stft2(tfdDATA.data.data,fs,nfreq,1,w,'short'); end tfdOUT.tfd=tfd; tfdOUT.t=t; tfdOUT.f=f; if strcmp(tfdDATA.gui_mode, 'gui') axes(handles.ax); colormap('jet'); if get(handles.las,'Value') ptfd(tfd, t, f, 8); else ptfddb(tfd, 25,t, f, 8) end end % --- Executes during object creation, after setting all properties. function e_l_fsw_CreateFcn(hObject, eventdata, handles) % hObject handle to e_l_fsw (see GCBO) % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc set(hObject,'BackgroundColor','white'); else set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end set(hObject,'string',num2str(5)); function e_l_fsw_Callback(hObject, eventdata, handles) % hObject handle to e_l_fsw (see GCBO) % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of e_l_fsw as text % str2double(get(hObject,'String')) returns contents of e_l_fsw as a double % --- Executes during object creation, after setting all properties. function e_l_tsw_CreateFcn(hObject, eventdata, handles) % hObject handle to e_l_tsw (see GCBO) % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. % global tfdDATA if ispc set(hObject,'BackgroundColor','white'); else set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end function e_l_tsw_Callback(hObject, eventdata, handles) % hObject handle to e_l_tsw (see GCBO) % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of e_l_tsw as text % str2double(get(hObject,'String')) returns contents of e_l_tsw as a double % --- Executes during object creation, after setting all properties. function method_CreateFcn(hObject, eventdata, handles) % hObject handle to method (see GCBO) % handles empty - handles not created until after all CreateFcns called % Hint: popupmenu controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc set(hObject,'BackgroundColor','white'); else set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end str='Born-Jordan distribution'; % 1 str=[str '|Binomial distribution']; % 2 str=[str '|quasi-Wigner distribution']; % 3 str=[str '|Levin distribution']; % 4 str=[str '|Rihaczek distribution']; % 5 str=[str '|Page distribution']; % 6 str=[str '|Margenau-Hill distribution']; % 7 str=[str '|Spectrogram']; % 8 str=[str '|Short-time Fourier Transform']; % 9 set(hObject,'string',str); % --- Executes on selection change in method. function method_Callback(hObject, eventdata, handles) % hObject handle to method (see GCBO) % handles structure with handles and user data (see GUIDATA) % Hints: contents = get(hObject,'String') returns method contents as cell array % contents{get(hObject,'Value')} returns selected item from method I=get(hObject,'value'); switch I case {1,2,3} set([handles.t_fsw handles.e_l_fsw],'visible','off'); set([handles.t_tsw handles.t_l_tsw handles.e_l_tsw ],'visible','on'); case {4,5,6,7} set([handles.t_fsw handles.e_l_fsw],'visible','off'); set([handles.t_tsw handles.t_l_tsw handles.e_l_tsw ],'visible','off'); case {8,9} set([handles.t_fsw handles.e_l_fsw],'visible','on'); set([handles.t_tsw handles.t_l_tsw handles.e_l_tsw ],'visible','off'); end % --- Executes on button press in das. function das_Callback(hObject, eventdata, handles) % hObject handle to das (see GCBO) % handles structure with handles and user data (see GUIDATA) % Hint: get(hObject,'Value') returns toggle state of das set(hObject,'Value',1); set(handles.las,'value',~get(hObject,'Value')); % --- Executes on button press in las. function las_Callback(hObject, eventdata, handles) % hObject handle to las (see GCBO) % handles structure with handles and user data (see GUIDATA) % Hint: get(hObject,'Value') returns toggle state of las set(hObject,'Value',1); set(handles.das,'value',~get(hObject,'Value')); %%% DiscreteTFD's functions (Type2,(3): discrete and aperiodic; continuous and periodic) %%% % Copyright (C) 1997, 1998, 1999 Jeffrey C. O'Neill % Copyright (C) 1998, 1999 Boston University % Copyright (C) 1997, 1998 L'Ecole Normale Superieure de Lyon % Copyright (C) 1997 The Regents of the University of Michigan % All Rights Reserved % % Jeffrey O'Neill <jeffo@bu.edu> % 8 St. Mary's Street % Boston, MA 02135 % % This program is free software; you can redistribute it and/or % modify it under the terms of the GNU General Public License % as published by the Free Software Foundation; either version 2 % of the License, or (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. function [tfd, t, f] = binomial2(x, fs, nfreq, wlen) % binomial2 -- Compute samples of the type II binomial distribution. % % Usage % [tfd, t, f] = binomial2(x, fs, nfreq, wlen) % % Inputs % x signal vector % fs sampling frequency of x (optional, default is 1 sample/second) % nfreq number of samples to compute in frequency (optional, default % is twice the length of x) % wlen length of the rectangular lag window on the auto-correlation % function, must be less than or equal to nfreq (optional, default % is twice the length of x) % % Outputs % tfd matrix containing the binomial distribution of signal x. If x has % length N, then tfd will be nfreq by N. (optional) % t vector of sampling times (optional) % f vector of frequency values (optional) % Copyright (C) -- see DiscreteTFDs/Copyright % specify defaults x = x(:); N = length(x); error(nargchk(1, 4, nargin)); if (nargin < 4) wlen = 2*N; end if (nargin < 3) nfreq = 2*N; end if (nargin < 2) fs = 1; end if (nfreq < wlen) error('rectangular lag window must be less than or equal to data length!'); end if (wlen > N) error('rectangular lag window must be less than or equal to the length of the signal!'); end w = wlen/2; % make the binomial kernel %%%%%%%%%%%%%%%%%%%%%%%%%%%% ker = zeros(w); ker(1,1) = 1; for tau = 2:w, temp = ker(tau-1,1:tau-1); ker(tau,1:tau) = ([0 temp] + [temp 0])/2; end % Do the computations. %%%%%%%%%%%%%%%%%%%%%% % make the acf for positive tau acf = lacf2(x, w); % convolve with the kernel acf2 = fft(acf.'); ker = [ker zeros(w,N-w)]; ker2 = fft(ker.'); gacf = ifft(acf2.*ker2); gacf = gacf.'; % make the gacf for negative lags gacf = [gacf ; zeros(nfreq-wlen+1,N) ; conj(flipud(gacf(2:w,:)))]; %compute the tfd tfd = real(fft(gacf)); tfd = tfdshift(tfd)/nfreq; t = 1/fs * (0:N-1); f = -fs/2:fs/nfreq:fs/2; f = f(1:nfreq); function [tfd, t, f] = born_jordan2(x, fs, nfreq, wlen) % born_jordan2 -- Compute samples of the type II Born_Jordan distribution. % % Usage % [tfd, t, f] = born_jordan2(x, fs, nfreq, wlen) % % Inputs % x signal vector % fs sampling frequency of x (optional, default is 1 sample/second) % nfreq number of samples to compute in frequency (optional, default % is twice the length of x) % wlen length of the rectangular lag window on the auto-correlation % function, must be less than or equal to nfreq (optional, default % is twice the length of x) % % Outputs % tfd matrix containing the Born_Jordan distribution of signal x. If x has % length N, then tfd will be nfreq by N. (optional) % t vector of sampling times (optional) % f vector of frequency values (optional) % Copyright (C) -- see DiscreeTFDs/Copyright % specify defaults x = x(:); N = length(x); error(nargchk(1, 4, nargin)); if (nargin < 4) wlen = 2*N; end if (nargin < 3) nfreq = 2*N; end if (nargin < 2) fs = 1; end if (nfreq < wlen) error('rectangular lag window must be less than or equal to data length!'); end if (wlen > N) error('rectangular lag window must be less than or equal to the length of the signal!'); end w = wlen/2; % make the born jordan kernel %%%%%%%%%%%%%%%%%%%%%%%%%%%% ker = zeros(w); for tau = 1:w, ker(tau,1:tau) = ones(1,tau)/tau; end % Do the computations. %%%%%%%%%%%%%%%%%%%%%% % make the acf for positive tau acf = lacf2(x, w); % convolve with the kernel acf2 = fft(acf.'); ker = [ker zeros(w,N-w)]; ker2 = fft(ker.'); gacf = ifft(acf2.*ker2); gacf = gacf.'; % make the gacf for negative lags gacf = [gacf ; zeros(nfreq-wlen+1,N) ; conj(flipud(gacf(2:w,:)))]; %compute the tfd tfd = real(fft(gacf)); tfd = tfdshift(tfd)/nfreq; t = 1/fs * (0:N-1); f = -fs/2:fs/nfreq:fs/2; f = f(1:nfreq); function lacf = lacf2(x, mlag) % lacf2 -- Compute samples of the type II local acf. % % Usage % lacf = lacf2(x, mlag) % % Inputs % x signal vector % mlag maximum lag to compute. must be <= length(x). % (optional, defaults to length(x)) % % Outputs % lacf matrix containing the lacf of signal x. If x has % length N, then lacf will be nfreq by N. (optional) % % This function has a tricky sampling scheme, so be careful if you use it. % Copyright (C) -- see DiscreteTFDs/Copyright % specify defaults x = x(:); N = length(x); error(nargchk(1, 2, nargin)); if (nargin < 2) mlag = N; end if (mlag > N) error('mlag must be <= length(x)') end % make the acf for positive tau lacf = zeros(mlag, N); for t=1:N mtau = min(mlag, N-t+1); lacf(1:mtau, t) = conj(x(t))*x(t:t+mtau-1); end function [tfd, t, f] = levin2(x, fs, nfreq) % levin2 -- Compute samples of the type II Levin distribution. % % Usage % [tfd, t, f] = levin2(x, fs, nfreq) % % Inputs % x signal vector % fs sampling frequency of x (optional, default is 1 sample/second) % nfreq number of samples to compute in frequency (optional, default % is twice the length of x) % % Outputs % tfd matrix containing the binomial distribution of signal x. If x has % length N, then tfd will be nfreq by N. (optional) % t vector of sampling times (optional) % f vector of frequency values (optional) % Copyright (C) -- see DiscreteTFDs/Copyright % specify defaults x = x(:); N = length(x); error(nargchk(1, 3, nargin)); if (nargin < 3) nfreq = 2*N; end if (nargin < 2) fs = 1; end % make the acf for positive tau gacf = zeros(N); for t=1:N; gacf(1:t,t) = conj(x(t)) * x(t:-1:1); end % negative tau gacf = [gacf ; zeros(nfreq-2*N+1,N) ; conj(flipud(gacf(2:N,:)))]; %compute the tfd tfd = real(fft(gacf)); tfd = tfdshift(tfd)/nfreq; t = 1/fs * (0:N-1); f = -fs/2:fs/nfreq:fs/2; f = f(1:nfreq); function [tfd, t, f] = margenau_hill2(x, fs, nfreq); % margenau_hill2 -- Compute samples of the type II Margenau-Hill % distribution. % % Usage % [tfd, t, f] = margenau_hill2(x, fs, nfreq) % % Inputs % x signal vector % fs sampling frequency of x (optional, default is 1 sample/second) % nfreq number of samples to compute in frequency (optional, default % is the length of x) % % Outputs % tfd matrix containing the Margenau-Hill distribution of signal x. % If x has length N, then tfd will be nfreq by N. (optional) % t vector of sampling times (optional) % f vector of frequency values (optional) % Copyright (C) -- see DiscreteTFDs/Copyright error(nargchk(1, 3, nargin)); if (nargin == 1) [tfd, t, f] = rihaczek1(x); elseif (nargin == 2) [tfd, t, f] = rihaczek1(x, fs); elseif (nargin == 3) [tfd, t, f] = rihaczek1(x, fs, nfreq); end tfd = real(tfd); function [tfd, t, f] = page2(x, fs, nfreq) % page2 -- Compute samples of the type II Page distribution. % % Usage % [tfd, t, f] = page2(x, fs, nfreq) % % Inputs % x signal vector % fs sampling frequency of x (optional, default is 1 sample/second) % nfreq number of samples to compute in frequency (optional, default % is twice the length of x) % % Outputs % tfd matrix containing the binomial distribution of signal x. If x has % length N, then tfd will be nfreq by N. (optional) % t vector of sampling times (optional) % f vector of frequency values (optional) % Copyright (C) -- see DiscreteTFDs/Copyright % specify defaults x = x(:); N = length(x); error(nargchk(1, 3, nargin)); if (nargin < 3) nfreq = 2*N; end if (nargin < 2) fs = 1; end % positive tau acf = zeros(N); for t=1:N; gacf(1:N-t+1,t) = x(t) * conj(x(t:N)); end % negative tau gacf = [gacf ; zeros(nfreq-2*N+1,N) ; conj(flipud(gacf(2:N,:)))]; %compute the tfd tfd = real(fft(gacf)); tfd = tfdshift(tfd)/nfreq; t = 1/fs * (0:N-1); f = -fs/2:fs/nfreq:fs/2; f = f(1:nfreq); function [tfd, t, f] = qwigner2(x, fs, nfreq, wlen) % qwigner2 -- Compute samples of the type II quasi-Wigner distribution. % % Usage % [tfd, t, f] = qwigner2(x, fs, nfreq, wlen) % % Inputs % x signal vector % fs sampling frequency of x (optional, default is 1 sample/second) % nfreq number of samples to compute in frequency (optional, default % is twice the length of x) % wlen length of the rectangular lag window on the auto-correlation % function, must be less than or equal to nfreq (optional, default % is twice the length of x) % % Outputs % tfd matrix containing the quasi-Wigner distribution of signal x. If x % has length N, then tfd will be nfreq by N. (optional) % t vector of sampling times (optional) % f vector of frequency values (optional) % % Note that the Wigner distribution does % not exist for type II signals, but the quasi-Wigner distribution is % a reasonable approximation. % Copyright (C) -- see DiscreteTFDs/Copyright % specify defaults x = x(:); N = length(x); error(nargchk(1, 4, nargin)); if (nargin < 4) wlen = 2*N; end if (nargin < 3) nfreq = 2*N; end if (nargin < 2) fs = 1; end if (nfreq < wlen) error('rectangular lag window must be less than or equal to data length!'); end if (wlen > N) error('rectangular lag window must be less than or equal to the length of the signal!'); end w = wlen/2; % make the quasi-wigner kernel %%%%%%%%%%%%%%%%%%%%%%%%%%%% ker = zeros(w); for tau = 1:2:w, ker(tau,(tau+1)/2) = 1; end for tau = 2:2:w; ker(tau,tau/2) = .5; ker(tau,tau/2+1) = .5; end % Do the computations. %%%%%%%%%%%%%%%%%%%%%% % make the acf for positive tau acf = lacf2(x, w); % convolve with the kernel acf2 = fft(acf.'); ker = [ker zeros(w,N-w)]; ker2 = fft(ker.'); gacf = ifft(acf2.*ker2); gacf = gacf.'; % make the gacf for negative lags gacf = [gacf ; zeros(nfreq-wlen+1,N) ; conj(flipud(gacf(2:w,:)))]; %compute the tfd tfd = real(fft(gacf)); tfd = tfdshift(tfd)/nfreq; t = 1/fs * (0:N-1); f = -fs/2:fs/nfreq:fs/2; f = f(1:nfreq); function [tfd, t, f] = rihaczek2(x, fs, nfreq); % rihaczek2 -- Compute samples of the type II Rihaczek distribution. % % Usage % [tfd, t, f] = rihaczek2(x, fs, nfreq) % % Inputs % x signal vector % fs sampling frequency of x (optional, default is 1 sample/second) % nfreq number of samples to compute in frequency (optional, default % is the length of x) % % Outputs % tfd matrix containing the Rihaczek distribution of signal x. If x has % length N, then tfd will be nfreq by N. (optional) % t vector of sampling times (optional) % f vector of frequency values (optional) % Copyright (C) -- see DiscreteTFDs/Copyright error(nargchk(1, 3, nargin)); if (nargin == 1) [tfd, t, f] = rihaczek1(x); elseif (nargin == 2) [tfd, t, f] = rihaczek1(x, fs); elseif (nargin == 3) [tfd, t, f] = rihaczek1(x, fs, nfreq); end function [tfd, t, f] = spec2(x, fs, nfreq, decf, w, how) % spec2 -- Compute samples of the type II spectrogram. % % Usage % [tfd, t, f] = spec2(x, fs, nfreq, decf, w, how) % % Inputs % x signal vector % fs sampling frequency of x (optional, default is 1 sample/second) % nfreq number of samples to compute in frequency (optional, default % is 256) % decf sub-sampling factor in time of the stft (optional, default % is 1, i.e. no sub-sampling) % w if length(w)==1 then the window is a guassian with duration 'w' % (see chirplets.m), otherwise 'w' is the window. 'w' must have an % odd length to have a center point. (optional, default is a % gaussian with a duration of 5) % how if how='short' then the stft is computed for the same times % as the signal and % size(tfd,2) = length(x) % if how='long' then the stft will be computed for times before % and after the times of the signal and % size(tfd,2) = length(x) + length(w) - 1 % (optional, default is 'short') % % Outputs % tfd matrix containing the spectrogram of signal x (optional) % t vector of sampling times (optional) % f vector of frequency values (optional) % Copyright (C) -- see DiscreteTFDs/Copyright error(nargchk(1, 6, nargin)); if (nargin == 1) [tfd, t, f] = stft2(x); elseif (nargin == 2) [tfd, t, f] = stft2(x, fs); elseif (nargin == 3) [tfd, t, f] = stft2(x, fs, nfreq); elseif (nargin == 4) [tfd, t, f] = stft2(x, fs, nfreq, decf); elseif (nargin == 5) [tfd, t, f] = stft2(x, fs, nfreq, decf, w); elseif (nargin == 6) [tfd, t, f] = stft2(x, fs, nfreq, decf, w, how); end tfd = real(tfd.*conj(tfd)); function [tfd, t, f] = stft2(x, fs, nfreq, decf, w, how) % stft2 -- Compute samples of the type II short-time Fourier transform. % % Usage % [tfd, t, f] = stft2(x, fs, nfreq, decf, w, how) % % Inputs % x signal vector % fs sampling frequency of x (optional, default is 1 sample/second) % nfreq number of samples to compute in frequency (optional, default % is 256) % decf sub-sampling factor in time of the stft (optional, default % is 1, i.e. no sub-sampling) % w if length(w)==1 then the window is a guassian with duration 'w' % (see chirplets.m), otherwise 'w' is the window. 'w' must have an % odd length to have a center point. (optional, default is a % gaussian with a duration of 5) % how if how='short' then the stft is computed for the same times % as the signal and % size(tfd,2) = length(x) % if how='long' then the stft will be computed for times before % and after the times of the signal and % size(tfd,2) = length(x) + length(w) - 1 % (optional, default is 'short') % % Outputs % tfd matrix containing the STFT of signal x % t vector of sampling times (optional) % f vector of frequency values (optional) % Copyright (C) -- see DiscreteTFDs/Copyright x = x(:); N=length(x); error(nargchk(1, 6, nargin)); if (nargin < 2) fs = 1; end if (nargin < 3) M = 63; w = chirplets(M,[1 (M+1)/2 0 0 5]); nfreq = 256; end if (nargin < 4) decf = 1; end if (nargin < 5) M = 63; w = chirplets(M,[1 (M+1)/2 0 0 5]); end if (nargin < 6) how = 'short'; end if (length(w)==1) M = 2*round(32*w/5)-1; w = chirplets(M,[1 (M+1)/2 0 0 w]); else w = w(:); M = length(w); end if (round(M/2) == M/2) error('window length must be odd') end if (N <= M) error('the signal must be longer than the window') end % Create a matrix filled with signal values. x = [x; zeros(decf,1)]; % prevents going past the end of the array if (how(1) == 'l') L = ceil((M+N-1)/decf); tfd=zeros(M,L); tfd(M,1)=x(1); for n=2:L, tfd(1:M-decf,n)=tfd(1+decf:M,n-1); t = (n-1)*decf+1; % real time if (t-decf+1 <= N) % we still have new data to add tfd(M-decf+1:M,n) = x(t-decf+1:t); end end else % how == 'short' L = ceil(N/decf); tfd=zeros(M,L); tfd((M+1)/2:M,1)=x(1:(M+1)/2); for n=2:L, tfd(1:M-decf,n)=tfd(1+decf:M,n-1); t = (n-1)*decf+1; % real time if ((M-1)/2+t-decf+1 <= N) tfd(M-decf+1:M,n)=x((M-1)/2+t-decf+1:(M-1)/2+t); end end end % Window the data. w=w*ones(1,L); tfd=tfd.*w; % take care of the case if M > nfreq if (M>nfreq) P = ceil(M/nfreq); tfd = [tfd ; zeros(P*nfreq-M,L)]; tfd = reshape(tfd,nfreq,P,L); tfd = squeeze(sum(tfd,2)); end % Perform the column ffts to get the stft. tfd = fft(tfd, nfreq); tfd = tfdshift(tfd)/sqrt(nfreq); if (how(1) == 'l') t = 1/fs * ((0:N+M-2) - (M-1)/2); t = t(1:decf:end); else t = 1/fs * (0:N-1); t = t(1:decf:end); end f = -fs/2:fs/nfreq:fs/2; f = f(1:nfreq); function ptfd(tfd, t, f, fs) % ptfd -- Display an image plot of a TFD with a linear amplitude scale. % % Usage % ptfd(tfd, t, f, fs) % % Inputs % tfd time-frequency distribution % t vector of sampling times (optional) % f vector of frequency values (optional) % fs font size of axis labels (optional) % Copyright (C) -- see DiscreteTFDs/Copyright error(nargchk(1, 4, nargin)); if (nargin < 4) fs = 10; end if (nargin < 3) f = [-0.5 0.5]; end if (nargin < 2) t = [1 size(tfd,2)]; end if isempty(t) t = [1 size(tfd,2)]; end if isempty(f) f = [-0.5 0.5]; end imagesc(t, f, abs(tfd)), axis('xy'), xlabel('time','FontSize',fs), ylabel('frequency','FontSize',fs), set(gca,'FontSize',fs); function ptfddb(tfd, dbs, t, f, fs) % ptfddb -- Display an image plot of a TFD with a dB amplitude scale. % % Usage % ptfddb(tfd, dbs, t, f, fs) % % Inputs % tfd time-frequency distribution % dbs rabge in dBs (optional, default is 25) % t vector of sampling times (optional) % f vector of frequency values (optional) % fs font size of axis labels (optional) % Copyright (C) -- see DiscreteTFDs/Copyright error(nargchk(1, 5, nargin)); if (nargin < 5) fs = 10; end if (nargin < 4) f = [-0.5 0.5]; end if (nargin < 3) t = [1 size(tfd,2)]; end if (nargin < 2) dbs = 25; end if isempty(t) t = [1 size(tfd,2)]; end if isempty(f) f = [-0.5 0.5]; end tfd=tfd./sum(sum(tfd)); tfd=20*log10(abs(tfd)+eps); tfd = tfd - max(max(tfd)); imagesc(t, f, tfd), axis('xy'), xlabel('time','FontSize',fs), ylabel('frequency','FontSize',fs),set(gca,'FontSize',fs); function [tfd, t, f] = rihaczek1(x, fs, nfreq); % rihaczek1 -- Compute samples of the type I Rihaczek distribution. % % Usage % [tfd, t, f] = rihaczek1(x, fs, nfreq) % % Inputs % x signal vector % fs sampling frequency of x (optional, default is 1 sample/second) % nfreq number of samples to compute in frequency (optional, default % is the length of x) % % Outputs % tfd matrix containing the Rihaczek distribution of signal x. If x has % length N, then tfd will be nfreq by N. (optional) % t vector of sampling times (optional) % f vector of frequency values (optional) % Copyright (C) -- see DiscreteTFDs/Copyright % specify defaults x = x(:); N = length(x); error(nargchk(1, 3, nargin)); if (nargin < 3) nfreq = N; end if (nargin < 2) fs = 1; end X = fft(x,nfreq); tfd = (conj(X) * x.') .* exp(-j*[0:2*pi/nfreq:2*pi*(1-1/nfreq)]'*[0:N-1]); tfd = tfdshift(tfd)/nfreq; t = 1/fs * (0:N-1); f = -fs/2:fs/nfreq:fs/2; f = f(1:nfreq); function out = tfdshift(in) % tfdshift -- Shift the spectrum of a TFD by pi radians. % % Usage % out = tfdshift(in) % % Inputs % in time-frequency distribution % % Outputs % out shifted time-frequency distribution % Copyright (C) -- see DiscreteTFDs/Copyright error(nargchk(1, 1, nargin)); N = size(in, 1); M = ceil(N/2); out = [in(M+1:N,:) ; in(1:M,:)]; function x = chirplets(N, P) % chirplets -- make a signal that is a sum of chirplets % % Usage % x = chirplets(N, P) % % Inputs % N length of signal % P matrix of parameters [amp time freq chirp_rate duration; ...] % (optional, default is [1 N/2+1 0 0 sqrt(N/4/pi)]) % % Outputs % x signal % % d is the standard deviation of the guassian, d=sqrt(N/4/pi) gives an % atom with a circular Wigner distribution, and 2*sqrt(2)*d is the % Rayleigh limit. % % Examples % N=128; x=chirplets(N, [1 N/2+1 0 0 sqrt(N/4/pi)]); % x=chirplets(128, [1 55 0 2*pi/128 12 ; 1 75 0 2*pi/128 12]); % Copyright (C) -- see DiscreteTFDs/Copyright error(nargchk(1,2,nargin)); if (nargin < 2) if (rem(N,2)==0) center = N/2+1; else center = (N+1)/2; end P = [1 center 0 0 sqrt(N/4/pi)]; end if (size(P,2) ~= 5) error('Matrix P has the wrong number of columns.') end x = zeros(N,1); n = (1:N)'; for p = 1:size(P,1), A = P(p,1); t = P(p,2); f = P(p,3); cr = P(p,4); d = P(p,5); am = exp(-((n-t)/2/d).^2) * sqrt(1/sqrt(2*pi)/d); x = x + A * am .* exp(j * (cr/2*(n-t).^2 + f*(n-t))); end