⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decimate.m

📁 有关matlab的电子书籍有一定的帮助希望有用
💻 M
字号:
function odata = decimate(idata,r,nfilt,option)
%DECIMATE Resample data at a lower rate after lowpass filtering.
%   Y = DECIMATE(X,R) resamples the sequence in vector X at 1/R times the 
%   original sample rate.  The resulting resampled vector Y is R times shorter,
%   LENGTH(Y) = LENGTH(X)/R.
%   DECIMATE filters the data with an eighth order Chebyshev type I lowpass 
%   filter with cutoff frequency .8*(Fs/2)/R, before resampling.
%   Y = DECIMATE(X,R,N) uses an N'th order Chebyshev filter.
%   Y = DECIMATE(X,R,'FIR') uses the 30 point FIR filter generated by 
%   FIR1(30,1/R) to filter the data.
%   Y = DECIMATE(X,R,N,'FIR') uses the N-point FIR filter.
%
%   Note: For large R, the Chebyshev filter design might be incorrect
%   due to numeric precision limitations.  In this case, DECIMATE will
%   use a lower filter order.  For better anti-aliasing performance, try 
%   breaking R up into its factors and calling DECIMATE several times.
%
%   See also INTERP, RESAMPLE.

%   Author(s): L. Shure, 6-4-87
%              L. Shure, 12-11-88, revised
%   Copyright (c) 1988-98 by The MathWorks, Inc.
%   $Revision: 1.10 $  $Date: 1997/12/02 19:16:50 $

%   References:
%    [1] "Programs for Digital Signal Processing", IEEE Press
%         John Wiley & Sons, 1979, Chap. 8.3.

if nargin < 2
   error('Not enough input arguments.')
end
if abs(r-fix(r)) > eps
   error('Resampling rate R must be a positive integer.')
end
if fix(r) == 1
	odata = idata;
	return
end
if r <= 0
	error('Resampling rate R must be a positive integer.')
end
fopt = 1;
if nargin == 2
	nfilt = 8;
else
	if isstr(nfilt)
		if nfilt(1) == 'f' | nfilt(1) == 'F'
			fopt = 0;
		elseif nfilt(1) == 'i' | nfilt(1) == 'I'
			fopt = 1;
		else
			error('Filter options are FIR and IIR.')
		end
		if nargin == 4
			nfilt = option;
		else
			nfilt = 8*fopt + 30*(1-fopt);
		end
	else
		if nargin == 4
			if option(1) == 'f' | option(1) == 'F'
				fopt = 0;
			elseif option(1) == 'i' | option(1) == 'I'
				fopt = 1;
			else
				error('Filter options are FIR and IIR.')
			end
		end
	end
end
if fopt == 1 & nfilt > 13
	disp('Warning: IIR filters above order 13 may be unreliable.')
end

nd = length(idata);
m = size(idata,1);
nout = ceil(nd/r);

if fopt == 0	% FIR filter
	b = fir1(nfilt,1/r);
% prepend sequence with mirror image of first points so that transients
% can be eliminated. then do same thing at right end of data sequence.
	nfilt = nfilt+1;
	itemp = 2*idata(1) - idata((nfilt+1):-1:2);
	[itemp,zi]=filter(b,1,itemp);
	[odata,zf] = filter(b,1,idata,zi);
	if m == 1	% row data
		itemp = zeros(1,2*nfilt);
	else	% column data
		itemp = zeros(2*nfilt,1);
	end
	itemp(:) = [2*idata(nd)-idata((nd-1):-1:(nd-2*nfilt))];
	itemp = filter(b,1,itemp,zf);
% finally, select only every r'th point from the interior of the lowpass
% filtered sequence
	gd = grpdelay(b,1,8);
	list = round(gd(1)+1.25):r:nd;
	odata = odata(list);
	lod = length(odata);
	nlen = nout - lod;
	nbeg = r - (nd - list(length(list)));
	if m == 1	% row data
		odata = [odata itemp(nbeg:r:nbeg+nlen*r-1)];
	else
		odata = [odata; itemp(nbeg:r:nbeg+nlen*r-1)];
	end
else	% IIR filter
	rip = .05;	% passband ripple in dB
	[b,a] = cheby1(nfilt, rip, .8/r);
	while (abs(filtmag_db(b,a,.8/r)+rip)>1e-6) 
		nfilt = nfilt - 1;
		if nfilt == 0
			break
		end
		[b,a] = cheby1(nfilt, rip, .8/r);
	end
	if nfilt == 0
error('Bad Chebyshev design, likely R is too big; try mult. decimation (R=R1*R2).')
	end
        
% be sure to filter in both directions to make sure the filtered data has zero phase
% make a data vector properly pre- and ap- pended to filter forwards and back
% so end effects can be obliterated.
	odata = filtfilt(b,a,idata);
	nbeg = r - (r*nout - nd);
	odata = odata(nbeg:r:nd);
end

function H = filtmag_db(b,a,f)
%FILTMAG_DB Find filter's magnitude response in decibels at given frequency.

nb = length(b);
na = length(a);
top = exp(-j*(0:nb-1)*pi*f)*b(:);
bot = exp(-j*(0:na-1)*pi*f)*a(:);

H = 20*log10(abs(top/bot));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -