function [Bm,Am,FIR]=sos2delparf_ls(SOS,G,NLS); %SOS2DELPARF_LS converts the series SOS form to delayed parallel SOS form. % [Bm,Am,FIR]=SOS2DELPARF_LS(B,A,NLS) converts the series second-order form % defined in the matrix SOS and gain G to delayed parallel second-order sections % described by Bm and Am, plus a parallel FIR part, if the order of % B(z) is larger than the order of A(z). % % The parameters are computed by a least-squares fit to match the impulse response % of the original filter, instead of partial fraction expansion. This procedure % is robust even for large (>100) filter orders. % % The NLS parameter sets the length of the impulse fit. % % The SOS matrix is defined as used by the TF2SOS and ZP2SOS commands: % SOS = [ b01 b11 b21 1 a11 a21 % b02 b12 b22 1 a12 a22 % ... % b0L b1L b2L 1 a1L a2L ] % And G is the optional series gain coefficient. % % The Bm and Am matrices contain the [b0 b1]' and [1 a0 a1]' % coefficients for the different sections in their columns. For example, % Bm(:,3) gives the [b0 b1]' parameters of the third second-order % section. These can be used by the filter command separatelly (e.g., by % y=filter(Bm(:,3),Am(:,3),x), or by the DELPARFILT command. % % Note that if there is an FIR part, then the IIR part must be delayed by % the length (order+1) of the FIR filter when this form is implemented. % % Also, remember that converting a transfer function to parallel second-order % is not possible if there is pole mulitplicity. % % For the details, see: % % Balázs Bank, "Converting IIR filters to parallel form," IEEE Signal Processing % Magazine, Tips and tricks, 2018. % % http://www.mit.bme.hu/~bank/parconv % % C. Balazs Bank, 2017-2018. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % computing the impulse response of the direct-form filter if nargin < 3, % if NLS is not specified NLS=2*length(B); end; if nargin < 2, % if G is not specified G=1; end; % computing the impulse response of the series implementation imp=zeros(1,NLS); imp(1)=1; serresp=imp*G; NSEC=size(SOS,1); % numer of second-order sections for k=1:NSEC, serresp=filter(SOS(k,1:3),SOS(k,4:6),serresp); end; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % preparing the target for the LS fit NFIR=1; % FIR part order is always 1 in the series to parallel case parfresp=serresp(NFIR+1:end); % the part modeled by the parallel filter L=length(parfresp); imp=zeros(L,1); imp(1)=1; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %constructing the modeling signal matrix for k=1:NSEC, resp=filter(1,SOS(k,4:6),imp); %impluse response of the denominator M(:,2*k-1)=resp; M(:,2*k)=[0 ;resp(1:L-1)]; %the response delayed by one sample end; y=parfresp(:); %making the target a column vector %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Looking for min(||y-M*par||) as a function of par by the LS fit par=M\y; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % constructing the Bm and Am matrices for k=1:NSEC, Am(:,k)=SOS(k,4:6).'; % denominators are the same as for the series case Bm(:,k)=par(2*k-1:2*k); % numerators from the LS fit end; FIR=0; % the FIR part is simply the first NFIR samples of the impulse response if NFIR>0, FIR=serresp(1:NFIR); end;