function tr = tree(nm,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,...
  b15,b16,b17,b18,b19,b20,b21,b22,b23,b24,b25,b26,b27,b28,b29,b30,...
  b31,b32,b33,b34,b35,b36,b37,b38,b39,b40,b41,b42,b43,b44,b45,b46,...
  b47,b48,b49,b50)
% TR = TREE(NM,B1,B2,...,BN) creates a hierarhical data structure TR 
%     called a "tree"  consisting of a single column vector into which
%     is encoded all the data and dimension information from its
%     branches B1, B2,...,BN along with a numerical index and a string-
%     name for each branch. The input argument NM assigns names to the
%     branches; it must be of the form
%           NM = 'name1,name2,...,nameN'
%     The names may be any valid MATLAB variable names and must be
%     separated by commas; if no names are to be assigned, set NM=''.
%     The arguments B1,B2,...,BN (called the "root branches" of the
%     tree) may be matrices, vectors, strings, or trees themselves.
%     Related functions include the following:
%         BRANCH   returns branches of a tree
%         ISTREE   tests existence of a specified branch
%         BRANCH(TR,0)  returns NM
%         TR(1)    returns the number N of root branches
%

% R. Y. Chiang & M. G. Safonov 10/01/90	
% Copyright (c) 1990 by the MathWorks, Inc.
% All Rights Reserved.
% ---------------------------------------------------------------------------

if nargin==0,error('missing input arguments');end

% Initialize variables
n = nargin-1;       % number of branches N
ind = 7+n;          % point to beginning of B0 data subfield of DAT
dat = [];
ptr = [];
magic1 = 29816; 
magic2 = 18341;

% create header for tree
header = [n;magic1;magic2;0;0];
% Note:  The tree TR has the "magic numbers" 29816 and 18341 in
% positions 2 and 3 , respectively.  These magic numbers are used 
% by other functions to distinguish a tree from an ordinary vector
% The two zero entries in positions 4 and 5 have no significance
% other than as place holders; they may be overwritten with data
% for specialized applications.

msg = 'first input argument must be string of names separated by commas';
[rnm,cnm]=size(nm);
if rnm>1,error(msg),end
if rnm==1 & ~isstr(nm),error(msg),end

% Remove any spaces from NM
nm=[nm ' ']; nm(find(nm==' '))='';
b0 = nm;                  % Let NM be branch zero of the tree

% Now check names in NM for validity
nm1=[',' nm ','];
ind1=find(nm1==',');
c=max(size(ind1))-1;
if c~=n & min(size(nm))>0,
   error(['Number of names in string ' 13 10 '''' nm '''' 13 10 'is not equal to number of branches of tree'])
end
for i=1:c,
   nmi=nm1(ind1(i)+1:ind1(i+1)-1);
   temp=find((nmi>='0' & nmi<='9')|(nmi>='A' & nmi<='Z')|nmi=='_'|(nmi>='a' & nmi<='z'));
   if min(size(nmi))>0
      temp=nmi(temp);
      if ~issame(temp,nmi) | ~(nmi(1)>=65),
         error([' ' nmi ' is not a valid branch name.'])
      end
   end
end

% Now create DAT vector with data on B0, B1, B2 et cetera and a PTR vector
% containing pointers pointing to the beginnning of the subfields of
% DAT corresponding to each of B0,B1, etc.

% Create a subfield of DAT for each of the branches B0, B1, B2, etc.
for i = 0:n,
   eval(['b = b' num2str(i) ';'])   % B = i-th branch
   [rb,cb]=size(b);
   if cb>0,
      ptr = [ptr;ind];
      % if B is string, set rb=-rb,end  % minus flags string branch 
      if isstr(b(:)'),
         rb=-rb;    % string data marked by negative sign
      end                   
      dat = [dat;rb;cb;b(:)]; % Append Bdat to DAT field

      ind=ind+size(b(:))*[1;0]+2;
           % IND points to start of data field for branch i+1
   else
       ptr = [ptr;1];      % PTR for empty matrix is 1
   end
end
% PTR vector now has length N+1 with first entry pointing to start
% of the NM field (i.e., B0) and the remaining N entries pointing
% to the start of the fields containing the data for B1,B2,...,BN

% Now assemble the tree vector TR
% Format:
% index     1        6       PTR(0)  ...      PTR(N)
      %     HEADER   PTR     B0dat   ...      BNdat ];
tr = 1*[header; ptr; dat]; 
% Note:  Multiplying TR by 1 unsets string bit, if needed

% ------ End of TREE.M --- RYC/MGS 10/05/90 %
