% function out = abv(mat1,mat2,mat3...,matN)
%
%   Stacks VARYING/SYSTEM/CONSTANT matrices above one another:
%
%                          |  mat1  |
%                          |  mat2  |
%            out    =      |  mat3  |
%                          |   ..   |
%                          |  matN  |
%
%   See also: MADD, DAUG, MMULT, SBS, SEL, and VDIAG.

function out = abv(mat1,mat2,mat3,mat4,mat5,mat6,mat7,mat8,mat9)
 if nargin < 2
   disp('usage: out = abv(mat1,mat2,mat3,...,matN)')
   return
 elseif nargin == 2
   top = mat1;
   bot = mat2;
   if isempty(top)
     out = bot;
   elseif isempty(bot)
     out = top;
   else
     [toptype,toprows,topcols,topnum] = minfo(top);
     [bottype,botrows,botcols,botnum] = minfo(bot);
     if (bottype == 'syst' & toptype == 'vary') | ...
                (bottype == 'vary' & toptype == 'syst')
       error('ABV of SYSTEM and VARYING not allowed')
       return
     end
     if topcols ~= botcols
       error('incompatible column (input) dimensions')
       return
     end
     if toptype == 'vary'
       if bottype == 'vary'
%	 both VARYING
         code = indvcmp(top,bot);
         if code == 1
           [vdt,rpt,indvt] = vunpck(top);
           [vdb,rpb,indvb] = vunpck(bot);
           tmp = [reshape(vdt,toprows,topnum*topcols);...
                 reshape(vdb,botrows,botnum*botcols)];
	   out = zeros((toprows+botrows)*topnum+1,topcols+1);
	   out((toprows+botrows)*topnum+1,topcols+1) = inf;
	   out((toprows+botrows)*topnum+1,topcols) = topnum;
 	   out(1:topnum,topcols+1) = indvt;
	   out(1:(toprows+botrows)*topnum,1:topcols) = ...
                 reshape(tmp,topnum*(toprows+botrows),topcols);
         else
           error('varying data is inconsistent')
           return
         end
       else
%	 VARYING above CONSTANT
         [vdt,rpt,indvt] = vunpck(top);
         tmp = [reshape(vdt,toprows,topnum*topcols);...
               kron(bot,ones(1,topnum))];
	 out = zeros((toprows+botrows)*topnum+1,topcols+1);
	 out((toprows+botrows)*topnum+1,topcols+1) = inf;
	 out((toprows+botrows)*topnum+1,topcols) = topnum;
	 out(1:topnum,topcols+1) = indvt;
	 out(1:(toprows+botrows)*topnum,1:topcols) = ...
               reshape(tmp,topnum*(toprows+botrows),topcols);
       end
     elseif toptype == 'cons'
       if bottype == 'vary'
         [vdb,rpb,indvb] = vunpck(bot);
         tmp = [kron(top,ones(1,botnum));...
               reshape(vdb,botrows,botnum*topcols)];
	 out = zeros((toprows+botrows)*botnum+1,topcols+1);
	 out((toprows+botrows)*botnum+1,topcols+1) = inf;
	 out((toprows+botrows)*botnum+1,topcols) = botnum;
	 out(1:botnum,topcols+1) = indvb;
	 out(1:(toprows+botrows)*botnum,1:topcols) = ...
               reshape(tmp,botnum*(toprows+botrows),topcols);
       elseif bottype == 'cons'
         out = [top ; bot];
       else
         [a,b,c,d] = unpck(bot);
         cc = [zeros(toprows,botnum) ; c];
         dd = [top ; d];
         out = pck(a,b,cc,dd);
       end
     else
       if bottype == 'cons'
         [a,b,c,d] = unpck(top);
         cc = [c ; zeros(botrows,topnum)];
         dd = [d ; bot];
         out = pck(a,b,cc,dd);
       else
         [at,bt,ct,dt] = unpck(top);
         [ab,bb,cb,db] = unpck(bot);
         a = daug(at,ab);
         b = [bt ; bb];
         c = [ct zeros(toprows,botnum) ; zeros(botrows,topnum) cb];
         d = [dt;db];
         out = pck(a,b,c,d);
       end
     end
   end
 else
%  recursive call for more than two input arguments
   exp = ['out=abv(abv('];
   for i=1:nargin-2
     exp=[exp 'mat' int2str(i) ','];
   end
   exp = [exp 'mat' int2str(nargin-1) '),mat' int2str(nargin) ');'];
   eval(exp);
 end
%
% Copyright MUSYN INC 1991,  All Rights Reserved
