function [Bm,Am,FIR]=rpk2parf(r,p,k); %RPK2PARF converts the partial fraction form to parallel SOS form. % [Bm,Am,FIR]=RPK2PARF(r,p,k) converts the partial fraction form % computed by RESIDUE, RESIDUEZ, or RESIDUED to parallel second-order filters. % The Bm and Am parameters are computed from the residues r and poles p % which are paired as complex conjugate pairs. The FIR part simply equals the % direct terms FIR=k; % % The Bm and Am matrices are containing 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 PARFILT or DELPARFILT command. % (The same function is used for normal and delayed parallel filters.) % % Also, remember that converting a transfer function to parallel second-order % is not possible if there is pole mulitplicity. % % For details, see: % % Balázs Bank and Julius O. Smith, III, "A delayed parallel filter structure % with an FIR part having improved numerical properties", 136th AES % Convention, Preprint No. 9084, Berlin, April 2014. % % http://www.mit.bme.hu/~bank/delparf % % C. Balazs Bank, 2014. psorted=cplxpair(p); % arrange into complex polepairs rsorted=zeros(size(r)); for n=1:length(p), [val,ind]=min(abs(p-psorted(n))); % find the nearest original pole to the sorted one rsorted(n)=r(ind); % copy the corresponding residue end; p=psorted; r=rsorted; for s=1:floor(length(p)/2), [Btmp,Atmp]=residuez(r(s*2-1:s*2),p(s*2-1:s*2),[]); Bm(:,s)=real(Btmp).'; Am(:,s)=real(Atmp).'; end; if mod(length(p),2)>0, % so there is a first order filter [Btmp,Atmp]=residuez(r(s*2+1),p(s*2+1),[]); Bm(1,s+1)=real(Btmp).'; Bm(2,s+1)=0; Am(1:2,s+1)=real(Atmp).'; Am(3,s+1)=0; end; FIR=k;