function display(sys)
%DISPLAY   Display a Transfer Function object.

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


% REVISIT: does not work for complex numbers  tf(1,[1+i 1-i 1+i 1-i])
linemax = 65;      % max number of char. per line

sys = tf(sys);     % default method for TF children
sysnum = sys.num;
sysden = sys.den;
L = struct(sys.lti);
Ts = L.Ts;  % sampling time
Td = L.Td;  % delay time
[p,m] = size(sysnum);
if m*p==0,
   disp('Empty transfer function.')
   return
else
   ch = sys.Variable;
end


% Use input/output names if any
Istr = '';  Ostr = '';
Inames = L.InputName;
NoInames = isequal('','',Inames{:});
Onames = L.OutputName;
NoOnames = isequal('','',Onames{:});
Ending = ':';

if m==1 & NoInames,
  % Single input and no name
  if p>1 | ~NoOnames,
     Istr = ' from input';
  end
else
  for i=1:m, 
     if isempty(Inames{i}),
        Inames{i} = int2str(i); 
     else
        Inames{i} = ['"' Inames{i} '"'];
     end
  end
  Istr = ' from input ';
end

if p>1,
  for i=1:p, 
     if isempty(Onames{i}), Onames{i} = ['#' int2str(i)]; end
  end
  Ostr = ' to output...';
  Ending = '';
elseif ~NoOnames,
  % Single output with name
  Ostr = ' to output ';
  Onames{1} = ['"' Onames{1} '"'];
else
  % Single unnamed output, but several inputs
  Onames = {''};
  if ~isempty(Istr),  Ostr = ' to output';  end
end


% REVISIT: Possibly make a matrix gain display as a simple matrix
i = 1; j = 1;
while j<=m,
   num = sysnum{i,j};
   den = sysden{i,j};
   % Make DEN(1) positive
   ind = find(den);
   if den(ind(1))<0,  num = -num;  den = -den;  end

   disp(' ');
   % Display header for each new input
   if i==1,
      str = ['Transfer function' Istr Inames{j} Ostr];
      if p==1,  str = [str Onames{1}];  end
      disp([str Ending])
   end

   % Set output label
   if p==1,
      OutputName = '';
      loutname = 0;
   else
      OutputName = [' ' Onames{i} ':  '];
      loutname = length(OutputName);
   end
 
   s1 = poly2str(num,ch);
   s1 = sformat(s1,'+-',linemax);  % Handle long lines

   if ~isequal(s1,'0'),
      s2 = poly2str(den,ch);
      s2 = sformat(s2,'+-',linemax);  
   end

   if isequal(s1,'0') | isequal(s2,'1'),
      disp([OutputName s1])
   else
      [m1,l1] = size(s1);
      [m2,l2] = size(s2);
      if m1>1 | m2>1, disp(' '); end
      sep = '-';
      b = ' ';
      extra = fix((l2-l1)/2);
      disp([b(ones(m1,loutname+max(0,extra))) s1]);
      disp([OutputName sep(ones(1,max(l1,l2)))]);
      disp([b(ones(m2,loutname+max(0,-extra))) s2]);
   end
   i = i+1;  
   if i>p,  
     i = 1;  j = j+1;
   end
end

disp(' ');


if Ts==0 & any(Td),
   if length(Td)==1,
      disp(['Input delay: ' num2str(Td)])
   elseif any(Td~=Td(1)),
      disp(['Input delays (listed by channel): ' sprintf('%0.3g  ',Td)])
   else
      disp(['Input delay (for all channels): ' num2str(Td(1))])
   end
   NoDelay = 0;
else
   NoDelay = 1;
end

if isgain(sysnum,sysden) & NoDelay,
   disp('Static gain.')
elseif Ts<0,
   disp('Sampling time: unspecified')
elseif Ts>0,
   disp(['Sampling time: ' num2str(Ts)])
end


% end ../@tf/display.m


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function s = poly2str(p,ch)
%POLY2STR Return polynomial as string.
%       S = POLY2STR(P,ch) where ch is 's', 'z', 'z^-1', or 'q'
%       returns a string S consisting of the polynomial coefficients 
%       in the vector P multiplied by powers of the transform variable 
%       's', 'z', 'z^-1', or 'q'.  Quite similar to old poly2str.
%
%       Example: POLY2STR([1 0 2],'s') returns the string  's^2 + 2'. 

form = '%.4g';
relprec = 0.0005;   % 1+relprec displays as 1


ind = find(p);
if isempty(ind),
   s = '0';
   return
elseif length(p)==1,
   % Quick exit if constant gain
   if p==round(p) & abs(p) < 1e6,
      s = int2str(p);
   else
      s = sprintf(form,p);
   end
   return
end

zinv = 0;
if strcmp(ch,'z^-1'),
   ch = 'q';
   zinv = 1;
end

if strcmp(ch,'q'),
   % Ascending powers
   pow = 0:length(p)-1;
else
   % Descending power
   pow = length(p)-1:-1:0;
end
pow = pow(ind); 
s = '';
% For each non-zero element of the polynomial ...
for i=1:length(ind),
   pi = pow(i);
   el = p(ind(i));
   % ... if it's not the first non-zero element of the polynomial ...
   if i~=1,
     if el>0,
       % Add a plus sign if the element is positive
       s = [s ' + '];
     else
       % Add a minus sign if the element is negative
       s = [s ' - '];  
     end
   elseif el<0,
     s = [s '-'];
   end
   % If the element isn't 1, or display in "/", or power is zero
   el = abs(el);
   if abs(el-1)>relprec | (pi==0),
      % Add the absolute value of the element
      if el==round(el) & el < 1e6,
         s = [s int2str(el) blanks(pi~=0)];
      else
         s = [s sprintf(form,el) blanks(pi~=0)];
      end
   end
   % Note: in following clause, never print "ch" to 0th power
   if pi==1,
      % Positive powers don't need exponents if to the 1st power
      s = [s ch];
   elseif pi~=0,
      % As long as the power is non-zero add "ch" raised to power
      s = [s ch '^' int2str(pi)];
   end
end

% Take care of ch='z^-1'
if zinv,
  s = strrep(s,'q^','z^-');
  s = strrep(s,'q','z^-1');
end

% end poly2str



