No BSD License  

Highlights from
Inverse Bilinear Transform

from Inverse Bilinear Transform by Paul Eccles
Convert z-domain systems to s-domain.

ibilinear(zd, pd, kd, fs, fp, fp1)
function [z, p, k, d] = ibilinear(zd, pd, kd, fs, fp, fp1)
%IBILINEAR Inverse bilinear transformation with optional frequency
%   prewarping.
%   [Z,P,K] = IBILINEAR(Zd,Pd,Kd,Fs) converts the z-domain transfer
%   function specified by Zd, Pd, and Kd to a s-transform discrete
%   equivalent obtained from the inverse bilinear transformation:
%
%      H(s) = H(z) |
%                  | z = (s+2*Fs)/(s-2*Fs)
%
%   where column vectors Zd and Pd specify the zeros and poles, scalar
%   Kd specifies the gain, and Fs is the sample frequency in Hz.
%   [NUM,DEN] = IBILINEAR(NUMd,DENd,Fs), where NUM and DEN are 
%   row vectors containing numerator and denominator transfer
%   function coefficients, NUM(z)/DEN(z), in descending powers of
%   z, transforms to s-transform coefficients NUM(s)/DEN(s).
%   [A,B,C,D] = IBILINEAR(Ad,Bd,Cd,Dd,Fs) is a state-space version.
%   Each of the above three forms of IBILINEAR accepts an optional
%   additional input argument that specifies prewarping. For example,
%   [Z,P,K] = IBILINEAR(Zd,Pd,Kd,Fs,Fp) applies prewarping before
%   the inverse bilinear transformation so that the frequency responses
%   before and after mapping match exactly at frequency point Fp
%   (match point Fp is specified in Hz).
%
%   See also BILINEAR, IMPINVAR.

%   Author(s): J.N. Little, 4-28-87 
%   	   J.N. Little, 5-5-87, revised
%   Copyright (c) 1988-98 by The MathWorks, Inc.
%   $Revision: 1.1 $  $Date: 1998/06/03 14:41:57 $
%   Gene Franklin, Stanford Univ., motivated the state-space
%   approach to the bilinear transformation.
%
%	 Adapted/plagiarised from BILINEAR.m by Paul Eccles, 2 April 2005


[mn,nn] = size(zd);
[md,nd] = size(pd);

if (nd == 1 & nn < 2) & nargout ~= 4	% In zero-pole-gain form
	if mn > md
		error('Numerator cannot be higher order than denominator.')
	end
	if nargin == 5		% Prewarp
		fp = 2*pi*fp;
		fs = fp/tan(fp/fs/2);
	else
		fs = 2*fs;
   end
   
   % prune extra zeroes. There must be a better way of doing this.
	for i = size(zd):-1:1,
   	if (zd(i) < -0.99) & (zd(i) > -1.01)
         zd = zd(1:(i-1));		% Prune final element.
      else
         break;					% Leave the 'for' loop.
   	end
	end  

	p = fs*(pd-1)./(pd+1);
	z = fs*(zd-1)./(zd+1);
	k = kd*prod((fs)-p)./prod((fs)-z);

elseif (md == 1 & mn == 1) | nargout == 4 %
	if nargout == 4		% State-space case
		ad = zd; bd = pd; cd = kd; dd = fs; fs = fp;
		error(abcdchk(ad,bd,cd,dd));
		if nargin == 6			% Prewarp
			fp = fp1;		% Decode arguments
			fp = 2*pi*fp;
			fs = fp/tan(fp/fs/2)/2;
		end
	else			% Transfer function case
		if nn > nd
			error('Numerator cannot be higher order than denominator.')
		end
		num = zd; den = pd;		% Decode arguments
		if nargin == 4			% Prewarp
			fp = fs; fs = k;	% Decode arguments
			fp = 2*pi*fp;
			fs = fp/tan(fp/fs/2)/2;
		else
			fs = kd;			% Decode arguments
		end
		% Put num(s)/den(s) in state-space canonical form.  
		[ad,bd,cd,dd] = tf2ss(num,den);
	end
	% Now do state-space version of bilinear transformation:
	t = 1/fs;
   r = sqrt(t);
   I = eye(size(ad));
   a = 2*fs*(ad-I)/(ad+I);				
   a1 = I-a/(2*fs);
   b = a1*bd*r/t;			
   c = cd*a1/r;				
   d = dd - c/a1*b*t/2;	
   
   if nargout == 4				% state-space form result
		z = a; p = b; k = c;
	else								% transfer function form result
		[z,p] = ss2tf(a,b,c,d);
	end
else
	error('First two arguments must have the same orientation.')
end

Contact us at files@mathworks.com