function m = identify(m,j,options)
%IDENTIFY Identify the system from data
%    
%    M = IDENTIFY(M)  performs the identification of the model
%    M using the data embedded inside the object for all the
%    outputs of the system, using the defautl values of the
%    identification methods. 
%    
%    M = IDENTIFY(M,J,OPTIONS) performs the identification of
%    the model M using the data embeded inside the object for
%    the outputs listed in the array J. Use OPTIONS in order
%    to specify the identification method and options.
%    
%    See also: EVAL
%    
%    

%MAN_PAGE_BEGIN
%
%   @purpose	Identify the system from data
%
%   @synopsis	m = identify(m) 
%   @description performs the identification of the model <CODE>m</CODE>
%   using the data embedded inside the object for all the outputs of the
%   system, using the defautl values of the identification methods. 
%
%   @synopsis	m = identify(m,j,options)
%   @description  performs the identification of the model <CODE>m</CODE> using
%   the data embeded inside the object for the outputs listed in the
%   array <code>j</code>. Use <CODE>options</CODE> in order
%   to specify the identification method and options.
%
%   @see  eval
%
%MAN_PAGE_END

  
if (nargin < 2)|isempty(j),
  j = 1:get(m,'n_out');
end

if nargin < 3, options = []; end

check(m);

error(checkargs([{m j options}],[1 3],'external','numeric','any'));

error(checkval(j,'intpos','j',{1 1:get(m,'n_out') 0},[1 get(m,'n_out')]));

listlinks = get(m,'links');
if isempty(listlinks)
  error('the links of the system have not jet been defined');
end  
listlinks = listlinks(j,:);

[ir, or] = regress(m,j);

for i = unique(listlinks(:,1))',
  sub = find(listlinks(:,1) == i);
  options.outputs = listlinks(sub,2);
  map = get(m,'mapping');
  map{i} = identify(map{i},ir{sub(1)},or{sub(1)},options);
  set(m,'mapping',map);
  
  lims = get(m,'limits');
  if ~all(isfinite(lims(:))),
	lims(:,j(sub)) = map{i}.limits(:,options.outputs);
	set(m,'limits',lims);
  end
  
  opt = get(m,'opt');
  opt.links_history(i,listlinks(sub,2)) = j(sub);
  m = set(m,'opt',opt);

end

%clear the error database from the results of the mapping which 
% had been identified again
opt=get(m,'opt');
if isfield(opt,'errors_database')  & ~isempty(opt.errors_database.system_output),
  database=opt.errors_database;
  mappings=unique(listlinks(:,1))';
  for i=1:size(mappings,2),
   for q=size(database.system_output,2):-1:1,
     %if there is a mapping in common with the one identified
     %eliminate all the ertries of the database since the 
     %mapping is changed
     if database.output_links{q}(1,1)==mappings(i),
       database.system_output(q)=[];
       database.output_links(q)=[];
       database.mapping_name(q)=[];
       database.file(q)=[];
       database.error_type(q)=[];
       database.value(q)= [];
     end  
   end
  end
  opt.errors_database=database;
end 

%clear the simulation database from the results of all the active  
%mappings

if isfield(opt,'simulation_database')  & ~isempty(opt.simulation_database.links),
  database=opt.simulation_database;
  links=get(m,'links');
  for i=size(database.links,2):-1:1,
    %if there is a model that hadf been used in a past simulation.
    %all the data vill be corrupted by a new identification, and
    %therefore it is necessary to delete all the entries
    if any(links(:,1)==database.links{i}(:,1))
      database.links(i)=[];
      database.file(i)=[];
      database.simulation_errors(i)=[];
      database.outputs(i)=[];
      database.simulated_outputs(i)=[];
    end
  end
  opt.simulation_database=database;
end

%write the update database files
set(m,'opt',opt);
assignin('caller',inputname(1),m);

