function set(m,varargin);
%SET set object properties
%    
%    General pupose function for  setting the values of the
%    fields of a mamdani object. For setting  the rules, use
%    the ADD_RULES, REM_RULES and ADD_SETS function. This
%    method extends the 'set' method defined in the mapping
%    class. 
%    
%    M=SET(M,LABEL1,VALUE1,LABEL2,VALUE2,...) sets the value
%    VALUE of the attribute LABEL associated to the object M.
%    The following codes are recognised:
%    
%      NAME: sets the name of the object
%      N_IN: sets the number of inputs of the model. This
%          sets the saturation level of the inputs to  -Inf,
%          Inf.
%      N_OUT: sets the number of outputs of the model
%      USERDATA: sets the 'userData' field
%      OPT: sets the 'opt' field
%      DATE: sets the date of creation of the object
%      LIMITS: sets the limits of the mapping
%      OPTIMPARAMS: sets the indices of the parameters to be
%          optimised
%      MODEL_CODE: sets the type of rules associated to the
%          mapping model
%      RLS: sets the fuzzy sets associated to the mapping
%          model
%      RL: sets one fuzzy set associated to the mapping
%          model
%      MFS: sets the definition of the rules of the mapping
%          model
%      MF: sets the definition of one rule of the mapping
%          model
%      LING: sets the linguistical representation of the
%          sets (the name of the sets)
%      VARNAMES: sets the name of the variables
%      MFTYPE: sets the type of a set. VALUE is 3 elements
%          cell array {a b c} where a is the number of the
%          input, b is the index of the set and c is the
%          type ('constant', 'trapezoidal', 's-shaped' or
%          'gaussian')
%      PARAMS: sets every parameters to be optimised
%          providing a vector
%    
%    See also: GET, ADD_DYNAMICS, ADD_DATA, ADD_RULES
%    
%    

%MAN_PAGE_BEGIN
%
%		@purpose	set object properties. General pupose function for 
%		setting the values of the fields of a mamdani object. For setting 
%		the rules, use the <code>add_rules</code>, <code>rem_rules</code> and
%		<code>add_sets</code> function.
%		This method
%		extends the 'set' method defined in the mapping class. 
%
%		@synopsis		m=set(m,label1,value1,label2,value2,...)
%		@description	sets the value <code>value</code> of the attribute <code>label</code>
%		associated to the object <code>m</code>. The following codes are recognised:
%<dl>
%<dt>			name		 <dd>		sets the name of the object
%<dt>			n_in		 <dd>		sets the number of inputs of the model. This
%													sets the saturation level of the inputs to 
%													-Inf, Inf.
%<dt>			n_out		 <dd>		sets the number of outputs of the model
%<dt>			userData <dd>		sets the 'userData' field
%<dt>			opt			 <dd>		sets the 'opt' field
%<dt>			date		 <dd>		sets the date of creation of the object
%<dt>	 limits	 <dd>				sets the limits of the mapping
%<dt>	 optimparams	 <dd>		sets the indices of the parameters to be optimised
%<dt> model_code   <dd>   sets the type of rules associated to the
%                         mapping model
%<dt> rls  <dd>           sets the fuzzy sets associated to the mapping
%                         model
%<dt> rl  <dd>           sets one fuzzy set associated to the mapping
%                         model
%<dt> mfs  <dd>       sets the definition of the rules of the mapping model
%<dt> mf  <dd>       sets the definition of one rule of the mapping model
%<dt> ling  <dd>       sets the linguistical representation of the sets (the name of the sets)
%<dt> varnames  <dd>       sets the name of the variables
%<dt> mftype  <dd>       sets the type of a set. <CODE>value</CODE> is 3 elements cell array
%						{a b c} where a is the number of the input, b is the index of the set
%						and c is the type ('constant', 'trapezoidal', 's-shaped' or 'gaussian')
%<dt> params  <dd>       sets every parameters to be optimised providing a vector
%</dl>
%	 
%
%		@see get, add_dynamics, add_data, add_rules
%
%MAN_PAGE_END		


ni = nargin;
if (ni<3)|(ni/2 == floor(ni/2)),
	error('Wrong number of inputs');
end

if ~isa(m,'mamdani'),
	
	% Call built-in SET. Handles calls like set(gcf,'user',linears) 
	builtin('set',m,varargin{:});
	return

end

% For each couple of inputs
for i=1:(ni - 1)/2,
	name = varargin{i*2-1};
	value = varargin{i*2};
	
	switch name,
			
	case 'rl',
	error(checkval(value,'cell', 'linear property'));
	error(checkargs(value, 2, 'numeric', 'numeric'));
	m.rls(value{1},:) = value{2};	

	case 'mf',
	error(checkval(value,'cell', 'linear property'));
	error(checkargs(value, 3, 'numeric', 'numeric', 'numeric'));
	m.mfs{value{1}}(value{2},2:end) = value{3};	

	case 'mftype',
	error(checkval(value,'cell', 'linear property'));
	error(checkargs(value, 3, 'numeric', 'numeric', 'char'));
	
	switch lower(value{3}),
		case 'constant',
		code = 0;
		
		case 'trapezoidal',
		code = 1;
		
		case 'gaussian',
		code = 2;
		
		case 's-shaped',
		code = 3;
		
		otherwise
		error('Unrecognized rule type');
	end
	
	m.mfs{value{1}}(value{2},1) = code;	

	case 'rls',
		if iscompat(value,zeros(m.n_rules, get(m,'n_in'))),
			m.rls = value;
		else
			error(['Size of the new value (' num2str(size(value)) ') for rls is not adequate.' 13 'It should be ' num2str([m.n_rules get(m,'n_in')])]);
		end

	case 'mfs',
		m.mfs = value;
		
	case 'ling',
		m.ling = value;
		
	case 'model_code',
		if isequal(size(value),[1 2]),
			m.model_code = value;
		else
			error(['Size of the new value (' num2str(size(value)) ') for model_code is not adequate']);
		end
	
	case 'optimparams',
		m.optimparams = value;
	
	case 'varnames',
		m.varnames = value;

	
	otherwise
		m.mapping = set(m.mapping, name, value);
	
	end
	
end

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

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function out=sub_params(select)

out = zeros(m.n_rules * (get(m,'n_in') + get(m,'n_out') +1) * get(m,'n_in'),1)

beg_mark = 1;
end_mark = get(m,'n_in') * m.n_rules;

if bitand(1,select),
	out(beg_mark:end_mark) = 1;
end

beg_mark = end_mark + 1;
end_mark = end_mark + get(m,'n_in') ^ 2 * m.n_rules;


if bitand(2,select), 
	out(beg_mark:end_mark) = 1;
end

beg_mark = end_mark + 1;
end_mark = end_mark + get(m,'n_in') * (1 + get(m,'n_out')) * m.n_rules;

if bitand(4,select),
	out(beg_mark:end_mark) = 1;
end

end_mark = beg_mark - 1;

if ~bitand(8,select),
	for i=1:m.n_rules,
		beg_mark = end_mark + get(m,'n_in') * get(m,'n_out') + 1;
		end_mark = end_mark + get(m,'n_in') * (1 + get(m,'n_out'));
		
		out(beg_mark:end_mark) = 0;
	end
end
