//--------------------------------------------------------------------------------//
// 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. //
//--------------------------------------------------------------------------------//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// FUNCION DE ERROR //
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
package xfuzzy.xfsl;
import xfuzzy.lang.*;
public class XfslErrorFunction implements Cloneable {
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// CONSTANTES PUBLICAS //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
public static final int MEAN_SQUARE_ERROR = 0;
public static final int W_MEAN_SQUARE_ERROR = 1;
public static final int MEAN_ABS_ERROR = 2;
public static final int W_MEAN_ABS_ERROR = 3;
public static final int CLASIF_ERROR = 4;
public static final int ADV_CLASIF_ERROR = 5;
public static final int NEFCLASS = 6;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// MIEMBROS PRIVADOS //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
private int code;
private double[] weight;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// CONSTRUCTORES //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//-------------------------------------------------------------//
// Constructor utilizado en la interfaz grafica //
//-------------------------------------------------------------//
public XfslErrorFunction(int code) throws XflException {
if(code < 0) throw new XflException(25);
this.code = code;
this.weight = new double[0];
}
//-------------------------------------------------------------//
// Constructor usado en la configuracion //
//-------------------------------------------------------------//
public XfslErrorFunction(String name) throws XflException {
this(nameToCode(name));
}
//-------------------------------------------------------------//
// Constructor con pesos usado en la configuracion //
//-------------------------------------------------------------//
public XfslErrorFunction(String name, double[] weights) throws XflException {
this(nameToCode(name));
setWeights(weights);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// METODOS ESTATICOS PRIVADOS //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//-------------------------------------------------------------//
// Parser de los identificadores de las funciones //
//-------------------------------------------------------------//
private static int nameToCode(String name) {
if(name.equals("mean_square_error")) return MEAN_SQUARE_ERROR;
if(name.equals("weighted_mean_square_error")) return W_MEAN_SQUARE_ERROR;
if(name.equals("mean_absolute_error")) return MEAN_ABS_ERROR;
if(name.equals("weighted_mean_absolute_error")) return W_MEAN_ABS_ERROR;
if(name.equals("classification_error")) return CLASIF_ERROR;
if(name.equals("advanced_classification_error")) return ADV_CLASIF_ERROR;
if(name.equals("classification_square_error")) return NEFCLASS;
if(name.equals("MSE")) return MEAN_SQUARE_ERROR;
if(name.equals("WMSE")) return W_MEAN_SQUARE_ERROR;
if(name.equals("MAE")) return MEAN_ABS_ERROR;
if(name.equals("WMAE")) return W_MEAN_ABS_ERROR;
if(name.equals("CE")) return CLASIF_ERROR;
if(name.equals("ACE")) return ADV_CLASIF_ERROR;
if(name.equals("CSE")) return NEFCLASS;
return -1;
}
//-------------------------------------------------------------//
// Identificador asociado a cada funcion //
//-------------------------------------------------------------//
private static String codeToName(int code) {
switch(code) {
case MEAN_SQUARE_ERROR: return "MSE";
case W_MEAN_SQUARE_ERROR: return "WMSE";
case MEAN_ABS_ERROR: return "MAE";
case W_MEAN_ABS_ERROR: return "WMAE";
case CLASIF_ERROR: return "CE";
case ADV_CLASIF_ERROR: return "ACE";
case NEFCLASS: return "CSE";
}
return null;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// METODOS PUBLICOS //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//-------------------------------------------------------------//
// Devuelve una copia del objeto //
//-------------------------------------------------------------//
public Object clone() {
try {
XfslErrorFunction clone = new XfslErrorFunction(this.code);
double wclone[] = new double[weight.length];
System.arraycopy(weight,0,wclone,0,weight.length);
clone.setWeights(wclone);
return clone;
} catch(Exception ex) { return null; }
}
//-------------------------------------------------------------//
// Obtiene el codigo de la funcion //
//-------------------------------------------------------------//
public int getCode() { return code; }
//-------------------------------------------------------------//
// Obtiene el nombre de la funcion (para la ventana de xfsl) //
//-------------------------------------------------------------//
public String getName() {
switch(code) {
case MEAN_SQUARE_ERROR: return "Mean Square Error";
case W_MEAN_SQUARE_ERROR: return "Weighted Mean Square Error";
case MEAN_ABS_ERROR: return "Mean Absolute Error";
case W_MEAN_ABS_ERROR: return "Weighted Mean Absolute Error";
case CLASIF_ERROR: return "Classification Error";
case ADV_CLASIF_ERROR: return "Advanced Classification Error";
case NEFCLASS: return "Classification Square Error";
}
return null;
}
//-------------------------------------------------------------//
// Analiza si es una funcion de error de clasificacion //
//-------------------------------------------------------------//
public boolean isClassification() {
switch(code) {
case MEAN_SQUARE_ERROR:
case W_MEAN_SQUARE_ERROR:
case MEAN_ABS_ERROR:
case W_MEAN_ABS_ERROR: return false;
case CLASIF_ERROR:
case ADV_CLASIF_ERROR:
case NEFCLASS: return true;
default: return false;
}
}
//-------------------------------------------------------------//
// Analiza si la funcion utiliza pesos //
//-------------------------------------------------------------//
public boolean isWeighted() {
return (code == W_MEAN_SQUARE_ERROR || code == W_MEAN_ABS_ERROR);
}
//-------------------------------------------------------------//
// Codigo del fichero de configuracion //
//-------------------------------------------------------------//
public String toCode() {
String eol = System.getProperty("line.separator", "\n");
String src = "xfsl_errorfunction("+codeToName(code);
for(int i=0; i<weight.length; i++) src += ", "+weight[i];
src += ")"+eol;
return src;
}
//-------------------------------------------------------------//
// Asigna los valores de los pesos //
//-------------------------------------------------------------//
public void setWeights(double[] weight) throws XflException {
if(!isWeighted() && weight.length>0) throw new XflException(25);
this.weight = weight;
}
//-------------------------------------------------------------//
// Obtiene los valores de los pesos //
//-------------------------------------------------------------//
public double[] getWeights() {
return this.weight;
}
//-------------------------------------------------------------//
// Normaliza el valor de los pesos //
//-------------------------------------------------------------//
public void normalizeWeights(int numoutputs) {
if(!isWeighted()) return;
double aw[] = new double[numoutputs];
double norm = 0;
for(int i=0; i<weight.length && i<numoutputs; i++) norm += weight[i];
for(int i=weight.length; i<numoutputs; i++) norm += 1;
for(int i=0; i<weight.length && i<numoutputs; i++) aw[i] = weight[i]/norm;
for(int i=weight.length; i<numoutputs; i++) aw[i] = 1/norm;
this.weight = aw;
}
//-------------------------------------------------------------//
// Evalua la funcion de error para un conjunto de patrones //
//-------------------------------------------------------------//
public XfslEvaluation evaluate(Specification s, XfslPattern p, double le) {
switch(code) {
case MEAN_SQUARE_ERROR: return MSE(s,p,le);
case W_MEAN_SQUARE_ERROR: return WMSE(s,p,le);
case MEAN_ABS_ERROR: return MAE(s,p,le);
case W_MEAN_ABS_ERROR: return WMAE(s,p,le);
case CLASIF_ERROR: return CE(s,p,le);
case ADV_CLASIF_ERROR: return ACE(s,p,le);
case NEFCLASS: return NCE(s,p,le);
}
return null;
}
//-------------------------------------------------------------//
// Calcula las derivadas del sistema //
//-------------------------------------------------------------//
public XfslEvaluation compute_derivatives(Specification s, XfslPattern p)
throws XflException{
switch(code) {
case MEAN_SQUARE_ERROR: return dMSE(s,p);
case W_MEAN_SQUARE_ERROR: return dWMSE(s,p);
case MEAN_ABS_ERROR: return dMAE(s,p);
case W_MEAN_ABS_ERROR: return dWMAE(s,p);
case CLASIF_ERROR: return dCE(s,p);
case ADV_CLASIF_ERROR: return dACE(s,p);
case NEFCLASS: return dNCE(s,p);
}
throw new XflException(19);
}
//-------------------------------------------------------------//
// Estima las derivadas del sistema mediante la tangente //
//-------------------------------------------------------------//
public XfslEvaluation estimate_derivatives(Specification spec,
XfslPattern pattern, double perturb) {
Parameter[] adjustable = spec.getAdjustable();
XfslEvaluation ev1 = evaluate(spec,pattern,1.0);
for(int i=0; i<adjustable.length; i++) {
double prev = adjustable[i].value;
double sign = (Math.random() <0.5? 1.0 : -1.0);
adjustable[i].setDesp(sign*perturb);
spec.update();
XfslEvaluation ev2 = evaluate(spec,pattern,1.0);
if((adjustable[i].value - prev)/(sign*perturb) >0.001 ) {
double deriv = (ev2.error - ev1.error)/(adjustable[i].value - prev);
adjustable[i].addDeriv( deriv );
}
adjustable[i].value = prev;
}
return ev1;
}
//-------------------------------------------------------------//
// Estima las derivadas del sistema de forma grosera //
//-------------------------------------------------------------//
public XfslEvaluation stochastic_derivatives(Specification spec,
XfslPattern pattern, double perturb) {
Parameter[] adjustable = spec.getAdjustable();
double prev[] = new double[adjustable.length];
double val1[] = new double[adjustable.length];
double sign[] = new double[adjustable.length];
for(int i=0; i<adjustable.length; i++) {
prev[i] = adjustable[i].value;
sign[i] = (Math.random() <0.5? 1.0 : -1.0);
adjustable[i].setDesp(sign[i]*perturb);
}
spec.update();
XfslEvaluation ev1 = evaluate(spec,pattern,1.0);
for(int i=0; i<adjustable.length; i++) {
val1[i] = adjustable[i].value;
adjustable[i].value = prev[i];
adjustable[i].setDesp(-sign[i]*perturb);
}
spec.update();
XfslEvaluation ev2 = evaluate(spec,pattern,1.0);
for(int i=0; i<adjustable.length; i++) {
double val2 = adjustable[i].value;
adjustable[i].value = prev[i];
if( (val1[i]-val2)/(sign[i]*perturb) >0.001 )
adjustable[i].addDeriv((ev2.error - ev1.error)/(val2 - val1[i]));
}
return evaluate(spec,pattern,1.0);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// METODOS PRIVADOS //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//-------------------------------------------------------------//
// Calculo de Mean Square Error //
//-------------------------------------------------------------//
private XfslEvaluation MSE(Specification spec,XfslPattern pattern,double le) {
SystemModule system = spec.getSystemModule();
double mxae=0, mse=0, error=0;
for(int p=0; p<pattern.input.length; p++) {
double[] output = system.crispInference(pattern.input[p]);
for(int i=0; i<output.length; i++) {
double dev = (output[i]-pattern.output[p][i])/pattern.range[i];
if(dev<0) dev = -dev;
error += dev*dev/output.length;
mse += dev*dev/output.length;
if(dev>mxae) mxae = dev;
}
}
return new XfslEvaluation(error,mse,mxae,le,pattern.input.length);
}
//-------------------------------------------------------------//
// Calculo de Weighted Mean Square Error //
//-------------------------------------------------------------//
private XfslEvaluation WMSE(Specification spec,XfslPattern pattern,double le) {
SystemModule system = spec.getSystemModule();
double mxae=0, mse=0, error=0;
for(int p=0; p<pattern.input.length; p++) {
double[] output = system.crispInference(pattern.input[p]);
for(int i=0; i<output.length; i++) {
double dev = (output[i]-pattern.output[p][i])/pattern.range[i];
if(dev<0) dev = -dev;
error += weight[i]*dev*dev;
mse += dev*dev/output.length;
if(dev>mxae) mxae = dev;
}
}
return new XfslEvaluation(error,mse,mxae,le,pattern.input.length);
}
//-------------------------------------------------------------//
// Calculo de Mean Absolute Error //
//-------------------------------------------------------------//
private XfslEvaluation MAE(Specification spec,XfslPattern pattern,double le) {
SystemModule system = spec.getSystemModule();
double mxae=0, mse=0, error=0;
for(int p=0; p<pattern.input.length; p++) {
double[] output = system.crispInference(pattern.input[p]);
for(int i=0; i<output.length; i++) {
double dev = (output[i]-pattern.output[p][i])/pattern.range[i];
if(dev<0) dev = -dev;
error += dev/output.length;
mse += dev*dev/output.length;
if(dev>mxae) mxae = dev;
}
}
return new XfslEvaluation(error,mse,mxae,le,pattern.input.length);
}
//-------------------------------------------------------------//
// Calculo de Weighted Mean Absolute Error //
//-------------------------------------------------------------//
private XfslEvaluation WMAE(Specification spec,XfslPattern pattern,double le) {
SystemModule system = spec.getSystemModule();
double mxae=0, mse=0, error=0;
for(int p=0; p<pattern.input.length; p++) {
double[] output = system.crispInference(pattern.input[p]);
for(int i=0; i<output.length; i++) {
double dev = (output[i]-pattern.output[p][i])/pattern.range[i];
if(dev<0) dev = -dev;
error += weight[i]*dev;
mse += dev*dev/output.length;
if(dev>mxae) mxae = dev;
}
}
return new XfslEvaluation(error,mse,mxae,le,pattern.input.length);
}
//-------------------------------------------------------------//
// Calculo de Classification Error //
//-------------------------------------------------------------//
private XfslEvaluation CE(Specification spec, XfslPattern pattern, double le) {
SystemModule system = spec.getSystemModule();
double misscr=0, misscn=0, error=0;
for(int p=0; p<pattern.input.length; p++) {
double[] output = system.crispInference(pattern.input[p]);
double norm = output.length * pattern.input.length;
double err = 0;
for(int i=0; i<output.length; i++)
if(output[i] != pattern.output[p][i]) err++;
error += err/norm;
misscn += err;
misscr += err/norm;
}
return new XfslEvaluation(error,misscr,misscn,le);
}
//-------------------------------------------------------------//
// Calculo de Advanced Classification Error //
//-------------------------------------------------------------//
private XfslEvaluation ACE(Specification spec,XfslPattern pattern,double le) {
SystemModule system = spec.getSystemModule();
double misscr=0, misscn=0, error=0;
for(int p=0; p<pattern.input.length; p++) {
double[] output = system.crispInference(pattern.input[p]);
double norm = output.length * pattern.input.length;
AggregateMemFunc[] fuzzyvalue = system.getFuzzyValues();
double err1=0, err2=0;
for(int i=0; i<output.length; i++) {
if(output[i] != pattern.output[p][i]) {
double degree1 = fuzzyvalue[i].getActivationDegree(output[i]);
double degree2 = fuzzyvalue[i].getActivationDegree(pattern.output[p][i]);
err1 += 1 + ( degree1 - degree2 )/output.length;
err2++;
}
}
error += err1/norm;
misscr += err2/norm;
misscn += err2;
}
return new XfslEvaluation(error,misscr,misscn,le);
}
//-------------------------------------------------------------//
// Calculo de Square Classification Error //
//-------------------------------------------------------------//
private XfslEvaluation NCE(Specification spec,XfslPattern pattern,double le) {
SystemModule system = spec.getSystemModule();
double misscr=0, misscn=0, error=0;
for(int p=0; p<pattern.input.length; p++) {
double[] output = system.crispInference(pattern.input[p]);
double norm = output.length * pattern.input.length;
AggregateMemFunc[] fuzzyvalue = system.getFuzzyValues();
Variable[] outvar = system.getOutputs();
double err1 = 0, err2 = 0;
for(int i=0; i<output.length; i++) {
LinguisticLabel[] pmf = outvar[i].getType().getAllMembershipFunctions();
for(int j=0; j<pmf.length; j++) {
double degree = fuzzyvalue[i].getActivationDegree(pmf[j].center());
if(pmf[j].center() == pattern.output[p][i])
err1 += (1-degree)*(1-degree)/pmf.length;
else err1 += degree*degree/pmf.length;
}
if(output[i] != pattern.output[p][i]) err2++;
}
error += err1/norm;
misscr += err2/norm;
misscn += err2;
}
return new XfslEvaluation(error,misscr,misscn,le);
}
//-------------------------------------------------------------//
// Derivada de Mean Square Error //
//-------------------------------------------------------------//
private XfslEvaluation dMSE(Specification spec, XfslPattern pattern)
throws XflException {
SystemModule system = spec.getSystemModule();
double mxae=0, mse=0, error=0;
double[] range = pattern.range;
int numpatterns = pattern.input.length;
for(int p=0; p<numpatterns; p++) {
double[] output = system.crispInference(pattern.input[p]);
double[] target = pattern.output[p];
double[] deriv = new double[output.length];
for(int i=0; i<output.length; i++) {
double dev = (output[i]-target[i])/range[i];
deriv[i] = 2*dev/(range[i]*output.length*numpatterns);
if(dev<0) dev = -dev;
error += dev*dev/output.length;
mse += dev*dev/output.length;
if(dev>mxae) mxae = dev;
}
system.derivative(deriv);
}
return new XfslEvaluation(error,mse,mxae,numpatterns);
}
//-------------------------------------------------------------//
// Derivada de Weighted Mean Square Error //
//-------------------------------------------------------------//
private XfslEvaluation dWMSE(Specification spec, XfslPattern pattern)
throws XflException {
SystemModule system = spec.getSystemModule();
double[] range = pattern.range;
double mxae=0, mse=0, error=0;
int numpatterns = pattern.input.length;
for(int p=0; p<pattern.input.length; p++) {
double[] output = system.crispInference(pattern.input[p]);
double[] target = pattern.output[p];
double[] deriv = new double[output.length];
for(int i=0; i<output.length; i++) {
double dev = (output[i]-target[i])/range[i];
deriv[i] = 2*weight[i]*dev/(range[i]*numpatterns);
if(dev<0) dev = -dev;
error += weight[i]*dev*dev;
mse += dev*dev/output.length;
if(dev>mxae) mxae = dev;
}
system.derivative(deriv);
}
return new XfslEvaluation(error,mse,mxae,numpatterns);
}
//-------------------------------------------------------------//
// Derivada de Mean Absolute Error //
//-------------------------------------------------------------//
private XfslEvaluation dMAE(Specification spec, XfslPattern pattern)
throws XflException {
SystemModule system = spec.getSystemModule();
double[] range = pattern.range;
double mxae=0, mse=0, error=0;
int numpatterns = pattern.input.length;
for(int p=0; p<pattern.input.length; p++) {
double[] output = system.crispInference(pattern.input[p]);
double[] target = pattern.output[p];
double[] deriv = new double[output.length];
for(int i=0; i<output.length; i++) {
double dev = (output[i]-target[i])/range[i];
if(dev>0) deriv[i] = 1.0;
else if(dev<0) deriv[i] = -1.0;
else deriv[i] = 0;
deriv[i] /= (range[i]*output.length*numpatterns);
if(dev<0) dev = -dev;
error += dev/output.length;
mse += dev*dev/output.length;
if(dev>mxae) mxae = dev;
}
system.derivative(deriv);
}
return new XfslEvaluation(error,mse,mxae,numpatterns);
}
//-------------------------------------------------------------//
// Derivada de Weighted Mean Absolute Error //
//-------------------------------------------------------------//
private XfslEvaluation dWMAE(Specification spec, XfslPattern pattern)
throws XflException {
SystemModule system = spec.getSystemModule();
double[] range = pattern.range;
double mxae=0, mse=0, error=0;
int numpatterns = pattern.input.length;
for(int p=0; p<pattern.input.length; p++) {
double[] output = system.crispInference(pattern.input[p]);
double[] target = pattern.output[p];
double[] deriv = new double[output.length];
for(int i=0; i<output.length; i++) {
double dev = (output[i]-target[i])/range[i];
if(dev>0) deriv[i] = weight[i];
else if(dev<0) deriv[i] = -weight[i];
else deriv[i] = 0;
deriv[i] /= (range[i]*numpatterns);
if(dev<0) dev = -dev;
error += weight[i]*dev;
mse += dev*dev/output.length;
if(dev>mxae) mxae = dev;
}
system.derivative(deriv);
}
return new XfslEvaluation(error,mse,mxae,numpatterns);
}
//-------------------------------------------------------------//
// Derivada de Classification Error //
//-------------------------------------------------------------//
private XfslEvaluation dCE(Specification spec, XfslPattern pattern)
throws XflException {
throw new XflException(19);
}
//-------------------------------------------------------------//
// Derivada de Advanced Classification Error //
//-------------------------------------------------------------//
private XfslEvaluation dACE(Specification spec, XfslPattern pattern)
throws XflException {
throw new XflException(19);
}
//-------------------------------------------------------------//
// Derivada de Square Classification Error //
//-------------------------------------------------------------//
private XfslEvaluation dNCE(Specification spec, XfslPattern pattern)
throws XflException {
SystemModule system = spec.getSystemModule();
double misscr=0, misscn=0, error=0;
for(int p=0; p<pattern.input.length; p++) {
double[] output = system.crispInference(pattern.input[p]);
double normalize = output.length * pattern.input.length;
AggregateMemFunc[] fuzzyvalue = system.getFuzzyValues();
Variable[] outvar = system.getOutputs();
double err1 = 0, err2 = 0;
for(int i=0; i<output.length; i++) {
LinguisticLabel[] pmf = outvar[i].getType().getAllMembershipFunctions();
for(int j=0; j<fuzzyvalue[i].conc.length; j++) {
double center = fuzzyvalue[i].conc[j].center();
double degree = fuzzyvalue[i].getActivationDegree(center);
double norm = pattern.input.length*output.length*pmf.length;
if(fuzzyvalue[i].conc[j].degree() == degree)
if(center == pattern.output[p][i])
fuzzyvalue[i].conc[j].setDegreeDeriv(-2*(1-degree)/norm);
else fuzzyvalue[i].conc[j].setDegreeDeriv(2*degree/norm);
}
for(int j=0; j<pmf.length; j++) {
double degree = fuzzyvalue[i].getActivationDegree(pmf[j].center());
if(pmf[j].center() == pattern.output[p][i])
err1 += (1-degree)*(1-degree)/pmf.length;
else err1 += degree*degree/pmf.length;
}
if(output[i] != pattern.output[p][i]) err2++;
}
error += err1/normalize;
misscr += err2/normalize;
misscn += err2;
system.derivative();
}
return new XfslEvaluation(error,misscr,misscn);
}
}