function err=flat_error(m,varargin)
%ERROR computes the mean square error of the model
%    
%    This function  evaluates the mean square error of the
%    model respect to the reference set of  values given as
%    output data. This is performed by the function by calling
%    the 'eval' method, obtaining the extimated output of the
%    model  and comparing it with the reference one.  
%    
%    ERR=ERROR(M,J) returns the mean square error of the model
%    respect the output J.
%    
%    ERR=ERROR(M,DATA,J) get the error of the model respect
%    the data DATA  and the output J. DATA must be an object
%    of the class dataset.
%    
%    See also: SIMULATION_ERROR
%    
%    

%MAN_PAGE_BEGIN
%
%   @purpose     computes the mean square error of the model. This function 
%   evaluates the mean square error of the model respect to the reference set of 
%   values given as output data. This is performed by the function by calling the
%   'eval' method, obtaining the extimated output of the model 
%   and comparing it with the reference one.  
%
%   @synopsis	err=error(m,j)
%   @description    returns the mean square error of the model respect the output <code>j</code>.
%
%   @synopsis	err=error(m,data,j)
%   @description    get the error of the model respect the data <code>data</code> 
%   and the output <code>j</code>. <code>data</code> must be an object of
%   the class dataset.
%
%   @see simulation_error
%
%MAN_PAGE_END   

%this .function needs to check the integrity of the object and if the
%'n_out' field has been initialized

%error(checkval(nargin,'inputs','number of inputs',{-1},[2 3])); 

error(checkval(m,'external','The first input'));
check(m);  

if nargin > 3,
  error('bad number of inputs');
end

if isa(varargin{1},'dataset'),
  old_data=get(m,'data');
  m=add_data(m,varargin{1},get(m,'T'));
  j=varargin{2};
else 
  j=varargin{1};
end

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

if get(m,'n_out') <=0,
  error ('the number of the outputs has not yet been initialized');
end  

[in,out] = regress(m);

out_mod = eval(m,in{j},j);

err=sqrt(sum((out{j} - out_mod).^2)./size(out_mod,1));


%%%update the error  database
opt=get(m,'opt');
if isfield(opt,'errors_database')  & ~isempty(opt.errors_database.system_output),
  database=opt.errors_database;
else,
  database=struct('system_output',cell(1,1),...
                  'output_links',cell(1,1),...
		  'mapping_name',cell(1,1),...
		  'file',cell(1,1),...
		  'error_type',cell(1,1),...
		  'value',cell(1,1));  
end 

links=get(m,'links');
data=get(m,'data');

%the new points have the following structure:
% {system_output, [mapping_number mapping_output], mapping_name,
%  data_file, type, value}

%check if the error has been already stored in the database
for i=1:size(j,1),
  found=0;
  for q=1:size(database.system_output,2)
    if database.system_output{q}==j(i) & ...
       all(database.output_links{q}==links(j(i),:)) & ...
       strcmp(database.file{q},get(data,'filename')),
       found=1;
    end
  end
  if found==0,  
    database.system_output{end+1}=j(i);
    database.output_links{end+1}=links(j(i),:);
    database.mapping_name{end+1}=m.system.mapping{links(j(i),1)}.name;
    database.file{end+1}=get(data,'filename');
    database.error_type{end+1}='mse';
    database.value{end+1}= err(i);
  end  
end

opt.errors_database=database;
set(m,'opt',opt);

if isa(varargin{1},'dataset'),
  m=add_data(m,old_data,get(m,'T'));
end

assignin('caller',inputname(1),m);


