function sys = tf(varargin)
%TF  Specify transfer functions or convert LTI model to transfer function.
%
%   TFSYS = TF(SYS)  converts an arbitrary LTI model SYS to transfer 
%   function format. The output TFSYS is a TF object.  
%
%   TFSYS = TF(SYS,'inv')  uses a fast algorithm for state-space SYS,
%   but is typically less accurate for high-order systems.
%
%   You can create SISO or MIMO transfer functions (TF) by
%    SYS = TF(NUM,DEN)       Continuous-time system  NUM(s)./DEN(s)
%    SYS = TF(NUM,DEN,T)     Discrete-time system  NUM(z)./DEN(z)  with 
%                            sampling time T (Set T=-1 if undetermined)
%    SYS = TF                Default empty TF object
%    SYS = TF(M)             Static gain matrix
%    SYS = TF(NUM,DEN,LTI)   Transfer function with LTI properties inherited 
%                            from system LTI (can be SS, TF, or ZPK).
%   All the above syntaxes may be followed by Property/Value pairs.
%   (Type "help ltiprops" for details on assignable properties). 
%   The output SYS is a TF object.
% 
%   The default TF variables 's' and 'z' can be altered by resetting  
%   the 'Variable' property.  Alternatives include 'p' for continuous TF
%   and 'z^-1' or 'q' for discrete TF.
%
%   For SISO systems, NUM and DEN are row vectors listing the numerator and
%   denominator coefficients in 
%     * descending powers of s or z by default
%     * ascending powers of q = z^-1 if 'Variable' is set to 'z^-1' or 'q'
%       (DSP convention).
%
%   For MIMO systems with NU inputs and NY outputs, NUM and DEN are 
%   NY-by-NU cell arrays of row vectors where NUM{i,j} and DEN{i,j} specify
%   the transfer function from input j to output i.  For example,
%       tf( {-5 ; [1 -5 6]} , {[1 -1] ; [1 1 0]})
%   specifies the two-output/one-input system
%
%       [     -5 /(s-1)      ]
%       [ (s^2-5s+6)/(s^2+s) ] 
%
%   See also  FILT, TFDATA, GET, SET, LTIPROPS, ZPK, SS.

%       Author(s): A. Potvin, 3-1-94, P. Gahinet, 4-1-96
%       Copyright (c) 1986-97 by The MathWorks, Inc.
%       $Revision: 1.8 $  $Date: 1997/04/09 00:30:04 $


ni = nargin;
if ni & isa(varargin{1},'tf'),
  % Quick exit for TF(SYS) with SYS of class TF
  sys = varargin{1};
  if ni>1,
     error('Use SET to modify the properties of TF objects.');
  end
  return
end

% Define default property values
inferiorto('ss','zpk')
superiorto('double')
sys.num = {};
sys.den = {};

% Dissect input list
DoubleInputs = 0;
LtiInput = 0;
PVstart = 0;
while DoubleInputs < ni & PVstart==0,
  nextarg = varargin{DoubleInputs+1};
  if isa(nextarg,'lti'),
     LtiInput = DoubleInputs+1;
     PVstart = DoubleInputs+2;
  elseif isstr(nextarg) | (~isempty(nextarg) & iscellstr(nextarg)),
     PVstart = DoubleInputs+1;  
  else
     DoubleInputs = DoubleInputs+1;
  end
end

% Handle bad calls
if PVstart==1,
   if ni==1,
     % Bad conversion
     error(['Conversion from ' cl ' to tf is not possible.'])
   else
     error('First input must contain only numerical data');
   end
elseif DoubleInputs>3 | (DoubleInputs==3 & LtiInput),
   error('Too many numerical inputs');
end


% Process numerical data 
numden = 0;
switch DoubleInputs,
case 0
   if ni, error('Too many LTI arguments or missing numerical data'); end
case 1
   % Gain matrix 
   nummat = varargin{1};
   if isa(nummat,'cell') | ndims(nummat)>2,
     error('Call with single input requires 2D matrix as input (static gain).')
   end
   sys.num = cell(size(nummat));
   sys.den = cell(size(nummat));
   if ~isempty(nummat),  sys.num = num2cell(nummat);   end
   sys.den(:) = {1};
otherwise
   % NUM and DEN specified
   num = varargin{1};    
   den = varargin{2};
   if isa(num,'double'), num = {num}; end
   if isa(den,'double'), 
      den0 = den;
      den = cell(size(num));
      den(:) = {den0};
   end
   % Check NUM/DEN consistency
   error(ndcheck(num,den,2));
   sys.num = num; 
   sys.den = den;
   numden = 1;
end


% Create LTI parent
[Ny,Nu] = size(sys.num);
if LtiInput,
   L = varargin{LtiInput};
   if isa(L,'tf'),
      L = L.lti;
   end
   Ls = struct(L);
   Ts = Ls.Ts;
elseif DoubleInputs<=2,
   % Default parent LTI with Ts = 0
   L = lti(Ny,Nu);
   Ts = 0;
else
   % Discrete TF 
   Ts = varargin{3};
   if isempty(Ts),  Ts = -1;  end
   if ~isreal(Ts) | ~isfinite(Ts) | length(Ts)~=1,
      error('Sample time T must be a real number.');
   elseif Ts<0 & Ts~=-1,
      error('Negative sample time not allowed (except Ts = -1 to mean unspecified).');
   end
   L = lti(Ny,Nu,Ts);
end

% Variable
if Ts==0,
   sys.Variable = 's';
else
   sys.Variable = 'z'; 
end

% TF is a subclass of LTI
sys = class(sys,'tf',L);

% Set PV pairs
if (PVstart>0) & (PVstart<=ni),
   set(sys,varargin{PVstart:ni})
end

% Make NUM{i,j} and DEN{i,j} of equal length by padding with zero on the 
% left or right depending on sys.Variable
if numden,
   [sys.num,sys.den] = ndpad(num,den,sys.Variable);
end

% end ../@tf/tf.m
