gusucode.com > 模糊控制工具箱 fuzzy logic toolbox源码程序 > fuzzy/fuzzy/anfisedit.m

    function anfisedit(action);
%ANFISEDIT anfis GUI tool.
%   The ANFIS Editor is used to create, train, and test a Sugeno fuzzy system. 
%
%   See also FUZZY, MFEDIT, RULEEDIT, RULEVIEW, SURFVIEW.

%   Kelly Liu, Dec. 96  N. Hickey Jan. 2001
%   Copyright 1994-2004 The MathWorks, Inc.
%   $Revision: 1.42.4.3 $  $Date: 2004/04/10 23:15:22 $

if nargin<1,
    % Open up an untitled system.
    newFis=newfis('Untitled', 'sugeno');
    newFis=addvar(newFis,'input','emptyinput1',[0 1],'init');
    newFis=addvar(newFis,'output','output1',[0 1],'init');
    action=newFis;
end

if isstr(action),
    if action(1)~='#',
        % The string "action" is not a switch for this function, 
        % so it must be a disk file
        fis=readfis(action);
        if ~strcmp(fis.type, 'sugeno') | length(fis.output)>1
            disp('anfis editor only works on Sugeno systems with one output');
            return;
        else
            action='#initialize';
        end
    end
else
    % For initialization, the fis is passed in as the parameter
    fis=action;
    action='#initialize';
end;
%=======initialize anfisedit============
switch action
case '#initialize',
    if isfield(fis, 'input')
        numInputs=length(fis.input);
    else
        numInputs=0;
    end
    
    if isfield(fis, 'output')
        numOutputs=length(fis.output);
    else
        numOutputs=0;
    end
    if isfield(fis, 'rule')
        numRules=length(fis.rule);
    else
        numRules=0;
    end
    
    numInputMFs = zeros(1,numInputs);
    for i=1:numInputs
        numInputMFs(i)=length(fis.input(i).mf);
    end
    totalInputMFs=sum(numInputMFs);
    fisnodenum=numInputs+2*totalInputMFs+2*numRules+2+1;
    infoStr=['Number of nodes: ' num2str(fisnodenum)];
    
    fisName=fis.name;
    nameStr=['Anfis Editor: ' fisName];
    savefis{1}=fis;
    figNumber=figure( ...
        'Name',nameStr, ...
        'Units', 'pixels', ...
        'Color', [.75 .75 .75],...
        'NumberTitle','off', ...
        'MenuBar','none', ...
        'IntegerHandle','off',...
        'Tag', 'anfisedit',...
        'Userdata', savefis,...
        'Visible','off', ...
        'DockControls', 'off');
    
    
    %====================================
    % The MENUBAR items
    
    % Call fisgui to create the menubar items
    fisgui #initialize
    
    axes( ...
        'Units','normalized', ...
        'Position',[0.10 0.55 0.65 0.38]);
    
    %===================================    
    left=0.03;
    right=0.75;
    bottom=0.05;
    labelHt=0.03;
    spacing=0.005;
    frmBorder=0.012;
    %======Set up the anfis info Window==========
    top=0.5;    
    % First, the all the frames 
    frmPos=[0 0 1 .47];
    frmHandle=LocalBuildFrmTxt(frmPos, '', 'frame', 'mainfrm'); 
    frmPos=[.01 .115 .292 .34];
    frmHandle=LocalBuildFrmTxt(frmPos, '', 'frame', 'datafrm'); 
    midfrmwidth=.25;
    frmPos=[.315 .115 midfrmwidth .34];
    frmHandle=LocalBuildFrmTxt(frmPos, '', 'frame', 'midbtnfrm'); 
    frmPos=[.575 .115 .195 .34];
    frmHandle=LocalBuildFrmTxt(frmPos, '', 'frame', 'rightbtnfrm'); 
    frmPos=[.78 .115 .21 .34];
    frmHandle=LocalBuildFrmTxt(frmPos, '', 'frame', 'infofrm'); 
    frmPos=[.01 .0218 .62 .073];
    frmHandle=LocalBuildFrmTxt(frmPos, '', 'frame', 'statusfrm'); 
    frmPos=[.64 .0218 .35 .073];
    frmHandle=LocalBuildFrmTxt(frmPos, '', 'frame', 'statusfrm'); 
    
    %======load data===============
    left=.02;
    labelPos=[.05+left .42 .15 .042];    
    lableHndl=LocalBuildFrmTxt(labelPos, '   Load data', 'text', 'lable2');
    width=.13;
    height=.04;
    left1=left+.14;
    width1=.13;
    height1=.04;
    labelPos=[left .38 .1 .042];    
    lableHndl=LocalBuildFrmTxt(labelPos, 'Type:', 'text', 'lable2');
    labelPos=[left1 .38 .1 .042];    
    lableHndl=LocalBuildFrmTxt(labelPos, 'From:', 'text', 'lable2');
    labelPos=[left .33 width height];    
    mcwPos=[left1 .30 width1 height1];
    lableHandle=LocalBuildUi(labelPos, 'radio', 'anfisedit #radioloadtype', 'Training', 'dattype');
    set(lableHandle, 'Max', 1, 'Value', 1);
    % Then the editable text field
    
    mcwHndl=LocalBuildUi(mcwPos, 'radio', 'anfisedit #radioloadfrom', 'disk', 'trndatin');
    set(mcwHndl, 'Max', 1, 'Value', 1);
    labelPos=[left .28 width height];    
    mcwPos=[left1 .23 width1 height1];
    lableHandle=LocalBuildUi(labelPos,  'radio', 'anfisedit #radioloadtype', 'Testing','dattype');
    set(lableHandle, 'Max', 1, 'Min', 0);
    % Then the editable text field
    
    mcwHndl=LocalBuildUi(mcwPos, 'radio', 'anfisedit #radioloadfrom', 'worksp.', 'trndatin');
    
    labelPos=[left .23 width height];    
    lableHandle=LocalBuildUi(labelPos,  'radio', 'anfisedit #radioloadtype', 'Checking','dattype');
    set(lableHandle, 'Max', 1, 'Min', 0);
    
    labelPos=[left .18 width height];    
    lableHandle=LocalBuildUi(labelPos,  'radio', 'anfisedit #radioloadtype', 'Demo','dattype');
    set(lableHandle, 'Max', 1, 'Min', 0);
    
    %   set(mcwHndl, 'Max', 1);
    mcwPos=[left .13 .13 height]; 
    %=======The Open Training set button==============
    delHndl=LocalBuildUi(mcwPos, 'pushbutton', 'anfisedit #opentrn', 'Load Data...', 'opentrn');
    mcwPos=[left+.14 .13 .13 height]; 
    delHndl=LocalBuildUi(mcwPos, 'pushbutton', 'anfisedit #cleardata', 'Clear Data', 'opentrn');
    
    
    %========Set up the Status Window ==================     
    
    % Then the status text field
    mcwPos=[0.02 0.04 0.55 0.040];
    mcwHndl=LocalBuildUi(mcwPos, 'text', '', '', 'status');
    %==========set genfis area============================
    % The text label
    labelPos=[.34 .42 .18 .042];      
    lableHndl=LocalBuildFrmTxt(labelPos, '   Generate FIS', 'text', 'lable2');
    left=.33;
    width=.225;
    height=.04;
    labelPos=[left .35  width height];    
    lableHandle=LocalBuildUi(labelPos, 'radio', 'anfisedit #radiogenfis', 'Load from disk', 'genfis');
    labelPos=[left .30  width height];    
    lableHandle=LocalBuildUi(labelPos, 'radio', 'anfisedit #radiogenfis', 'Load from worksp.', 'genfis');
    labelPos=[left .25  width height];    
    lableHandle=LocalBuildUi(labelPos, 'radio', 'anfisedit #radiogenfis', 'Grid partition', 'genfis');
    set(lableHandle, 'Max', 1, 'Value', 1);
    labelPos=[left .20  width height];    
    lableHandle=LocalBuildUi(labelPos, 'radio', 'anfisedit #radiogenfis', 'Sub. clustering', 'genfis');
    % Then the editable text field
    labelPos=[left .13  width height];    
    
    mcwHndl=LocalBuildUi(labelPos, 'pushbutton', 'anfisedit #genfis', 'Generate FIS ...', 'genfisbtn');
    
    
    %====================================
    % Information for anfis
    left=0.80;
    btnWid=0.15;
    top=.55;
    frmBorder=0.02;
    frmPos=[left-frmBorder .5 btnWid+2*frmBorder .46];
    frmHandle=LocalBuildFrmTxt(frmPos, '', 'frame', '');
    labelPos=[left .95 .15 .030];    
    lableHndl=LocalBuildFrmTxt(labelPos, '  ANFIS Info.', 'text', 'lable2');
    % Then the info text field
    mcwPos=[left .65 .15 .24]; 
    textHndl=LocalBuildFrmTxt(mcwPos, infoStr, 'text', 'Comments');
    mcwPos=[left .57 .15 .04]; 
    
    % Create the Structure button
    StrctBtnHndl=LocalBuildUi(mcwPos, 'pushbutton', '', 'Structure', 'plotstrc');
    set(StrctBtnHndl,'CallBack', @LocalStructureBtnCallback);
    
    set(StrctBtnHndl, 'Backgroundcolor', [0.75 0.75 0.75], 'HorizontalAlignment', 'center'); 
    mcwPos=[left .52 .15 .04]; 
    delHndl=LocalBuildUi(mcwPos, 'pushbutton', 'cla', 'Clear Plot', '');
    set(delHndl, 'HorizontalAlignment', 'center');
    
    %=========The Train fis=============
    labelPos=[.6 .42 .14 .042];    
    lableHndl=LocalBuildFrmTxt(labelPos, '   Train FIS', 'text', 'lable2');
    frmBorder=0.02;
    btnHt=0.03;
    yPos=top+.31;
    left=.595;
    width=.16;
    height=.04;
    labelPos=[left .39  width height];    
    lableHandle=LocalBuildFrmTxt(labelPos, 'Optim. Method:','text', '');
    labelPos=[left .35  width height];    
    lableHandle=LocalBuildUi(labelPos, 'popupmenu', '', {'backpropa', 'hybrid'}, 'trnmethod');
    set(lableHandle, 'value', 2);
    labelPos=[left .295  width height];    
    lableHandle=LocalBuildFrmTxt(labelPos, 'Error Tolerance:','text', '');
    labelPos=[left .26  width height];    
    lableHandle=LocalBuildUi(labelPos, 'edit', 'anfisedit #errorlim', '0', 'errlim');
    set(lableHandle, 'backgroundcolor', 'white');
    labelPos=[left .22  width height];    
    lableHandle=LocalBuildFrmTxt(labelPos,'Epochs:',  'text','');
    set(lableHandle, 'Max', 1, 'Value', 1);
    labelPos=[left .19  width height];    
    lableHandle=LocalBuildUi(labelPos, 'edit', 'anfisedit #reset', '3', 'epoch');
    set(lableHandle, 'backgroundcolor', 'white', 'Max', 1);
    % Then the editable text field
    
    labelPos=[left .13  width height];    
    
    mcwHndl=LocalBuildUi(labelPos, 'pushbutton', 'anfisedit #start', 'Train Now', 'startbtn');
    %=========The test fis=============
    labelPos=[.82 .42 .14 .042];    
    lableHndl=LocalBuildFrmTxt(labelPos, '   Test FIS', 'text', 'lable2');
    frmBorder=0.02;
    left=.79;
    width=.19;
    height=.04;
    labelPos=[left .34  width height];    
    lableHandle=LocalBuildFrmTxt(labelPos, 'Plot against:', 'text', '');
    labelPos=[left .30  width height];    
    lableHandle=LocalBuildUi(labelPos, 'radio', 'anfisedit #radiotest', 'Training data', 'test');
    set(lableHandle, 'Max', 1, 'Value', 1);
    labelPos=[left .25  width height];    
    lableHandle=LocalBuildUi(labelPos, 'radio', 'anfisedit #radiotest', 'Testing data', 'test');
    labelPos=[left .2  width height];    
    set(lableHandle, 'Max', 1, 'Value', 0);
    lableHandle=LocalBuildUi(labelPos, 'radio', 'anfisedit #radiotest', 'Checking data', 'test');
    set(lableHandle, 'Max', 1, 'Value', 0);
    labelPos=[left .205  width height];    
    % Then the editable text field
    labelPos=[left .13  width height];    
    
    mcwHndl=LocalBuildUi(labelPos, 'pushbutton', 'anfisedit #test', 'Test Now', 'testbtn');
    
    %=======The Close button=============
    closeHndl=LocalBuildBtns('pushbutton', 0, 'Close', 'fisgui #close', 'close');
    helpHndl=LocalBuildBtns('pushbutton', 0, 'Close', 'anfisedit #help', 'help');
    pos=get(helpHndl, 'Position');
    pos(1)=pos(1)-.17;
    set(helpHndl, 'Position', pos, 'String', 'Help');
    %====================================
    % The MENUBAR items
    % First create the menus standard to every GUI
    
    LocalEnableBtns(fis(1));   
    textHndl=findobj(figNumber, 'Tag', 'Comments');
    %textstr=get(textHndl, 'String');
    if isfield(fis, 'input') & isfield(fis, 'output')
        textstr={['# of inputs: ' num2str(length(fis(1).input))],  ['# of outputs: ' ...
                    num2str(length(fis(1).output))], [ '# of input mfs: '], [ num2str(getfis(fis(1), 'inmfs'))]};
    else
        textstr = '';
    end
    set(textHndl, 'String', textstr);
    
    % Finally make figure visible and protect it
    set(figNumber,'Visible','on','HandleVisibility','callback')
    
case '#update',
    %==========updata anfis information==========================
    WatchFig=watchon;
    figNumber = gcbf;
    oldfis=get(figNumber,'UserData');
    fis=oldfis{1};
    % Clear the current variable plots and redisplay
    textHndl=findobj(figNumber, 'Tag', 'Comments');
    %textstr=get(textHndl, 'String');
    textstr={['# of inputs: ' num2str(length(fis.input))], ['# of outputs: ' ...
                num2str(length(fis.output))],  ['# of input mfs: '], [ num2str(getfis(fis(1), 'inmfs'))]};
    set(textHndl, 'String', textstr);
    LocalEnableBtns(fis(1));
    if length(fis)<=1
        undomenu=findobj(figNumber, 'Tag', 'undo');
        set(undomenu, 'Enable', 'off');
    end
    watchoff(WatchFig);
    %========start/stop training==============
case '#start',
    figNumber = gcbf;
    oldfis=get(figNumber, 'UserData');
    fis=oldfis{1};
    chkvector=[];
    if ~isfield(fis, 'trndata')| isempty(fis.trndata(1))
        msgbox('no training data yet');
    elseif isempty(fis.input(1).mf)
        msgbox('No membership functions! Use mf editor or genfis button to generate membership functions');
    elseif ~isfield(fis, 'rule') | isempty(fis.rule)
        msgbox('No rules yet! Use rule editor or genfis button to generate rules.');
    else
        if isfield(fis, 'chkdata')
            testdata=fis.chkdata;
        else
            testdata=[];
        end
        EpochHndl=findobj(figNumber, 'Tag', 'epoch');
        numEpochs=str2double(get(EpochHndl, 'String'));
        if isempty(numEpochs)
            numEpochs=0;
        end
        txtHndl=findobj(figNumber, 'Tag', 'status');
        stopHndl=findobj(figNumber, 'Tag', 'startbtn');
        stopflag=get(stopHndl, 'String');
        fismat1=fis;
        errHndl=[];
        if strcmp(stopflag, 'Train Now')
            %=========init plot for training==========
            cla;
            set(stopHndl, 'String', 'Stop');
            errHndl=findobj(figNumber, 'Tag', 'errline');
            chkHndl=findobj(figNumber, 'Tag', 'chkline');
            errLimHndl=findobj(figNumber, 'Tag', 'errlim');
            methodHndl=findobj(figNumber, 'Tag', 'trnmethod');
            method=get(methodHndl, 'value');
            errlim=str2double(get(errLimHndl, 'String'));
            xlabelHndl=get(gca, 'XLabel');
            ylabelHndl=get(gca, 'YLabel');
            set(xlabelHndl, 'String', 'Epochs');
            set(ylabelHndl, 'String', 'Error');
            if isempty(errlim)
                errlim=0;
            end
            if isempty(errHndl)|length(get(errHndl, 'Xdata'))~=numEpochs
                if length(get(errHndl, 'Xdata'))~=numEpochs
                    delete(errHndl)
                end
                errHndl=line([1:numEpochs], [1:numEpochs], 'linestyle', 'none',...
                    'marker', '*', 'Tag', 'errline');
            end
            if isfield(fis, 'chkdata') & ~isempty(fis.chkdata) & (isempty(chkHndl)|length(get(chkHndl, 'Xdata'))~=numEpochs)
                if length(get(chkHndl, 'Xdata'))~=numEpochs
                    delete(chkHndl)
                end
                chkHndl=line([1:numEpochs], [1:numEpochs], 'linestyle', 'none',...
                    'marker', '.', 'MarkerSize', 10, 'Tag', 'chkline');
                chkvector=zeros(numEpochs,1);
            end
            errvector=zeros(numEpochs,1);
            %========start training=============
            testHndl=findobj(gcbf, 'Tag', 'testbtn');
            set(testHndl, 'Enable', 'off');
            try
                for i=1:numEpochs
                    [fismat1, trn_err, stepSize, fismat2, chk_err]=anfis(fis.trndata, fismat1, 2, NaN, testdata, method-1);
                    if ~isempty(chkHndl)
                        chkvector(i)=chk_err(1);
                        set(chkHndl, 'Ydata', chkvector);
                    end
                    errvector(i)=trn_err(1);
                    if ~isempty(errHndl)
                        set(errHndl, 'Ydata', errvector);
                        drawnow
                    end
                    txtStr={['Epoch ' num2str(i) ':error= ' num2str(trn_err(1))]};
                    set(txtHndl, 'String', txtStr);
                    stopflag=get(stopHndl, 'String');
                    if strcmp(stopflag, 'Train Now')| trn_err(1)<=errlim
                        break;
                    end
                end   %end of if Satrt
            catch
                error(lasterr)
            end
            title('Training Error');
            set(testHndl, 'Enable', 'on');
            set(stopHndl, 'String', 'Train Now');
        else
            %=========reset start button=========
            set(stopHndl, 'String', 'Train Now');
        end
        % end of for loop
        if ~isempty(chkvector)
            trnedfis=fismat2;
        else
            trnedfis=fismat1;
        end
        trnedfis.trndata=fis.trndata;
        if isfield(fis, 'tstdata');
            trnedfis.tstdata=fis.tstdata;
        end 
        if isfield(fis, 'chkdata');
            trnedfis.chkdata=fis.chkdata;
        end 
        %      set(gcf, 'UserData', trnedfis);
        WatchFig=watchon;
        %===========updata fis for all the fis editors=======
        updtfis(figNumber,trnedfis,[2 3 4 5 6]);
        pushundo(gcbf, trnedfis);
        watchoff(WatchFig);
    end
    %========take training input data from commandline workspace
case '#trndatin',
    figNumber = gcbf;
    fis=get(figNumber, 'UserData');
    fis=fis(1);
    trndatinHndl=findobj(figNumber, 'Tag', 'trndatin');
    trndatinTxt=get(trndatinHndl, 'String');
    trnData=[];
    trnData=evalin('base', trndatinTxt, '[]');
    if isempty(trnData),
        msgbox('No such variable (or variable is empty)')
    else
        fis.trndata(:,1:length(fis.input))=trnData
    end   
    %========take training output data from commandline workspace
    
    
    
case '#genfis',
    figNumber=gcbf;
    genHndl=findobj(figNumber, 'Tag', 'genfis');
    n=get(genHndl, 'Value');
    indexStr='';
    for i=1:length(n)
        if n{i}~=0
            indexStr=get(genHndl(i), 'String');
            break;
        end
    end
    oldfis=get(figNumber,'UserData');
    fis=oldfis{1};
    if ~isfield(fis, 'trndata');
        trnData=[];
    else
        trnData=fis.trndata;
    end
    fismat=[];
    param=[];
    switch indexStr
    case 'Grid partition'
        %========use grid genfis===========
        if isempty(trnData)
            msgbox('Load training data in order to generate ANFIS');
            return
        end
        mfType=getfis(fis, 'inmftypes');   
        dlgFig=findobj('type', 'figure', 'Tag', 'genfis1dlg');
        
        if isempty(dlgFig)
            param=gfmfdlg('#init', fis);
        else
            figure(dlgFig);
        end
        if ~isempty(param)
            mfType=char(param(2));
            outType=char(param(3));
            
            inmflist=str2num(param{1});  % don't use STR2DOUBLE here (can be multi-valued)
            if ~isempty(inmflist)&length(inmflist)~=length(fis.input)
                inmflist(end+1:length(fis.input))=inmflist(end);
            end
            if isempty(inmflist)
                inmflist=[2];
            end
            if isempty(mfType)
                % for i=1:length(fis.input)
                %     mfType(i,:)='gbellmf';
                % end
                mfType='gbellmf';
            end
            
            fismat=genfis1(trnData, inmflist, mfType, outType);
            %in case user changed the following from mfedit or fiseditor
            fismat.type=fis.type;
            fismat.name=fis.name;
            fismat.andMethod = fis.andMethod;
            fismat.orMethod = fis.orMethod;
            fismat.defuzzMethod =fis.defuzzMethod;
            fismat.impMethod = fis.impMethod;
            fismat.aggMethod = fis.aggMethod;
        end
        
    case 'Sub. clustering'
        %========use cluster genfis=====================
        if isempty(trnData)
            msgbox('Load training data in order to generate ANFIS');
            return
        end
        param=inputdlg({'Range of influence:', 'Squash factor:','Accept ratio:','Reject ratio:'},...
            'Parameters for clustering genfis', 1,...
            {'.5', '1.25', '.5', '.15'});
        
        if ~isempty(param)
            watchon;
            fismat=genfis2(trnData(:,1:length(fis.input)), trnData(:,length(fis.input)+1), ...
                str2double(param{1}),[], [str2double(param(2:4));0]');
            fismat.name=fis.name;
            watchoff   
        end
    case 'Load from disk'
        [fname, fpath]=uigetfile('*.fis'); 
        if fname ~=0
            fismat=readfis([fpath fname]);
            %make sure loading a sugeno type fis structure
            if ~strcmp(fismat.type, 'sugeno')
                msgbox('Not a sugeno type, no fis structure is loaded');
                fismat=[];
            end
        end 
    case 'Load from worksp.'
        vname=[];
        vname=inputdlg('input variable name');
        
        if ~isempty(vname)
            fismat=evalin('base', char(vname), '[]');
        end
        if isempty(fismat),
            msgbox('No such variable (or variable is empty)')
        else
            if ~strcmp(fismat.type, 'sugeno')
                msgbox('Not a sugeno type, no fis structure is loaded');
                fismat=[];
            end
        end   
    end
    if ~isempty(fismat)
        if isfield(fis, 'tstdata')
            fismat.tstdata=fis.tstdata;
        end 
        if isfield(fis, 'chkdata')
            fismat.chkdata=fis.chkdata;
        end 
        set(figNumber, 'Name',['Anfis Editor: ' fismat.name]); 
        fismat.trndata=trnData;
        textHndl=findobj(gcbf, 'Tag', 'Comments');
        textstr={['# of input: ' num2str(length(fismat.input))], ['# of outputs: ' ...
                    num2str(length(fismat.output))],  ['# of input mfs: '], [num2str(getfis(fismat, 'inmfs'))]};
        set(textHndl, 'String', textstr);
        cmtHndl=findobj(gcbf, 'Tag', 'status');
        set(cmtHndl, 'String', 'a new fis generated');
        %      set(figNumber, 'Userdata', fismat);
        %========updata all the fis editors===============
        %       set(textHndl, 'String', 'New fis generated');
        pushundo(figNumber, fismat);
        updtfis(figNumber,fismat,[2 3 4 5]);
        LocalEnableBtns(fismat);  
    end   
    
    
    %========open training set file================                
case '#opentrn',
    
    % open an existing file
    oldfis=get(gcbf,'UserData'); 
    fis=oldfis{1};
    typeHndl=findobj(gcbf, 'Tag', 'dattype');
    fromHndl=findobj(gcbf, 'Tag', 'trndatin');
    for i=1:length(typeHndl)
        if get(typeHndl(i), 'Value')==1 
            thistype=get(typeHndl(i), 'String');
            switch thistype
            case 'Testing',
                type ='test';
            case 'Training',
                type='train';
            case 'Checking',
                type='check';
            otherwise,
                type='demo';
            end
            break
        end
    end
    inNum=length(fis.input);
    outNum=length(fis.output);
    varname=[];
    if get(fromHndl(2), 'value') ==0 & ~strcmp(type, 'demo')
        %from workspace
        vname=[];
        trndata=[];
        vname=inputdlg('input variable name');
        dtloaded=0;
        if ~isempty(vname)
            trndata=evalin('base', char(vname), '[]');
            if isempty(trndata),
                msgbox('No such variable (or variable is empty)')
            else
                dtloaded=1;
            end   
        end     
     elseif ~strcmp(type, 'demo')
        %from file
        [fname, fpath]=uigetfile('*.dat'); 
        dtloaded=0;
        trndata=[];
        if isstr(fname)&isstr(fpath)
           trndata=load([fpath fname]);
           dtloaded=1;
        end 
     else
        %demo data
        load('fuzex1trn.dat');
        load('fuzex1chk.dat');
        trndata=fuzex1trn;
        tstdata=fuzex1chk;
        chkdata=[];
        fis=genfis1(trndata, 4, 'gaussmf');
        fis.trndata=trndata;
        fis.tstdata=tstdata;
        fis.chkdata=chkdata;
        dtloaded=1;
        inNum = size(trndata,2)-1;
    end  
    if ~isempty(trndata) & ~strcmp(type, 'demo'),
        if size(trndata, 2)<=1
            msgbox('Data needs to be at least two columes! No data is loaded.')
            clear trndata;
            statueHndl=findobj(gcbf, 'Tag', 'status');
            set(statueHndl, 'String', [type ' data is not loaded']);
            return;
        end
        inNumNew=size(trndata,2)-1;
        if inNumNew~=inNum 
            if  ~strcmp(fis.input(1).name,'emptyinput1') | strcmp(type,'test')==1 | strcmp(type,'check')==1
                msgbox({['The number of inputs for ' type ' data is ' num2str(inNumNew)],...
                        ['The number of inputs for current fuzzy system is ' num2str(inNum)],...
                        ['No new ' type ' data is loaded']});
                qustout='No';
            else
                qustout='Yes';
            end
            if strcmp(qustout, 'Yes')==1
                if strcmp(fis.input(1).name,'emptyinput1'),
                    fis.input(1).name = 'input1';
                end
                dtloaded=1;
                if inNumNew>inNum
                    for i=inNum+1:inNumNew
                        fis=addvar(fis,'input',['input' num2str(i)],[0 1],'init');
                    end
                else
                    for i=inNum:-1:inNumNew+1
                        fis=rmvar(fis,'input', i, true);
                    end 
                end
                inNum=length(fis.input);
            else
                dtloaded=0;
                clear trndata;
                statueHndl=findobj(gcbf, 'Tag', 'status');
                
                set(statueHndl, 'String', 'Training data is not loaded');
            end
        end
    end
    if dtloaded==1
        lineMarker=['o', '.', '+'];
        colorIndex=1;
        titleStr='Demo Data';
        switch type
        case 'train'
            fis.trndata=trndata;
            titleStr='Training Data (ooo)';
        case 'test'
            fis.tstdata=trndata;
            titleStr='Testing Data (...)';
            colorIndex=2;
        case 'check'
            fis.chkdata=trndata;
            titleStr='Checking Data (+++)';
            colorIndex=3;
        end 
        updtfis(gcbf,fis,[6]);
        textHndl=findobj(gcbf, 'Tag', 'Comments');
        textstr={['# of inputs: ' num2str(length(fis.input))], ['# of outputs: ' ...
                    num2str(length(fis.output))],  ['# of input mfs: '], [ num2str(getfis(fis, 'inmfs'))],...
                ['# of ' type ' data pairs: ' num2str(size(trndata,1))]};
        targetlineHndl=line([1:size(trndata, 1)], trndata(:, inNum+outNum),...
            'lineStyle', 'none', ...
            'Marker', lineMarker(colorIndex), 'Tag', 'targetline'); 
        title(titleStr);
        xlabelHndl=get(gca, 'XLabel');
        
        set(xlabelHndl, 'String', 'data set index');
        ylabelHndl=get(gca, 'YLabel');
        set(ylabelHndl, 'String', 'Output');
        set(textHndl, 'String', textstr);
        cmtHndl=findobj(gcbf, 'Tag', 'status');
        set(cmtHndl, 'String', [type ' data loaded']);
        pushundo(gcbf, fis);
        %      set(gcbf, 'UserData', fis); 
    end
    
    LocalEnableBtns(fis);  
    
    %% end
    %=============test anfis==============
case '#test',
    fis=get(gcbf,'UserData');
    fis=fis{1};
    testHndl=findobj(gcbf, 'Tag', 'test');
    cla
    for i=1:length(testHndl)
        if get(testHndl(i), 'Value')==1 
            thistype=get(testHndl(i), 'String');
            testdata=[];
            markerStr='o';
            switch thistype
            case 'Testing data',
                if isfield(fis, 'tstdata')
                    testdata=fis.tstdata;
                    markerStr='.';
                else
                    msgbox([thistype ' does not exist']);         
                    return
                end
            case 'Training data',
                if isfield(fis, 'trndata')
                    testdata=fis.trndata;
                    markerStr='o';
                else
                    msgbox([thistype ' does not exist']);
                    return
                end
            case 'Checking data',
                if isfield(fis, 'chkdata')
                    testdata=fis.chkdata;
                    markerStr='+';
                else
                    msgbox([thistype ' does not exist']);
                    return
                end
            otherwise,
                msgbox([thistype ' does not exist']);
                return
            end
            break
        end
    end
    if ~isempty(testdata)
        xlabelHndl=get(gca, 'XLabel');
        ylabelHndl=get(gca, 'YLabel');
        set(xlabelHndl, 'String', 'Index');
        set(ylabelHndl, 'String', 'Output');
        datasize=size(testdata, 1);
        inputnum=size(testdata, 2)-1;
        targetdata=testdata(1:datasize, inputnum+1);
        testOut=evalfis(testdata(1:datasize, 1:inputnum), fis);
        %      errordata=sum(abs(targetdata-testOut))/length(targetdata);
        errordata=sqrt(sum((targetdata-testOut)'*(targetdata-testOut))/length(targetdata));
        targetlineHndl=line([1:datasize],targetdata,...
            'lineStyle', 'none', 'Marker', markerStr); 
        title( [thistype ' : ' markerStr '   FIS output : *']);
        testlineHndl=line([1:datasize],testOut, 'lineStyle', 'none', 'Marker', '*', 'Color', 'red'); 
        statueHndl=findobj(gcbf, 'Tag', 'status');
        set(statueHndl, 'String', ['Average testing error: ' num2str(errordata)]);
    else
        msgbox([thistype ' does not exist']);
    end
case '#cleardata'
    oldfis=get(gcbf,'UserData'); 
    fis=oldfis{1};
    typeHndl=findobj(gcbf, 'Tag', 'dattype');
    for i=1:length(typeHndl)
        if get(typeHndl(i), 'Value')==1 
            thistype=get(typeHndl(i), 'String');
            out=questdlg({['do you really want to clear ' thistype ' Data?']}, '', 'Yes', 'No', 'No'); 
            if strcmp(out, 'Yes')
                switch thistype
                case 'Testing',
                    fis.tstdata=[];
                case 'Training',
                    fis.trndata=[];
                case 'Checking',
                    fis.chkdata=[];
                end
                cla
                pushundo(gcbf, fis);
            end
            break
        end
    end
    
case '#radioloadfrom'
    curHndl=gcbo;
    radioHndl=findobj(gcbf, 'Tag', 'trndatin');
    if radioHndl(1)==curHndl
        set(radioHndl(2), 'Value', 0);
        set(radioHndl(1), 'Value', get(radioHndl(1), 'max'));
    else
        set(radioHndl(1), 'Value', 0);
        set(radioHndl(2), 'Value', get(radioHndl(2), 'max'));
    end
case '#radioloadtype'
    curHndl=gco;
    radioHndl=findobj(gcbf, 'Tag', 'dattype');
    set(radioHndl, 'Value', 0);
    set(curHndl, 'Value', 1);
case '#radiogenfis'
    curHndl=gco;
    set(curHndl, 'Value', get(curHndl, 'max'));
    thisstr=get(curHndl, 'String');
    genHndl=findobj(gcbf, 'Tag', 'genfisbtn');
    radioHndl=findobj(gcbf, 'Tag', 'genfis');
    for i=1:length(radioHndl)
        if radioHndl(i)~=curHndl
            set(radioHndl(i), 'Value', 0);
        end
    end
    switch thisstr
    case 'Grid partition'
        set(genHndl, 'String', 'Generate FIS ...');
    case 'Sub. clustering'
        set(genHndl, 'String', 'Generate FIS ...');
    otherwise
        set(genHndl, 'String', 'Load ...');
    end
case '#radiotest'
    curHndl=gco;
    set(curHndl, 'Value', get(curHndl, 'max'));
    radioHndl=findobj(gcbf, 'Tag', 'test');
    for i=1:length(radioHndl)
        if radioHndl(i)~=curHndl
            set(radioHndl(i), 'Value', 0);
        end
    end
case '#help'
    figNumber=watchon;
    helpwin(mfilename)
    watchoff(figNumber)
end;    % if strcmp(action, ...
% End of function anfisedit

%==================================================
function LocalEnableBtns(fis)
% control the enable property for buttons, based on whether training data/mf/rule
% has already set
figNumber = gcbf;
startHndl = findobj(figNumber, 'Tag', 'startbtn');

if ~isfield(fis, 'trndata')| isempty(fis.trndata)| isempty(fis.input(1).mf) 
    %| isempty(fis.input(1).mf)|...
    %      ~isfield(fis, 'rule') | isempty(fis.rule)
    set(startHndl, 'Enable', 'off');
else
    set(startHndl, 'Enable', 'on');
end

%genHndl = findobj(gcf, 'Tag', 'genfis');

%if ~isfield(fis, 'trndata')| isempty(fis.trndata(1))
%   set(genHndl, 'Enable', 'off');
%else
%   set(genHndl, 'Enable', 'on'); 
%end
plotHndl = findobj(figNumber, 'Tag', 'plotstrc');
testHndl = findobj(figNumber, 'Tag', 'testbtn');
if isfield(fis,'input') & (isempty(fis.input(1).mf) | ~isfield(fis, 'rule') | isempty(fis.rule))
    set(plotHndl, 'Enable', 'off');
    set(testHndl, 'Enable', 'off');
    
else
    set(plotHndl, 'Enable', 'on');
    set(testHndl, 'Enable', 'on');
    
end


%==================================================
function uiHandle=LocalBuildUi(uiPos, uiStyle, uiCallback, promptStr, uiTag)
% build uicontrol 
uiHandle=uicontrol( ...
    'Style',uiStyle, ...
    'HorizontalAlignment','left', ...
    'BackgroundColor',[.75 .75 .75], ...  
    'Units','normalized', ...
    'Max',20, ...
    'Position',uiPos, ...
    'Callback',uiCallback, ... 
    'Tag', uiTag, ...
    'String',promptStr);

%==================================================
function frmHandle=LocalBuildFrmTxt(frmPos, txtStr, uiStyle, txtTag)
% Build frame and label with an edge
%frmColor=192/255*[1 1 1];
frmColor=[.75 .75 .75];
frmHandle=uicontrol( ...
    'Style', uiStyle, ...
    'Units','normalized', ...
    'Position',frmPos, ...
    'HorizontalAlignment', 'left',...
    'BackgroundColor',frmColor, ...
    'String', txtStr, ...
    'Tag', txtTag);
%   'ForegroundColor',[1 1 1], ...                  %generates an edge

%==================================================
function btHandle=LocalBuildBtns(thisstyle, btnNumber, labelStr, callbackStr, uiTag)
% build buttons or check boxes so they easily aline on the right

labelColor=[0.75 0.75 0.75];
top=0.953;
left=0.825;
btnWid=0.15;
btnHt=0.05;
bottom=0.032;
% Spacing between the button and the next command's label
spacing=0.03;

yPos=top-(btnNumber-1)*(btnHt+spacing);
if strcmp(labelStr, 'Close')==1
    yPos= bottom;
elseif strcmp(labelStr, 'Info')==1
    yPos= bottom+btnHt+spacing; 
else
    yPos=top-(btnNumber-1)*(btnHt+spacing)-btnHt;
end
% Generic button information
btnPos=[left yPos btnWid btnHt];
btHandle=uicontrol( ...
    'Style',thisstyle, ...
    'Units','normalized', ...
    'Position',btnPos, ...
    'String',labelStr, ...
    'Tag', uiTag, ...
    'Callback',callbackStr); 


%==================================================
function LocalStructureBtnCallback(eventSrc, eventdata)
% Plots initial anfis structure, can only be called when Structure button is enabled,
% therefore no need to check for existing figure. eventSrc is Structure btn hndl

% Get the default figure position at the root level
default_pos = get(0,'DefaultFigurePosition');

% The main figure is the parent of the Structure button which issued this callback
MainFigHndl = get(eventSrc,'Parent');

SubFigHndl=figure('Name', 'Anfis Model Structure',...
    'Position', default_pos + [40 -40 0 0], ...
    'Unit', 'normal',...
    'NumberTitle','off',...
    'HandleVisibility','callback',...
    'Color', [.75 .75 .75],...
    'MenuBar','none', ...
    'DefaultTextFontSize',8+2*isunix, ...
    'DeleteFcn',{@LocalCloseSubFigCallback eventSrc}, ...
    'DockControls', 'off');

% Create the axis where the structure will be drawn
AxesHndl = axes('Parent',SubFigHndl,'Visible','off', ...
    'Position', [0.01 0.132 0.975 0.82], ...
    'XLimMode', 'Manual', ...
    'Xlim', [-0.30 1.22], 'Ylim', [0 1.0]);       

% Create status bar and Help/Close frames
uicontrol('Parent',SubFigHndl,'Style', 'frame',...
    'Unit', 'normal',...
    'BackgroundColor',[0.75 0.75 0.75], ...
    'Position', [.01 .0218 .45 .073]);
uicontrol('Parent',SubFigHndl,'Style', 'frame',...
    'Unit', 'normal',...
    'BackgroundColor',[0.75 0.75 0.75], ...
    'Position', [.47 .0218 .52 .073]);
uicontrol('Parent',SubFigHndl,'Style', 'text',...
    'Unit', 'normal',...
    'Position', [.02 .025 .4 .05],...
    'BackgroundColor',[0.75 0.75 0.75], ...
    'FontSize',get(SubFigHndl,'DefaultTextFontSize'), ...
    'HorizontalAlignment','Left', ...
    'String', 'Click on each node to see detailed information');

% Create Help and Close buttons     
helpHndl=LocalBuildBtns('pushbutton', 0, 'Close', 'anfisedit #help', 'help');
pos=get(helpHndl, 'Position');
pos(1)=pos(1)-.17;
set(helpHndl, 'Position', pos, 'String', 'Help');
uicontrol('Parent',SubFigHndl,'Style', 'pushbutton',...
    'Unit', 'normal',...
    'Position', [0.825 0.032 0.15 0.05],...
    'Callback',  'close(gcbf)', 'String', 'Close');

% Create the update button
UpDateBtnHndl = uicontrol('Parent',SubFigHndl,'Style', 'pushbutton',...
    'Unit', 'normal',...
    'Position', [0.825-2*0.17 0.032 0.15 0.05],...
    'String', 'Update', ...
    'CallBack',{@LocalUpDateStructure MainFigHndl AxesHndl});

% Create a listener to close the Structure GUI when the main figure is closed
listener = handle.listener(MainFigHndl, 'ObjectBeingDestroyed', ...
    {@LocalCloseMainFigCallback SubFigHndl});
% Store the listener
set(SubFigHndl, 'UserData', listener);

% Disable the main figure Structure button
set(eventSrc,'Enable','off');

% Call the Local function to draw the structure on the axis
LocalUpDateStructure(UpDateBtnHndl, [], MainFigHndl, AxesHndl);


%==================================================
function LocalUpDateStructure(eventSrc, eventData, MainFigHndl, AxesHndl)
% Redraw the anfis structure on the figure when the update button is pressed

% If the Structure has already been drawn delete it and redraw
kids = get(AxesHndl,'Children');
delete(kids(ishandle(kids)));

SubFigHndl = get(eventSrc,'Parent');

% The FIS is stored in the UserData of the main figure
fis=get(MainFigHndl, 'UserData');
fis=fis{1};

% Create a text box to show node information during mouse button down on object
TextHndl=uicontrol('Parent',SubFigHndl,'Style', 'text', 'Unit', 'norm',...
    'Visible', 'off',...
    'Fontsize',8 + 2*isunix, ...
    'BackGroundColor',[1 1 .6]);

% Give a text label to each node
text([-0.25 -0.029 0.43 0.63 1.06], [1.01 1.01 1.01 1.01 1.01], ...
    {'input', 'inputmf', 'rule', 'outputmf', 'output'}, ...
    'Parent',AxesHndl,'Fontsize',get(SubFigHndl,'DefaultTextFontSize'));

%======== calculate input nodes and input mfs
% The input node centres are first calculated then plotted later to ensure correct layering
instep=1/(length(fis.input)+1);
outstep=1/(length(fis.output)+1);
theta=0:pi/5:2*pi;
r= 0.02;
rsin=r*sin(theta);
rcos=r*cos(theta);

numin = length(fis.input);
total_nummf = 0;
for id = 1:numin
    nummf(id) = length(fis.input(id).mf);
    total_nummf = total_nummf + nummf(id);
end
mfstep = 1/(total_nummf + numin);

for id = 1:numin
    total_mf_block = 0;
    for jid = numin:-1:id + 1
        mf_block(jid) = (nummf(jid) + 1)*mfstep;
        total_mf_block = total_mf_block + mf_block(jid);
    end 
    % Calculate the input node centres
    input_node_ctr(id)   = total_mf_block + (nummf(id) + 1)*mfstep/2;
    for kid = 1:nummf(id)
        % Calculate the input mf node centres
        inputmf_node_ctr(id,kid) = total_mf_block + mfstep*(nummf(id)+1-kid);
    end 
end

%=========rules and output mfs
rulestep=length(fis.rule)+1;

% Plot the connections from output mf nodes to the weighted sum output nodes
for i=1:length(fis.output)
    for j=1:length(fis.rule)
        line([0.7 0.9], [(rulestep-j)/rulestep outstep*i], [-1 -1], 'color', 'black','Parent',AxesHndl);
    end
end   

% Plot the connections from the input mf nodes to the rule nodes
for id = 1:length(fis.rule)
    conn = fis.rule(id).connection;
    numa = length(fis.rule(id).antecedent);
    y_pos_rule = (rulestep-id)/rulestep;
    for jid = 1:numa
        ruleindex=fis.rule(id).antecedent(jid);
        if ruleindex~=0
            if ruleindex < 0 
                thiscolor = 'green';
                InfoTxt = 'Not True';
            else
                thiscolor = 'black';
                InfoTxt = 'True';
            end
            mfstep=instep/(nummf(jid)+1);
            % Plot the connections between the inputmf nodes and the rule nodes
            LineHndl = line([0.0 0.45], ...
                [inputmf_node_ctr(jid,abs(ruleindex)) y_pos_rule], [-1 -1], ...
                'Color', char(thiscolor),'Parent',AxesHndl, ...
                'ButtonDownFcn', {@LocalMouseBtnDown TextHndl InfoTxt});
        end
    end  
    
    % Plot the connections from the rule nodes to the output mf nodes
    line([0.45 0.7], [y_pos_rule y_pos_rule], [-1 -1], 'color', 'black','Parent',AxesHndl);
    
    % Draw the rule nodes
    xcircle=r*sin(theta)+0.45;
    ycircle=r*cos(theta)+y_pos_rule;  
    zcircle = ones(length(ycircle));
    % rulecolor = AND    OR  
    rulecolor={'blue', 'red'};
    thiscolor = rulecolor{conn};
    InfoTxt = ['Rule ' sprintf('%i',id)];
    patch(xcircle, ycircle, 'w',...
        'ButtonDownFcn', {@LocalMouseBtnDown TextHndl InfoTxt},...
        'FaceColor',thiscolor, ...
        'Parent',AxesHndl);
    
    % Draw the outputmf nodes
    xcircle=xcircle+0.25;
    InfoTxt = ['Output MF ' sprintf('%i',fis.rule(id).consequent(1))];
    patch(xcircle, ycircle, 'w',...
        'ButtonDownFcn', {@LocalMouseBtnDown TextHndl InfoTxt},...
        'Parent',AxesHndl); 
end

% Plot the input mf nodes
for id = 1:numin
    for kid = 1:nummf(id)
        xcircle = rsin - 0.0;
        ycircle = rcos + inputmf_node_ctr(id,kid);
        zcircle = 10*ones(length(ycircle));
        % Plot the connections between the inputmf nodes and the rule nodes
        line([-0.2 0.0], [input_node_ctr(id) inputmf_node_ctr(id,kid)], [-1 -1], 'Parent',AxesHndl,'color', 'black');
        InfoTxt = ['Input ' sprintf('%i',id) ',' ' MF ' fis.input(id).mf(kid).name];
        patch(xcircle, ycircle, zcircle, 'w',...
            'ButtonDownFcn', {@LocalMouseBtnDown TextHndl InfoTxt},...
            'Parent',AxesHndl);
    end
    
    % Plot the input nodes
    xcircle = rsin - 0.2;
    ycircle = rcos + input_node_ctr(id);
    InfoTxt = ['Input ' sprintf('%i',id)];
    patch(xcircle, ycircle, 'black', ...
        'ButtonDownFcn', {@LocalMouseBtnDown TextHndl InfoTxt}, ...
        'Parent',AxesHndl);
end

%=====output nodes
line([0.9 1.1], [outstep outstep], 'color', 'black','Parent',AxesHndl);

for id=1:length(fis.output)
    xcircle=rsin+0.9;
    ycircle=rcos+outstep*id;     
    InfoTxt = ['Aggregated Output ' sprintf('%i',id)];
    patch(xcircle, ycircle, zcircle, 'w',...
        'ButtonDownFcn', {@LocalMouseBtnDown TextHndl InfoTxt},...
        'Parent',AxesHndl);
end

%=======normalize and dividing node
xcircle=rsin+1.1;
ycircle=rcos+outstep;   
InfoTxt = ['Output'];
patch(xcircle, ycircle, 'black',...
    'ButtonDownFcn', {@LocalMouseBtnDown TextHndl InfoTxt},...
    'Parent',AxesHndl);

%============== create a custom legend ===============
line([0.90 1.22 1.22 0.90 0.90],[0.0 0.0 0.2 0.2 0.0], 'Parent',AxesHndl,'Color','black');
text([0.94 1.12 1.12 1.12], [0.16 0.115 0.07 0.025], ...
    {'Logical Operations', 'and', 'or', 'not'}, ...
    'Fontsize',get(SubFigHndl,'DefaultTextFontSize'),'Parent',AxesHndl);
% Create the blue AND circle, the red OR circle and the green NOT line
xcircle=r*sin(theta)+1.;      ycircle=r*cos(theta)+0.12;     patch(xcircle, ycircle,'blue','Parent',AxesHndl);
xcircle=r*sin(theta)+1.;      ycircle=r*cos(theta)+0.07;     patch(xcircle, ycircle,'red','Parent',AxesHndl);
line([0.95 1.05],[0.03 0.03],'LineWidth',1,'Color','green','Parent',AxesHndl);


%==================================================
function LocalCloseMainFigCallback(eventSrc, eventData, SubFigHndl)
% A listener callback when the main figure window is closed
delete(SubFigHndl);


%==================================================
function LocalCloseSubFigCallback(eventSrc, eventData, StrctBtnHndl)
% Operates when the Structure diagram sub-figure is closed
set(StrctBtnHndl,'Enable','on');


%==================================================
function LocalMouseBtnDown(eventSrc, eventData, TextHndl, InfoTxt)
% Operates when user button downs on objects in the Anfis Model Structure window.
% eventSrc is the hndl of the object where the btn down event occurred
AxesHndl = get(eventSrc,'Parent');
FigHndl = get(AxesHndl,'Parent');
CP = get(FigHndl,'CurrentPoint');

switch  get(eventSrc,'Type');
    
case 'line'
    set(eventSrc,'LineWidth',4);
case 'patch' 
    set(TextHndl, ...
        'String', InfoTxt, ...
        'Visible', 'on');
    ex = get(TextHndl,'Extent');
    set(TextHndl,'Position',[CP(1,1) CP(1,2) ex(3) ex(4)]);
end

% Reset the sub-figure window btn up function, and pass the text hndl and the selected object hndl
set(FigHndl,'WindowButtonUpFcn',{@LocalWindowBtnUpFcn TextHndl eventSrc});

%==================================================
function LocalWindowBtnUpFcn(eventSrc, eventData, varargin)
% Operates when the Window Button Up occurs, varargin = [ TextHndl objHndl ]

switch  get(varargin{2},'Type');
    
case 'line'
    set(varargin{2},'LineWidth',0.5);
case 'patch'
    set(varargin{1},'Visible','off');
end

% Reset the sub-figure window btn up function to do nothing
set(eventSrc,'WindowButtonUpFcn', ' ');