function m=mamdani(varargin)
%MAMDANI build a mamdami object
%    
%    M=MAMDANI(VARARGIN) 
%    
%    The class defines the following methods:
%    
%      ADD_RULES: add specified number of rules
%      ADD_SETS: Add fuzzy sets along one or more dimension
%          of the space
%      CHECK: checks the consistency of all the field of a
%          mamdani object
%      DENORMALIZE: denormalises the model
%      DISPLAY: Display an object of class mamdani
%      EVAL: computes the value of the model
%      GET: gets the value of the attribute of an object
%      IDENTIFY: identifies a fuzzy model from data
%      JACOB_INPUTS: computes the jacobian of the model
%      JACOB_PARAMS: computes the jacobian of the model
%      MEMBERSHIP: Compute the degree of fullfilment of the
%          rules of a mamdani function
%      NORMALISE: normalises the model M
%      PLOT: performs a plot of the a mamdani model
%      REM_RULES: remove the specified rules from the
%          mamdani object
%      REM_SETS: remove the specified sets from the mamdani
%          object
%      RULES_PARSER: parses rules in order to populate the
%          rules base of a mamdani model
%      SET: set object properties
%      SETS_GRID: Remove every fuzzy sets and replace them
%          by evenly spaced ones
%    
%    See also: 
%    
%    

%MAN_PAGE_BEGIN
%
%   @purpose	build a mamdami object
%
%   @synopsis	m=mamdani(varargin)
%   @description  
%
%   @see 
%
%MAN_PAGE_END

% By Antoine Duchateau. All Rights Reserved.
% Written: 26/05/99

error(checkargs(varargin,[0 3],'any','numeric','numeric'));

m=[];
if nargin==0                   %if no arguments build an empty object
	m.rls = [];
  	m.mfs={};
  	m.ling={};
  	m.n_rules = 0;
  	m.model_code = {};
  	m.varnames = {};
  	
  	f=mapping;
  	m=class(m,'mamdani',f);
  	
elseif nargin==1,              %if one argument
	if isa(varargin{1},'mamdani') & isa(varargin{1}.mapping ,'mapping'),   %if type mamdani clone it
	    m=varargin{1};
	elseif isa(varargin{1},'mapping') & ~ isa(varargin{1},'mamdani'), %if type mapping add the fields
	    m.rls = [];
  		m.n_rules = 0;
  		m.model_code = {};
  		
  	    f=varargin{1};
        m.mfs=cell(1,get(f,'n_in')+get(f,'n_out'));
        m.ling=cell(1,get(f,'n_in')+get(f,'n_out'));
        m.varnames=cell(1,get(f,'n_in')+get(f,'n_out'));
        for i=1:get(f,'n_in'),
        	m.varnames{i} = ['input ' num2str(i)];
        end
        for i=get(f,'n_in')+(1:get(f,'n_out')),
        	m.varnames{i} = ['output ' num2str(i)];
        end 
  		
  		m=class(m,'mamdani',f);
	else                              %if it is something else (usually for update purposes)
	    m.rls = [];
  		m.mfs={};
  		m.n_rules = 0;
  		m.model_code = {};
  		
  	    f=mapping;
	  	
	 	arg = struct(varargin{1});
	  	
	  	if isfield(arg,'mapping'),
	    f=mapping(arg.mapping);
	    arg=rmfield(arg,'mapping');
	    
	    fn=fieldnames(m);
	    for i=1:size(fn,1),
	      if isfield(arg,fn{i}),
		  m=setfield(m,fn{i},getfield(arg,fn{i}));
	      end
	    end  
	  end
	  m=class(m,'mamdani',f);
	end
elseif nargin>1,
  	f=mapping(varargin{:});
  	
  	m.rls = [];
  	m.mfs = cell(1,get(f,'n_in')+get(f,'n_out'));
  	m.ling = cell(1,get(f,'n_in')+get(f,'n_out'));
  	m.varnames=cell(1,get(f,'n_in')+get(f,'n_out'));
  	for i=1:get(f,'n_in'),
       	m.varnames{i} = ['input ' num2str(i)];
    end
    for i=1:get(f,'n_out'),
      	m.varnames{get(f,'n_in')+i} = ['output ' num2str(i)];
    end 
  		
  		m.n_rules = 0;
  	m.model_code = {};
  	
  m=class(m,'mamdani',f);
end



