function [b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15,b16,b17,b18,b19,b20] = branch(tr,j1,j2,j3,j4,j5,j6,j7,j8,j9,j10,j11,j12,j13,j14,j15,j16,j17,j18,j19,j20)

% [B1,B2,...,BN] = BRANCH(TR,PATH1,PATH2,...,PATHN) returns N sub-
%     branches of tree TR.  If NARGIN==1, the root branches are returned
%     in sequence by numerical index; otherwise, the branches returned
%     are determined by the paths PATH1, PATH2,...,PATHN.  Each path is
%     normally a STRING of the form 
%           PATH = '/name1/name2/.../namen'
%     where name1,name2, et cetera are the string names of the branches
%     which define the path from the tree root to the sub-branch of 
%     interest.  Alternatively, one may substitute for any PATH a row
%     vector containing the integer indices of the branches which define
%     the PATH.  For example, if S=TREE('a,b,c','foo',[49 50],'bar') then 
%     BRANCH(S,'c') and BRANCH(S,3) both return the value 'bar'.
%
%  See also ISTREE and TREE. 

%
% R. Y. Chiang & M. G. Safonov 10/01/90	
% Copyright (c) 1990 by the MathWorks, Inc.
% All Rights Reserved.
% ---------------------------------------------------------------------------
nin = nargin-1;
n=max([nargout,1]);  
%    
if nin==-1,error('no tree input specified'),end

magic1 = 29816; % Every tree vector TR includes these two "magic numbers"
magic2 = 18341; % in postions TR(2) and TR(3) for identification purposes.

%  Check that TR is a tree
msg='first input argument must be a TREE';
%  Check that TR is a vector and has length at least 5
if max(size(tr))<6 | min(size(tr))~=1,
  error(msg);
end
% If TR is a row vector, transpose it
tr=tr(:);  
% Check magic numbers to ensure that TR is a tree
if tr(2)~=magic1 |tr(3)~=magic2
  error(msg);
end

% Now get the paths I1,...,IN:
% If no paths specified, assign values I1=1,...,IN=n; otherwise
% copy Ij's from Jj's, breaking up string Jj's at commas.
if nin==0,
   for j=1:n,
      temp=['i' num2str(j) '=' num2str(j) ';'];
      eval(temp);
   end
   iind=n;
end
if nin>0,
  iind=0;
  for jind=1:nin,
     eval(['jj=j' num2str(jind) ';']),
     if isstr(jj),             % If Jj is a string, create one
        jj=[',' jj ','];       % extra Ij for each comma in Jj
        ind=find(jj==',');
        [rind,cind]=size(ind);
        for j=1:cind-1,  
            iind=iind+1;
            ptr1=ind(j)+1;
            ptr2=ind(j+1)-1;
            eval(['i' num2str(iind) '=jj(ptr1:ptr2);']),
        end         
     else                      % otherwise, simply copy Jj onto Ij
        iind=iind+1;
        eval(['i' num2str(iind) '=jj;'])         
     end
  end
end
nin=iind;

% Number of paths must not be less the NARGOUT
if n>nin, 
   msg ='Too many output arguments.';
   error(msg),
end

%  For each J=1,...,N follow path IJ to get branch BJ
for j = 1:n,
   temp =['ij = i' num2str(j) ';'];  % IJ = Ij
   eval(temp);
   [rj,cj]=size(ij);
   if rj~=1 | cj==0,error('invalid path or index'),end
   if isstr(ij),           % case of string-name path IJ=PATHJ
      flag=1;
      ij=[ij '/'];           % append extra '/' to string ij
      if ij(1)~='/',ij=['/' ij];end  %if missing add leading '/'
      pptrj=find(ij=='/');   % PPTRJ = pointers to /'s in PATH IJ
      lj=max(size(pptrj))-1; % path length (number of names)
   else                      % case of numeric path INDEX IJ
      flag=0;             
      lj=max(size(ij));      % path length (number of indices)
   end
   x = tr; 
   % Now descend tree X one branch at a time, recursively
   % overwriting X with root branch having index IJ(K)
   for k=1:lj, 
     % Check to make sure X is a TREE 
     if max(size(x))<6 | min(size(x))~=1,
       error('Invalid path or branch');
     end
     if x(2)~=magic1 |x(3)~=magic2
        error('Invalid path or branch');
     end

     [rx1,cx1]=size(x);
     if flag ==1,
        nm = branch(x,0);
        nm=[',' nm ','];  % nm = ',name1,name2,..,namen,'

        % Now get k-th name in pathj
        if pptrj(k+1)-pptrj(k)>1,
            nmjk = ij(pptrj(k)+1:pptrj(k+1)-1);
        else
            error('empty string encountered in path')
        end

        if max(nmjk)<='9' & min(nmjk)>=0,  % If NMJK contains a string
           [rnmjk,cnmjk]=size(nmjk);       % representation of an 
           njk=0;                          % integer, set NJK equal
           for jjj=1:cnmjk,                % to that integer
               njk=nmjk(jjj)-'0'+10*njk;
           end
        else                               % otherwise...
           % compare NMJK with names in NM and set 
           % NJK = (position in nm of name matching NMJK); if no
           % match found then set fflag = 0 and announce error
           nmptr=find(nm==',');
           nnm = max(size(nmptr))-1; % number branch names in nm
           fflag=0;
           iter=0;
           while fflag==0 & iter<nnm
              temp=nm(nmptr(iter+1)+1:nmptr(iter+2)-1);
              if size(nmjk)==size(temp),    % if match found
                 if nmjk==temp,             % set NJK=ITER+1
                   njk=iter+1;              % and exit while 
                   fflag=1;                 % loop 
                 end                       
              end                           
              iter=iter+1;
           end
           if fflag==0,
              error(['branch ' ij(1:pptrj(k+1)-1) ' not present']);
           end
        end
     else
        njk = ij(k);
     end      
     msg=['branch B' num2str(j) ' index out of range'];
     if njk>x(1)| njk<0 | njk+6>rx1, error(msg),end
     ptr1 = x(njk+6);   % points to start of njk-th subfield of DAT
     if ptr1~=1,
         rx = x(ptr1);  % rows of branch
     else                   
         rx=0;          % empty matrix is indicated by ptr1=1
     end     
     if rx<0,     % RX is negative if the branch contains string data 
          rx = abs(x(ptr1)); 
          sflag=1;
     else
          sflag=0;
     end
     if rx1>=ptr1+1,
        cx = x(ptr1+1);   % cols of x
     else
        error('Invalid path or branch')
     end
     lx = rx*cx;       % length of x
     if lx>0 & ptr1+lx+1<=rx1,  % if new X empty and old X is big enough
        xcol = x(ptr1+2:ptr1+lx+1); % Store new X data into XCOL
        x = zeros(rx,cx);      % Create a new X matrix of correct dimension
        x(:) = xcol(:);        % Now fill in new X with XCOL data
     elseif lx==0,
        x=[];
     else
        error('invalid path or index')
     end
   end
   if sflag==1,
      x=setstr(x);  %set string bit
   end
   temp=['b' num2str(j) ' = x;'];
   eval(temp);
end
% ------ End of BRANCH.M --- RYC/MGS 10/05/90 %
