//--------------------------------------------------------------------------------//
// 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. //
//--------------------------------------------------------------------------------//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// CONSTRUCCION AUTOMATICA DE UN SISTEMA //
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
package xfuzzy.xfdm;
import xfuzzy.lang.*;
import xfuzzy.xfsl.XfslPattern;
public abstract class XfdmAlgorithm {
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// MIEMBROS PRIVADOS //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
protected Specification spec;
protected XfdmConfig config;
protected XfslPattern pattern;
protected Operatorset opset;
protected Type[] inputtype;
protected Type[] outputtype;
protected Rulebase rulebase;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// CONSTRUCTOR //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// METODOS PUBLICOS //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//-------------------------------------------------------------//
// Crea un algoritmo a partir de su identificador //
//-------------------------------------------------------------//
public static XfdmAlgorithm create(String name, double[] param) {
if(name.equals("Flat")) return new XfdmFlatSystem();
else if(name.equals("WangMendel")) return new XfdmWangMendel();
else if(name.equals("Nauck")) return new XfdmNauck(param);
else if(name.equals("Senhadji")) return new XfdmSenhadji(param);
else if(name.equals("IncGrid")) return new XfdmIncGrid(param);
else if(name.equals("ICFA")) return new XfdmICFA(param);
else if(name.equals("IncClustering")) return new XfdmIncClustering(param);
else if(name.equals("HardCMeans"))
return new XfdmFixedClustering(XfdmFixedClustering.HARD_CMEANS,param);
else if(name.equals("CMeans"))
return new XfdmFixedClustering(XfdmFixedClustering.CMEANS,param);
else if(name.equals("GustafsonKessel"))
return new XfdmFixedClustering(XfdmFixedClustering.GUSTAFSON_KESSEL,param);
else if(name.equals("GathGeva"))
return new XfdmFixedClustering(XfdmFixedClustering.GATH_GEVA,param);
else return null;
}
//-------------------------------------------------------------//
// Metodo que construye el sistema a partir de los datos //
//-------------------------------------------------------------//
public abstract void compute(Specification spec, XfdmConfig config)
throws XflException;
/* Get the algorithm name. */
public abstract String toString();
//-------------------------------------------------------------//
// Representacion en el fichero de configuracion //
//-------------------------------------------------------------//
public abstract String toCode();
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// METODOS PRIVADOS //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//=============================================================//
// Metodos que generan los objetos identificados //
//=============================================================//
//-------------------------------------------------------------//
// Genera el conjunto de operadores de la base de reglas //
//-------------------------------------------------------------//
protected Operatorset createOperatorSet() {
if(config.systemstyle == null) return null;
String prefix = config.systemstyle.rulebase+"_opset";
String oname = ""+prefix;
int osi=0;
while(spec.searchOperatorset(oname) != null) { oname = prefix+osi; osi++; }
Operatorset op = new Operatorset(oname);
switch(config.systemstyle.conjunction) {
case XfdmSystemStyle.MIN:
op.set(new pkg.xfl.binary.min(), FuzzyOperator.AND);
break;
case XfdmSystemStyle.PROD:
op.set(new pkg.xfl.binary.prod(), FuzzyOperator.AND);
break;
}
switch(config.systemstyle.defuz) {
case XfdmSystemStyle.FUZZYMEAN:
op.set(new pkg.xfl.defuz.FuzzyMean(),FuzzyOperator.DEFUZMETHOD);
break;
case XfdmSystemStyle.WEIGHTED:
op.set(new pkg.xfl.defuz.WeightedFuzzyMean(),FuzzyOperator.DEFUZMETHOD);
break;
case XfdmSystemStyle.TAKAGI:
op.set(new pkg.xfl.defuz.TakagiSugeno(),FuzzyOperator.DEFUZMETHOD);
break;
case XfdmSystemStyle.CLASSIFICATION:
op.set(new pkg.xfl.defuz.MaxLabel(),FuzzyOperator.DEFUZMETHOD);
break;
}
return op;
}
//-------------------------------------------------------------//
// Genera el conjunto de tipos de variables de entrada //
//-------------------------------------------------------------//
protected Type[] createInputTypes() {
Type itp[] = new Type[config.numinputs];
for(int i=0; i<config.numinputs; i++) {
String tname = "Tin"+i;
int mfs = config.commonstyle.mfs;
int style = config.commonstyle.style;
Universe universe = null;
if(config.commonstyle.isUniverseDefined()) {
try { universe=new Universe(config.commonstyle.min,config.commonstyle.max);}
catch(Exception ex) {}
}
if(config.inputstyle != null && config.inputstyle.length > i &&
config.inputstyle[i] != null) {
tname = "T"+config.inputstyle[i].name;
mfs = config.inputstyle[i].mfs;
style = config.inputstyle[i].style;
if(config.inputstyle[i].isUniverseDefined()) {
try {
universe=new Universe(config.inputstyle[i].min,config.inputstyle[i].max);
} catch(Exception ex) {
}
} else {
universe = null;
}
}
if(universe == null) universe = pattern.getUniverse(i,true);
itp[i] = new Type(tname,universe);
createInputMemFuncs(itp[i],style,mfs);
}
return itp;
}
//-------------------------------------------------------------//
// Genera el conjunto de tipos de variables de salida //
//-------------------------------------------------------------//
protected Type[] createOutputTypes(int numomfs){
Type otp[] = new Type[config.numoutputs];
for(int i=0; i<config.numoutputs; i++) {
String tname = "T"+config.systemstyle.outputname;
if(config.numoutputs>1) tname += ""+i;
otp[i] = new Type(tname,pattern.getUniverse(i,false));
switch(config.systemstyle.defuz) {
case XfdmSystemStyle.FUZZYMEAN:
createSingletons(otp[i],numomfs);
break;
case XfdmSystemStyle.WEIGHTED:
createBells(otp[i],numomfs);
break;
case XfdmSystemStyle.TAKAGI:
createTakagi(otp[i],numomfs,1+inputtype.length);
break;
case XfdmSystemStyle.CLASSIFICATION:
createClasses(otp[i],pattern.getValues(i));
break;
}
}
return otp;
}
//-------------------------------------------------------------//
// Genera la base de reglas //
//-------------------------------------------------------------//
protected Rulebase createEmptyRulebase() {
Rulebase base = new Rulebase(""+config.systemstyle.rulebase);
base.setOperatorset(opset);
Variable ivar[] = new Variable[config.numinputs];
Variable ovar[] = new Variable[config.numoutputs];
for(int i=0; i<config.numinputs; i++) {
String varname = "in"+i;
if(config.inputstyle != null && config.inputstyle.length > i &&
config.inputstyle[i] != null) {
varname = ""+config.inputstyle[i].name;
}
ivar[i] = new Variable(varname,inputtype[i],Variable.INPUT);
base.addInputVariable(ivar[i]);
}
for(int i=0; i<config.numoutputs; i++) {
String name = config.systemstyle.outputname;
if(config.numoutputs>1) name += ""+i;
ovar[i] = new Variable(name,outputtype[i],base);
base.addOutputVariable(ovar[i]);
}
return base;
}
//-------------------------------------------------------------//
// Genera la estructura modular //
//-------------------------------------------------------------//
protected void createSystemStructure() {
SystemModule system = spec.getSystemModule();
RulebaseCall rmcall[] = system.getRulebaseCalls();
for(int i=0; i<rmcall.length; i++) system.removeCall(rmcall[i]);
Variable rmvar[] = system.getVariables();
for(int i=0; i<rmvar.length; i++) system.removeVariable(rmvar[i]);
for(int i=0; i<config.numinputs; i++) {
String varname = "in"+i;
if(config.inputstyle != null && config.inputstyle.length > i &&
config.inputstyle[i] != null) {
varname = ""+config.inputstyle[i].name;
}
system.addVariable( new Variable(varname,inputtype[i],Variable.INPUT) );
}
for(int i=0; i<config.numoutputs; i++) {
String name = config.systemstyle.outputname;
if(config.numoutputs>1) name += ""+i;
system.addVariable( new Variable(name,outputtype[i],Variable.OUTPUT) );
}
system.addCall(rulebase,system.getInputs(),system.getOutputs());
}
//=============================================================//
// Metodos auxiliares //
//=============================================================//
//-------------------------------------------------------------//
// Calcula el numero de reglas del grid //
//-------------------------------------------------------------//
protected int computeGridSize(Type[] itp) {
int number=1;
for(int i=0; i<itp.length; i++) {
number *= itp[i].getAllMembershipFunctions().length;
}
return number;
}
//-------------------------------------------------------------//
// Obtiene el indice de la etiqueta mas activa //
//-------------------------------------------------------------//
protected int getMFIndex(Type type, double x) {
LinguisticLabel mf[] = type.getAllMembershipFunctions();
double max = 0;
int index = 0;
for(int i=0; i<mf.length; i++) {
double degree = mf[i].compute(x);
if(degree>=max) { max = degree; index = i; }
}
return index;
}
//-------------------------------------------------------------//
// Obtiene los indices de las etiquetas mas activas //
//-------------------------------------------------------------//
protected int[] getMFIndexes(Type type, double x, double threshold) {
LinguisticLabel mf[] = type.getAllMembershipFunctions();
boolean active[] = new boolean[mf.length];
int counter = 0;
for(int i=0; i<mf.length; i++) {
double degree = mf[i].compute(x);
if(degree>=threshold) { active[i] = true; counter++; }
else active[i] = false;
}
int index[] = new int[counter];
for(int i=0,j=0; i<active.length; i++) if(active[i]) { index[j] = i; j++; }
return index;
}
//-------------------------------------------------------------//
// Calcula el grado de activacion de un antecedente //
//-------------------------------------------------------------//
protected double computeActivationDegree(int index[], double value[]) {
double degree = 1.0;
for(int i=0; i<index.length; i++) {
LinguisticLabel mf[] = inputtype[i].getAllMembershipFunctions();
double dom = mf[index[i]].compute(value[i]);
if(config.systemstyle.conjunction == XfdmSystemStyle.MIN) {
if(dom < degree) degree = dom;
} else {
degree *= dom;
}
}
return degree;
}
//=============================================================//
// Metodos que generan un tipo //
//=============================================================//
//-------------------------------------------------------------//
// Genera un conjunto de MFs predefinidas para una entrada //
//-------------------------------------------------------------//
protected void createInputMemFuncs(Type type, int sel, int mfs) {
switch(sel) {
case XfdmInputStyle.FREE_TRIANGLES:
createFreeTriangles(type,mfs);
break;
case XfdmInputStyle.FREE_SH_TRIANGLES:
createFreeShoulderedTriangles(type,mfs);
break;
case XfdmInputStyle.FREE_GAUSSIANS:
createFreeGaussians(type,mfs);
break;
case XfdmInputStyle.TRIANGULAR_FAMILY:
createTriangularFamily(type,mfs);
break;
case XfdmInputStyle.SH_TRIANGULAR_FAMILY:
createShoulderedTriangularFamily(type,mfs);
break;
case XfdmInputStyle.BSPLINES_FAMILY:
createBsplinesFamily(type,mfs);
break;
}
}
//-------------------------------------------------------------//
// Crea un conjunto de triangulos equiespaciados //
//-------------------------------------------------------------//
private void createFreeTriangles(Type type, int mfs) {
if(mfs == 0) return;
Universe u = type.getUniverse();
double min = u.min();
double max = u.max();
double r = (max-min)/(mfs-1);
double param[] = new double[3];
ParamMemFunc pmf[] = new ParamMemFunc[mfs];
param[0] = min - r;
param[1] = min;
param[2] = min + r;
pmf[0] = new pkg.xfl.mfunc.triangle();
pmf[0].set("mf0",u);
try { pmf[0].set(param); } catch(XflException ex) {}
for(int i=1; i<mfs-1; i++) {
param[0] = min + (i-1)*r;
param[1] = min + i*r;
param[2] = min + (i+1)*r;
pmf[i] = new pkg.xfl.mfunc.triangle();
pmf[i].set("mf"+i,u);
try { pmf[i].set(param); } catch(XflException ex) {}
}
param[0] = max - r;
param[1] = max;
param[2] = max + r;
pmf[mfs-1] = new pkg.xfl.mfunc.triangle();
pmf[mfs-1].set("mf"+(mfs-1),u);
try { pmf[mfs-1].set(param); } catch(XflException ex) {}
try { for(int i=0; i<mfs; i++) type.add(pmf[i]); }
catch(XflException e) {}
}
//-------------------------------------------------------------//
// Crea un conjunto de triangulos y trapecios //
//-------------------------------------------------------------//
private void createFreeShoulderedTriangles(Type type, int mfs) {
if(mfs == 0) return;
Universe u = type.getUniverse();
double min = u.min();
double max = u.max();
double r = (max-min)/(mfs+1);
double param4[] = new double[4];
double param3[] = new double[3];
ParamMemFunc pmf[] = new ParamMemFunc[mfs];
param4[0] = min-r;
param4[1] = min;
param4[2] = min+r;
param4[3] = min+2*r;
pmf[0] = new pkg.xfl.mfunc.trapezoid();
pmf[0].set("mf0",u);
try { pmf[0].set(param4); } catch(XflException ex) {}
for(int i=1; i<mfs-1; i++) {
param3[0] = min + i*r;
param3[1] = min + (i+1)*r;
param3[2] = min + (i+2)*r;
pmf[i] = new pkg.xfl.mfunc.triangle();
pmf[i].set("mf"+i,u);
try { pmf[i].set(param3); } catch(XflException ex) {}
}
param4[0] = max-2*r;
param4[1] = max-r;
param4[2] = max;
param4[3] = max+r;
pmf[mfs-1] = new pkg.xfl.mfunc.trapezoid();
pmf[mfs-1].set("mf"+(mfs-1), u);
try { pmf[mfs-1].set(param4); } catch(XflException ex) {}
try { for(int i=0; i<mfs; i++) type.add(pmf[i]); }
catch(XflException e) {}
}
//-------------------------------------------------------------//
// Crea un conjunto de campanas equiespaciadas //
//-------------------------------------------------------------//
private void createFreeGaussians(Type type, int mfs) {
if(mfs == 0) return;
Universe u = type.getUniverse();
double min = u.min();
double max = u.max();
double r = (max-min)/(mfs-1);
double param[] = new double[2];
ParamMemFunc pmf[] = new ParamMemFunc[mfs];
param[0] = min;
param[1] = 0.6*r;
pmf[0] = new pkg.xfl.mfunc.bell();
pmf[0].set("mf0", u);
try { pmf[0].set(param); } catch(XflException ex) {}
for(int i=1; i<mfs-1; i++) {
param[0] = min + i*r;
pmf[i] = new pkg.xfl.mfunc.bell();
pmf[i].set("mf"+i, u);
try { pmf[i].set(param); } catch(XflException ex) {}
}
param[0] = max;
pmf[mfs-1] = new pkg.xfl.mfunc.bell();
pmf[mfs-1].set("mf"+(mfs-1), u);
try { pmf[mfs-1].set(param); } catch(XflException ex) {}
try { for(int i=0; i<mfs; i++) type.add(pmf[i]); }
catch(XflException e) {}
}
//-------------------------------------------------------------//
// Crea un conjunto de campanas y sigmoides //
//-------------------------------------------------------------//
/*
private void createFreeShoulderedGaussians(Type type, int mfs) {
if(mfs == 0) return;
Universe u = type.getUniverse();
double min = u.min();
double max = u.max();
double r = (max-min)/(mfs+1);
double param[] = new double[2];
ParamMemFunc pmf[] = new ParamMemFunc[mfs];
param[0] = min + 1.5*r;
param[1] = -0.17*r;
pmf[0] = new pkg.xfl_mf_sigma();
pmf[0].set("mf0", u);
try { pmf[0].set(param); } catch(XflException ex) {}
for(int i=1; i<mfs-1; i++) {
param[0] = min + (i+1)*r;
param[1] = 0.6*r;
pmf[i] = new pkg.xfl_mf_bell();
pmf[i].set("mf"+i, u);
try { pmf[i].set(param); } catch(XflException ex) {}
}
param[0] = max - 1.5*r;
param[1] = 0.17*r;
pmf[mfs-1] = new pkg.xfl_mf_sigma();
pmf[mfs-1].set("mf"+(mfs-1), u);
try { pmf[mfs-1].set(param); } catch(XflException ex) {}
try { for(int i=0; i<mfs; i++) type.add(pmf[i]); }
catch(XflException e) {}
}
*/
//-------------------------------------------------------------//
// Crea un conjunto de trapecios equiespaciados //
//-------------------------------------------------------------//
/*
private void createFreeTrapezoids(Type type, int mfs) {
if(mfs == 0) return;
Universe u = type.getUniverse();
double min = u.min();
double max = u.max();
double r = (max-min)/(3*mfs-1);
double param[] = new double[4];
ParamMemFunc pmf[] = new ParamMemFunc[mfs];
param[0] = min - r;
param[1] = min;
param[2] = min + 2*r;
param[3] = min + 3*r;
pmf[0] = new pkg.xfl_mf_trapezoid();
pmf[0].set("mf0", u);
try { pmf[0].set(param); } catch(XflException ex) {}
for(int i=1; i<mfs-1; i++) {
param[0] = min + (3*i-1)*r;
param[1] = min + 3*i*r;
param[2] = min + (3*i+2)*r;
param[3] = min + (3*i+3)*r;
pmf[i] = new pkg.xfl_mf_trapezoid();
pmf[i].set("mf"+i, u);
try { pmf[i].set(param); } catch(XflException ex) {}
}
param[0] = max - 3*r;
param[1] = max - 2*r;
param[2] = max;
param[3] = max + r;
pmf[mfs-1] = new pkg.xfl_mf_trapezoid();
pmf[mfs-1].set("mf"+(mfs-1), u);
try { pmf[mfs-1].set(param); } catch(XflException ex) {}
try { for(int i=0; i<mfs; i++) type.add(pmf[i]); }
catch(XflException e) {}
}
*/
//-------------------------------------------------------------//
// Crea una familia de triangulos equiespaciados //
//-------------------------------------------------------------//
private void createTriangularFamily(Type type, int mfs) {
if(mfs == 0) return;
Universe u = type.getUniverse();
double min = u.min();
double max = u.max();
double r = (max-min)/(mfs-1);
double param[] = new double[mfs-2];
for(int i=0; i<param.length; i++) param[i] = min + (i+1)*r;
Family fam = new pkg.xfl.family.triangular();
fam.set("fam",type);
try { fam.set(param); type.addFamily(fam); } catch(XflException ex) {}
for(int i=0; i<mfs; i++) {
FamiliarMemFunc fmf = new FamiliarMemFunc("mf"+i,fam,i);
try { type.add(fmf); } catch(XflException e) {}
}
}
//-------------------------------------------------------------//
// Crea una familia de triangulos y trapecios //
//-------------------------------------------------------------//
private void createShoulderedTriangularFamily(Type type, int mfs) {
if(mfs == 0) return;
Universe u = type.getUniverse();
double min = u.min();
double max = u.max();
double r = (max-min)/(mfs+1);
double param[] = new double[mfs];
for(int i=0; i<param.length; i++) param[i] = min + (i+1)*r;
Family fam = new pkg.xfl.family.sh_triangular();
fam.set("fam",type);
try { fam.set(param); type.addFamily(fam); } catch(XflException ex) {}
for(int i=0; i<mfs; i++) {
FamiliarMemFunc fmf = new FamiliarMemFunc("mf"+i,fam,i);
try { type.add(fmf); } catch(XflException e) {}
}
}
//-------------------------------------------------------------//
// Crea una familia de B-splines //
//-------------------------------------------------------------//
private void createBsplinesFamily(Type type, int mfs) {
if(mfs == 0) return;
Universe u = type.getUniverse();
double min = u.min();
double max = u.max();
double r = (max-min)/(mfs-2);
double param[] = new double[mfs-3];
for(int i=0; i<param.length; i++) param[i] = min + (i+1)*r;
Family fam = new pkg.xfl.family.spline();
fam.set("fam",type);
try { fam.set(param); type.addFamily(fam); } catch(XflException ex) {}
for(int i=0; i<mfs; i++) {
FamiliarMemFunc fmf = new FamiliarMemFunc("mf"+i,fam,i);
try { type.add(fmf); } catch(XflException e) {}
}
}
//-------------------------------------------------------------//
// Crea un conjunto de etiquetas (singularidades) //
//-------------------------------------------------------------//
private void createClasses(Type type, double[] value) {
Universe u = type.getUniverse();
ParamMemFunc pmf[] = new ParamMemFunc[value.length];
for(int i=0; i<value.length; i++) {
pmf[i] = new pkg.xfl.mfunc.singleton();
pmf[i].set("mf"+i, u);
pmf[i].set(value[i]);
}
try { for(int i=0; i<pmf.length; i++) type.add(pmf[i]); }
catch(XflException e) {}
}
//-------------------------------------------------------------//
// Crea un conjunto de campanas centradas //
//-------------------------------------------------------------//
private void createBells(Type type, int mfs) {
if(mfs == 0) return;
Universe u = type.getUniverse();
double min = u.min();
double max = u.max();
double param[] = new double[2];
param[0] = (min + max)/2;
param[1] = (max - min)/8;
ParamMemFunc pmf[] = new ParamMemFunc[mfs];
for(int i=0; i<mfs; i++) {
pmf[i] = new pkg.xfl.mfunc.bell();
pmf[i].set("mf"+i, u);
try { pmf[i].set(param); } catch(XflException ex) {}
}
try { for(int i=0; i<mfs; i++) type.add(pmf[i]); }
catch(XflException e) {}
}
//-------------------------------------------------------------//
// Crea un conjunto de singularidades centradas //
//-------------------------------------------------------------//
private void createSingletons(Type type, int mfs) {
if(mfs == 0) return;
Universe u = type.getUniverse();
double min = u.min();
double max = u.max();
double middle = (min + max)/2 ;
ParamMemFunc pmf[] = new ParamMemFunc[mfs];
for(int i=0; i<mfs; i++) {
pmf[i] = new pkg.xfl.mfunc.singleton();
pmf[i].set("mf"+i, u);
pmf[i].set(middle);
}
try { for(int i=0; i<mfs; i++) type.add(pmf[i]); }
catch(XflException e) {}
}
//-------------------------------------------------------------//
// Crea un conjunto de funciones de Takagi-Sugeno //
//-------------------------------------------------------------//
private void createTakagi(Type type, int mfs, int np) {
if(mfs == 0) return;
Universe u = type.getUniverse();
double param[] = new double[np];
for(int i=0; i<np; i++) param[i] = 1.0;
ParamMemFunc pmf[] = new ParamMemFunc[mfs];
for(int i=0; i<mfs; i++) {
pmf[i] = new pkg.xfl.mfunc.parametric();
pmf[i].set("mf"+i, u);
try { pmf[i].set(param); } catch(XflException ex) {}
}
try { for(int i=0; i<mfs; i++) type.add(pmf[i]); }
catch(XflException e) {}
}
}