function D = x2fx(x,model)
%X2FX   Factor settings matrix (x) to design matrix (fx).
%   D = X2FX(X,'MODEL') Transforms a matrix of system inputs, X, to 
%   the design matrix for a regression analysis. The optional string
%   input, MODEL, controls the order of the regression model. By 
%   default, X2FX returns the design matrix for a linear additive
%   model with a constant term. MODEL can be following strings:
%   interaction (i)   - includes constant, linear, and cross product terms.
%   quadratic (q)     - interactions plus squared terms.
%   purequadratic (p) - includes constant, linear and squared terms.
%   
%   Alternatively, MODEL can be a matrix of terms. Each row of MODEL 
%   represents one term. The value in a column is the exponent to raise 
%   the same column in X for that term. This allows for models with 
%   polynomial terms of arbitrary order.
%
%   Example: x = [1 2 3]' model = [0 1 2]'
%   D = [1 1 1; 1 2 4; 1 3 9] 
%   The first column is x to the 0th power. The second column is x to
%   the 1st power. And the last column is x squared.
% 
%   X2FX is a utility function for RSTOOL, REGSTATS and CORDEXCH.
%   See also RSTOOL, CORDEXCH, ROWEXCH, REGSTATS. 

%   B.A. Jones 12-20-94
%   Copyright (c) 1993-96 by The MathWorks, Inc.
%   $Revision: 2.3 $  $Date: 1996/03/13 14:48:41 $


[m,n]  = size(x);

if nargin == 1
   D = [ones(m,1) x];
   return
end

D = [ones(m,1) x];

if strcmp(model,'interaction') | strcmp(model,'quadratic') | ...
   strcmp(model,'q') | strcmp(model,'i'),
   for idx = 1:n
      xidx   = x(:,idx);
      xidx   = xidx(:,ones(n-idx,1));
      D = [D xidx .* x(:,idx+1:n)];
   end
end

if strcmp(model,'quadratic') | strcmp(model,'q'),
    D = [D x.*x];
end

if strcmp(model,'purequadratic') | strcmp(model,'p'),
    D = [D x.*x];
end

if ~isstr(model)
  [row,col] = size(model);
  if col ~= n
     error('A numeric second argument must have the same number of columns as the first argument.');
  end
  D = zeros(m,row);
  for idx = 1:row
    carat = model(idx,:);
    tmp = x.^carat(ones(m,1),:);
    if min(size(tmp)) == 1
        D(:,idx) = prod(tmp);
    else
        D(:,idx) = (prod(tmp'))';
    end
  end
end
     
