//--------------------------------------------------------------------------------// // COPYRIGHT NOTICE // //--------------------------------------------------------------------------------// // Copyright (c) 2012, Instituto de Microelectronica de Sevilla (IMSE-CNM) // // // // All rights reserved. // // // // Redistribution and use in source and binary forms, with or without // // modification, are permitted provided that the following conditions are met: // // // // * Redistributions of source code must retain the above copyright notice, // // this list of conditions and the following disclaimer. // // // // * Redistributions in binary form must reproduce the above copyright // // notice, this list of conditions and the following disclaimer in the // // documentation and/or other materials provided with the distribution. // // // // * Neither the name of the IMSE-CNM nor the names of its contributors may // // be used to endorse or promote products derived from this software // // without specific prior written permission. // // // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE // // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //--------------------------------------------------------------------------------// package xfuzzy.lang; /** * Clase que describe la estructura global del sistema * * @author Francisco Jos� Moreno Velo * */ public class SystemModule { //----------------------------------------------------------------------------// // MIEMBROS PRIVADOS // //----------------------------------------------------------------------------// /** * Variables definidas en el sistema */ private Variable var[]; /** * Lista de llamadas a bases de reglas o m�dulos no difusos que constituyen * la estructura jer�rquica del sistema */ private ModuleCall call[]; //----------------------------------------------------------------------------// // CONSTRUCTOR // //----------------------------------------------------------------------------// /** * Constructor */ public SystemModule() { this.var = new Variable[1]; this.var[0] = new Variable("NULL",Variable.INNER); this.call = new ModuleCall[0]; } //----------------------------------------------------------------------------// // M�TODOS P�BLICOS // //----------------------------------------------------------------------------// /** * Sustituci�n de una base de reglas */ public void exchangeRulebase(Rulebase oldrb, Rulebase newrb) { for(int i=0; i<call.length; i++) if(call[i] instanceof RulebaseCall) { RulebaseCall rbcall = (RulebaseCall) call[i]; rbcall.exchangeRulebase(oldrb, newrb); } } /** * Sustituci�n de un bloque no difuso */ public void exchangeBlock(CrispBlock oldblock, CrispBlock newblock) { for(int i=0; i<call.length; i++) if(call[i] instanceof CrispBlockCall) { CrispBlockCall cbcall = (CrispBlockCall) call[i]; cbcall.exchangeBlock(oldblock,newblock); } } //----------------------------------------------------------------------------// // M�todos que generan c�digo // //----------------------------------------------------------------------------// /** * Genera la descripci�n XFL3 de la estructura global */ public String toXfl() { String eol = System.getProperty("line.separator", "\n"); Variable input[] = getInputs(); Variable output[] = getOutputs(); String code = eol+"system ("; for(int i=0; i<input.length; i++) code += (i==0? "" : ", ")+input[i].toXfl(); code += " : "; for(int i=0; i<output.length; i++) code += (i==0? "":", ")+output[i].toXfl(); code += ") {"+eol; for(int i=0; i<call.length; i++) code += call[i].toXfl(); code += " }"+eol; return code; } //----------------------------------------------------------------------------// // M�todos de acceso a las variables // //----------------------------------------------------------------------------// /** * Obtiene la lista de variables globales de entrada */ public Variable[] getInputs() { int size = 0; for(int i=0; i<var.length; i++) if(var[i].isInput()) size++; Variable[] input = new Variable[size]; for(int i=0,j=0; i<this.var.length; i++) if(var[i].isInput()) { input[j] = var[i]; j++; } return input; } /** * Obtiene la lista de variables globales de salida */ public Variable[] getOutputs() { int size = 0; for(int i=0; i<var.length; i++) if(var[i].isOutput()) size++; Variable[] output = new Variable[size]; for(int i=0,j=0; i<var.length; i++) if(var[i].isOutput()) { output[j] = var[i]; j++; } return output; } /** * Obtiene la lista de variables globales internas */ public Variable[] getInners() { int size = 0; for(int i=0; i<var.length; i++) if(var[i].isInner()) size++; Variable[] inner = new Variable[size]; for(int i=0,j=0; i<var.length; i++) if(var[i].isInner()) { inner[j] = var[i]; j++; } return inner; } /** * Obtiene la lista completa de variables globales */ public Variable[] getVariables() { return this.var; } /** * A�ade una variable global */ public void addVariable(Variable newvar) { Variable aux[] = new Variable[var.length+1]; System.arraycopy(var,0,aux,0,var.length); aux[var.length] = newvar; var = aux; } /** * Elimina una variable global */ public void removeVariable(Variable rmvar) { int index = -1; for(int i=0; i<var.length; i++) if(var[i] == rmvar) index = i; if(index <= 0 || rmvar.isLinked() ) return; Variable[] aux = new Variable[var.length-1]; System.arraycopy(var,0,aux,0,index); System.arraycopy(var,index+1,aux,index,aux.length-index); var = aux; rmvar.dispose(); } /** * A�ade una variable interna */ public Variable addInnerVariable() { String newname = "i0"; for(int i=0; searchVariable(newname)!=null; i++) newname="i"+i; Variable inner = new Variable(newname,Variable.INNER); addVariable(inner); return inner; } /** * Busca una variable global */ public Variable searchVariable(String varname) { for(int i=0; i<var.length; i++) if( var[i].equals(varname) ) return var[i]; return null; } //----------------------------------------------------------------------------// // M�todos de acceso a las llamadas // //----------------------------------------------------------------------------// /** * Obtiene la lista de llamadas a bases de reglas y bloques no difusos */ public ModuleCall[] getModuleCalls() { return call; } /** * Obtiene la lista de llamadas a bases de reglas */ public RulebaseCall[] getRulebaseCalls() { int count=0; for(int i=0;i<call.length;i++) if(call[i] instanceof RulebaseCall) count++; RulebaseCall rbc[] = new RulebaseCall[count]; for(int i=0,j=0;i<call.length;i++) if(call[i] instanceof RulebaseCall) { rbc[j] = (RulebaseCall) call[i]; j++; } return rbc; } /** * A�ade una llamada a una base de reglas */ public void addCall(Rulebase ref, Variable ivar[], Variable ovar[]) { ModuleCall aux[] = new ModuleCall[call.length+1]; System.arraycopy(call,0,aux,0,call.length); aux[call.length] = new RulebaseCall(ref,ivar,ovar); call = aux; } /** * A�ade una llamada a un modulo no difuso */ public void addCall(CrispBlock block, Variable ivar[], Variable ovar) { ModuleCall aux[] = new ModuleCall[call.length+1]; System.arraycopy(call,0,aux,0,call.length); aux[call.length] = new CrispBlockCall(block,ivar,ovar); call = aux; } /** * Elimina una llamada */ public void removeCall(ModuleCall rmcall) { int index = -1; for(int i=0; i<call.length; i++) if(call[i] == rmcall) index = i; if(index == -1) return; ModuleCall[] aux = new ModuleCall[call.length-1]; System.arraycopy(call,0,aux,0,index); System.arraycopy(call,index+1,aux,index,aux.length-index); call = aux; rmcall.dispose(); } /** * Cambia el orden de dos llamadas a base de reglas */ public void exchangeCall(int i, int j) { ModuleCall aux = call[i]; call[i] = call[j]; call[j] = aux; } //----------------------------------------------------------------------------// // M�todos utilizados en el aprendizaje // //----------------------------------------------------------------------------// /** * Calcula la derivada del proceso de inferencia del sistema */ public void derivative(double[] deriv) throws XflException { Variable[] outputvar = getOutputs(); for(int i=call.length-1; i>=0; i--) { Variable[] calloutput = call[i].getOutputVariables(); double[] callderiv = new double[calloutput.length]; for(int j=0; j<calloutput.length; j++) for(int k=0; k<outputvar.length; k++) if(calloutput[j] == outputvar[k]) callderiv[j] = deriv[k]; call[i].derivative(callderiv); } } /** * Calcula la derivada del proceso de inferencia del sistema */ public void derivative() throws XflException { for(int i=call.length-1; i>=0; i--) call[i].derivative(); } //----------------------------------------------------------------------------// // M�todos de inferencia // //----------------------------------------------------------------------------// /** * Ejecuta una inferencia devolviendo datos concretos */ public double [] crispInference(double input[]) { Variable[] inputvar = getInputs(); Variable[] outputvar = getOutputs(); double output[] = new double[outputvar.length]; for(int i=0; i<var.length; i++) var[i].reset(); for(int i=0; i<input.length; i++) inputvar[i].set(input[i]); for(int i=0; i<call.length; i++) call[i].compute(); for(int i=0; i<outputvar.length; i++) if(outputvar[i].getValue() instanceof pkg.xfl.mfunc.singleton) output[i] = ((pkg.xfl.mfunc.singleton) outputvar[i].getValue()).get()[0]; else output[i] = ((AggregateMemFunc) outputvar[i].getValue()).defuzzify(); return output; } /** * Ejecuta una inferencia devolviendo datos concretos */ public double [] crispInference(MemFunc input[]) { Variable[] inputvar = getInputs(); Variable[] outputvar = getOutputs(); double output[] = new double[outputvar.length]; for(int i=0; i<var.length; i++) var[i].reset(); for(int i=0; i<input.length; i++) inputvar[i].set(input[i]); for(int i=0; i<call.length; i++) call[i].compute(); for(int i=0; i<outputvar.length; i++) if(outputvar[i].getValue() instanceof pkg.xfl.mfunc.singleton) output[i] = ((pkg.xfl.mfunc.singleton) outputvar[i].getValue()).get()[0]; else output[i] = ((AggregateMemFunc) outputvar[i].getValue()).defuzzify(); return output; } /** * Ejecuta una inferencia devolviendo datos difusos */ public MemFunc [] fuzzyInference(double input[]) { Variable[] inputvar = getInputs(); Variable[] outputvar = getOutputs(); MemFunc output[] = new MemFunc[outputvar.length]; for(int i=0; i<var.length; i++) var[i].reset(); for(int i=0; i<input.length; i++) inputvar[i].set(input[i]); for(int i=0; i<call.length; i++) call[i].compute(); for(int i=0; i<outputvar.length; i++) output[i] = outputvar[i].getValue(); return output; } /** * Ejecuta una inferencia devolviendo datos difusos */ public MemFunc [] fuzzyInference(MemFunc input[]) { Variable[] inputvar = getInputs(); Variable[] outputvar = getOutputs(); MemFunc output[] = new MemFunc[outputvar.length]; for(int i=0; i<var.length; i++) var[i].reset(); for(int i=0; i<input.length; i++) inputvar[i].set(input[i]); for(int i=0; i<call.length; i++) call[i].compute(); for(int i=0; i<outputvar.length; i++) output[i] = outputvar[i].getValue(); return output; } /** * Obtiene los resultados difusos de las variables de salida */ public AggregateMemFunc[] getFuzzyValues() { Variable[] outputvar = getOutputs(); AggregateMemFunc[] fuzzyvalue = new AggregateMemFunc[outputvar.length]; for(int i=0; i<call.length; i++) { Variable[] calloutput = call[i].getOutputVariables(); MemFunc[] callvalue = call[i].getFuzzyValues(); for(int j=0; j<calloutput.length; j++) for(int k=0; k<outputvar.length; k++) if(calloutput[j] == outputvar[k]) fuzzyvalue[k] = (AggregateMemFunc) callvalue[j]; } return fuzzyvalue; } }