function m=add_dynamics(m,varargin)
%ADD_DYNAMICS add the dynamical description of the model
%    
%    This is  done by inizializing the 'nu', 'ny' and 'nd'
%    subfields of the  'dynamics' field of the model. These 
%    define the structure of the  regressors and therefore the
%    dynamical behaviour of the system. 'ny' is a  NUM_OUT *
%    NUM_OUT square matrix which contains the relationships of
%    each output (each row) with all the other outputs. Each
%    entry IJ indicates the number of past values associated
%    to the output J used in the regressor of the output I.
%    'nu' is a  NUM_OUT * NUM_IN matrix defining the
%    relationships between the outputs and each input. Each
%    entry IJ indicates the number of past values associated
%    to the input J used in the regressor of the output I.
%    Finally 'nd' is a  NUM_OUT * NUM_IN matrix defining the
%    delay of the inputs respect to the outputs. Each entry IJ
%    indicates the delay of the input J used in the regressor
%    of the output I.
%    
%    M=ADD_DYNAMICS(M,DYN) attaches to the model M the dynamic
%    description of the model present in the structure DYN
%    which must include the fields 'nu', 'ny' and 'nd',
%    defining the appropriate matrixes of the inputs, outputs
%    and delays of the system.
%    
%    M=ADD_DYNAMICS(M,NY,NU,ND) attaches to the model M the
%    dynamic description of the system as defined in the
%    arrays NY, NU, and ND.
%    
%    See also: GET
%    
%    

%MAN_PAGE_BEGIN
%
%   @purpose add the dynamical description of the model. This is 
%   done by inizializing the 'nu', 'ny' and 'nd' subfields of the 
%   'dynamics' field of the model. These  define the structure of the 
%   regressors and therefore the dynamical behaviour of the system. 'ny'
%   is a <code> num_out * num_out</code> square matrix which contains
%   the relationships of each output (each row) with all the other
%   outputs. Each entry <code>ij</code> indicates the number of past
%   values associated to the output <code>j</code> used in the
%   regressor of the output <code>i</code>. 'nu' is a <code> num_out *
%   num_in</code> matrix defining the relationships between the
%   outputs and each input. Each entry <code>ij</code> indicates the
%   number of past values associated to the input <code>j</code> used
%   in the regressor of the output <code>i</code>. Finally 'nd' is a
%   <code> num_out * num_in</code> matrix defining the delay of the
%   inputs respect to the outputs. Each entry <code>ij</code>
%   indicates the delay of the input <code>j</code> used in the
%   regressor of the output <code>i</code>.
%
%   @synopsis	m=add_dynamics(m,dyn)
%   @description attaches to the model <code>m</code> the dynamic
%   description of the model present in the structure <code>dyn</code> which
%   must include the fields 'nu', 'ny' and 'nd', defining the appropriate
%   matrixes of the inputs, outputs and delays of the system.
%
%   @synopsis	m=add_dynamics(m,ny,nu,nd)
%   @description attaches to the model <code>m</code> the dynamic
%   description of the system as defined in the arrays <code>ny</code>,
%   <code>nu</code>, and <code>nd</code>.
%
%   @see get
%
%MAN_PAGE_END

%in this function it is necessary to perform a deep check for the
%consistency of the dynamicsl description.  
  
error(checkval(m,'external','The first input'));
  
if nargin==2,
  error(checkval(varargin{1},'struct','The second input'));
  m.dynamics = varargin{1};
elseif nargin==4,
  m.dynamics.ny = varargin{1};   %matrix of the outputs
  m.dynamics.nu = varargin{2};   %matrix of the inputs
  m.dynamics.nd = varargin{3};   %matrix ofn the delays
else
  error('Wrong number of arguments');     
end

%check for integrity of the dynamics structure just passed
if checkval(m.dynamics.ny,'intpos','dynamics.ny',...
	    {size(m.dynamics.ny,1) size(m.dynamics.ny,1) 0 })
  error('''dynamics.ny'' must be a positive square matrix');
end
error(checkval(m.dynamics.nu,'intpos','''dynamics.nu'''));
error(checkval(m.dynamics.nd,'intpos','''dynamics.nd'''));
if checkval(m.dynamics.nu,'intpos','dynamics.nu',...
	    {size(m.dynamics.nd,1) size(m.dynamics.nd,2) 0 })
  error('''dynamics.nu'' must be the same size of ''dynamics.nd''');
end
if checkval(m.dynamics.ny,'intpos','dynamics.ny',...
	    {size(m.dynamics.nd,1) size(m.dynamics.ny,1) 0 })
  error('''dynamics.ny'' must have the same number of rows as ''dynamics.nu''');
end

if get(m,'n_in')==0 & get(m,'n_out')==0
   set(m,'n_in',size(m.dynamics.nu,2));
   set(m,'n_out', size(m.dynamics.ny,2));
end

number_inputs = get(m,'n_in');
number_outputs = get(m,'n_out');

if number_inputs ==0
  error('the number of inputs of the system is equal to zero');
end  
if number_outputs ==0
  error('the number of outputs of the system is equal to zero');
end 

if number_outputs ~= size(m.dynamics.ny,2),
  error('mismatch between the number of outputs and the structure of ''dynamics.ny'''); 
end

if number_outputs ~= size(m.dynamics.nu,1),
  error('mismatch between the number of outputs and the structure of ''dynamics.nu'''); 
end

if number_outputs ~= size(m.dynamics.nd,1),
  error('mismatch between the number of outputs and the structure of ''dynamics.nd'''); 
end

if number_inputs ~= size(m.dynamics.nu,2)
  error('mismatch between the number of inputs and the structure of ''dynamics.nu''');
end
if number_inputs ~= size(m.dynamics.nd,2)
  error('mismatch between the number of inputs and the structure of ''dynamics.nd''');
end


if nargout == 0,
  assignin('caller',inputname(1),m)
end





