function f = sos(h,varargin)
%SOS  Convert a DFILT object to second-order sections DFILT object.
%   G = SOS(H) returns a filter object G of second-order sections given
%   any DFILT object H.  If H has a single section, G and H will be of
%   the same class.
%
%   G = SOS(H,I) converts the I-th section of H to a second-order
%   sections filter object.
%
%   SOS(H,DIR_FLAG) and SOS(H,I,DIR_FLAG) specify the ordering of the 2nd
%   order sections. If DIR_FLAG is equal to 'UP', the first row will contain
%   the poles closest to the origin, and the last row will contain the
%   poles closest to the unit circle. If DIR_FLAG is equal to 'DOWN', the
%   sections are ordered in the opposite direction. The zeros are always
%   paired with the poles closest to them. DIR_FLAG defaults to 'UP'.
%
%   SOS(H,DIR_FLAG,SCALE) and SOS(H,I,DIR_FLAG,SCALE) specify the desired
%   scaling of the gain and the numerator coefficients of all 2nd order
%   sections. SCALE can be either 'NONE', 'INF' or 'TWO' which correspond
%   to no scaling, infinity norm scaling and 2-norm scaling respectively.
%   SCALE defaults to 'NONE'. 
%
%   Using infinity-norm scaling in conjunction with 'UP' ordering will
%   minimize the probability of overflow in the realization. On the other
%   hand, using 2-norm scaling in conjunction with 'DOWN' ordering will
%   minimize the peak roundoff noise.
%
%   See also DFILT/TF, DFILT/SS, DFILT/ZPK.


%   Author(s): R. Losada
%   Copyright 1988-2000 The MathWorks, Inc.
%   $Revision: 1.7 $  $Date: 2000/06/13 21:21:23 $ 

error(nargchk(1,4,nargin));

if nargin > 1 & isnumeric(varargin{1}) & ~isempty(varargin{1}),
    h = section(h,varargin{1});
    
    % Remove the section number from the varargin
    varargin = {varargin{2:end}};
end

% Gather info on h
connect = connection(h);
nsecs = nsections(h);


switch connect,
case 'cas',
    
    f = cas2sos(nsecs,h,varargin{:});        
case 'par',
    
    f = par2sos(nsecs,h,varargin{:});       
end
    
%-----------------------------------------------------------------------
function f = cas2sos(nsecs,h,varargin)

filtstruct = filterstructure(h);


% Convert to transfer function first
[b,a] = tf(h);

% Compute the sos matrix and the gain
[sos,g] = tf2sos(b,a,varargin{:});
    
% Form cell of second-order sections 
c = sos2cell(sos,g);
 
% Create df2t object of cascaded second-order sections
tempfilt = df2t(c);

% Now convert to original structure
f = feval(filtstruct,tempfilt);

%------------------------------------------------------------------------
function f = par2sos(nsecs,h,varargin)

for n = 1:nsecs,
    
    hsec = section(h,n);
    
    % Get the filterstructure of each section
    filtstruct = filterstructure(hsec);
    
    [b,a] = tf(section(h,n));
    [sos,g] = tf2sos(b,a,varargin{:});
    
    % Form a cell of sos
    c = sos2cell(sos,g);
    
    % Create a temporary filter of sos in df2t to be converted
    tempfilt = df2t(c);
    
    % Convert back this section to original structure
    secfilt{n} = feval(filtstruct,tempfilt);
end

% Now form parallel filter with cascaded sos branches
f = par(secfilt{:});


