//--------------------------------------------------------------------------------//
// 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.xfvhdl;
import xfuzzy.lang.*;
//import xfuzzy.xfvhdl.XfvhdlError;
import java.util.*;
/**
* Clase que discretiza el universo de discurso de una variable
*
* @author Lidia Delgado Carretero
*
*/
public class XfvhdlDiscretizeUniverse {
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// M�TO_DOS P�BLICOS DE LA CLASE
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**Atributo que nos avisa si las entradas no est�n normalizadas
* porque el solapamiento entre las funciones de pertenencia
* es mayor que 1.*/
boolean EntradasNoNormalizadasMayor1;
/**Atributo que nos avisa si las entradas no est�n normalizadas
* porque el solapamiento entre las funciones de pertenencia
* es menor que 1.*/
boolean EntradasNoNormalizadasMenor1;
/**Constructor de la clase.*/
public XfvhdlDiscretizeUniverse(){
EntradasNoNormalizadasMayor1=false;
EntradasNoNormalizadasMenor1=false;
}
/**
* M�todo que discretiza el universo de discurso de una variable.
* @return Devuelve el universo de discurso de la variable v
* discretizado.
*/
public XfvhdlUniverse discretizeUniverse(Variable v, XfvhdlFLC flc, int entrada) {
List mf_sorted = new ArrayList();
ParamMemFunc mf1 = null;
ParamMemFunc mf2 = null;
FamiliarMemFunc fmf1=null;
FamiliarMemFunc fmf2=null;
double minMF1=5000, minFMF1=5000;
double maxMF1=-5000, maxFMF1=-5000;
int total;
int actual = 0;
double valor1;
double valor2;
List puntos = new ArrayList();
double factor;
double iR, iN;
boolean familiar;
int cardinalidad=8;
EntradasNoNormalizadasMayor1=false;
EntradasNoNormalizadasMenor1=false;
if(flc.getN()!=0){
cardinalidad=flc.getN();
}
// Crea un XUniverse con cardinalidad N (que es el n�mero de bits
// con que se codifican las entradas)siempre y cuando este dato se
// haya inicializado previamente.
XfvhdlUniverse u =
new XfvhdlUniverse(
v.getName(),
v.getType().getUniverse().max(),
v.getType().getUniverse().min(),
cardinalidad);
// Crea un objeto XFvhdlInOrderParamMemFunc con las funciones
// de pertenencia ordenadas de la variable v
XfvhdlInOrderParamMemFunc inOrderMf =
new XfvhdlInOrderParamMemFunc(v);
// Ordena las funciones de pertenencia de la variable v
mf_sorted = inOrderMf.sort();
// Calcula el n�mero de funciones de pertenencia
total = mf_sorted.size();
if (mf_sorted.size()==0&&inOrderMf.getFamiliarMemFunc().length>0){
familiar=true;
total=inOrderMf.getFamiliarMemFunc().length;
}else
familiar=false;
//Si la funciones de pertenencia de la emtrada es una familia de funciones,
//entonces, la entrada est� normalizada y no hay que comprobar m�s nada.
if(familiar){
EntradasNoNormalizadasMayor1=false;
//return null;
}
// Comprueba el solapamiento 2 a 2
if (total >= 2&&!familiar) {
// Comprueba el solapamiento de todas las funciones de
// pertenencia menos las tres �ltimas
for (int i = 0; i < total - 2; i++) {
mf1 = (ParamMemFunc) mf_sorted.get(i);
mf2 = (ParamMemFunc) mf_sorted.get(i + 2);
if (inOrderMf.opMemFuncParameter(mf1, "max")
> inOrderMf.opMemFuncParameter(mf2, "min")) {
new XfvhdlError(4, v.getName());
EntradasNoNormalizadasMayor1=true;
}
}
// Comprueba el solapamiento en las tres �ltimas funciones
// de pertenencia
mf1 = (ParamMemFunc) mf_sorted.get(total - 3);
mf2 = (ParamMemFunc) mf_sorted.get(total - 1);
if (inOrderMf.opMemFuncParameter(mf1, "max")
> inOrderMf.opMemFuncParameter(mf2, "min")) {
new XfvhdlError(4, v.getName());
EntradasNoNormalizadasMayor1=true;
}
}
// Coge las dos primeras funciones de pertenencia
if (total == 0&&!familiar) { // no puede ser que no existan funciones
new XfvhdlError(5, v.getName());
}
if(!familiar) {
mf1 = (ParamMemFunc) mf_sorted.get(actual);
minMF1 = inOrderMf.opMemFuncParameter(mf1, "min");
maxMF1 = inOrderMf.opMemFuncParameter(mf1, "max");
} else {
fmf1= (FamiliarMemFunc) inOrderMf.getFamiliarMemFunc()[actual];
minFMF1 = minimoFamilia(actual, entrada, total, flc);
maxFMF1 = maximoFamilia(actual, entrada, total, flc);
}
actual++;
if (actual == total) {
// si solo hay una funcion de pertenencia coge esa funci�n 2 veces
actual--;
}
if(!familiar) {
mf2 = (ParamMemFunc) mf_sorted.get(actual);
} else {
fmf2= (FamiliarMemFunc) inOrderMf.getFamiliarMemFunc()[actual];
}
actual++;
// calcula el factor necesario para mantener la relaci�n entre los
// universos de discurso
factor =
(v.getType().getUniverse().max()
- v.getType().getUniverse().min())
/ Math.pow((double) 2, (double) cardinalidad);
// Hace un recorrido para cada uno de los puntos del universo de
// discurso
long precision=1000000000;
for (int i = 0;
i < (int) Math.pow((double) 2, (double) cardinalidad);
i++) {
iR = ( i * factor) + v.getType().getUniverse().min();
iN = ( i / Math.pow((double) 2, (double) cardinalidad));
if(!familiar){
if (iR < minMF1) {
//si el punto es menor que el m�nimo de mf1 a�ade un 0
u.addXUniversePoint(new XfvhdlUniversePoint(actual - 1, 0, 0));
puntos.add(new Double(0));
} else if (iR >= minMF1 && iR <= maxMF1) {
// si i est� dentro de la funci�n de pertenencia mf1
valor1 = mf1.compute((double) iR);
valor2 = mf2.compute((double) iR);
valor1=Math.round(valor1*precision)/1000000000.0;
valor2=Math.round(valor2*precision)/1000000000.0;
u.addXUniversePoint(new XfvhdlUniversePoint(actual - 1, valor1, valor2));
if((valor1+valor2)<1.0){
EntradasNoNormalizadasMenor1=true;
}
} else {
if (actual < total) { //avanza una funci�n de pertenencia
mf1 = mf2;
mf2 = (ParamMemFunc) mf_sorted.get(actual);
minMF1 = inOrderMf.opMemFuncParameter(mf1, "min");
maxMF1 = inOrderMf.opMemFuncParameter(mf1, "max");
actual++;
}
valor1 = mf1.compute((double) iR);
valor2 = mf2.compute((double) iR);
valor1=Math.round(valor1*precision)/1000000000.0;
valor2=Math.round(valor2*precision)/1000000000.0;
u.addXUniversePoint(new XfvhdlUniversePoint(actual - 1, valor1, valor2));
if((valor1+valor2)<1.0){
EntradasNoNormalizadasMenor1=true;
}
}
}else{
if (iN < minFMF1) {
//si el punto es menor que el m�nimo de mf1 a�ade un 0
u.addXUniversePoint(new XfvhdlUniversePoint(actual - 1, 0, 0));
puntos.add(new Double(0));
} else if (
iN >= minFMF1 && iN <= maxFMF1) {
// si i est� dentro de la funci�n de pertenencia mf1
valor1 = fmf1.compute((double) iR);
valor2 = fmf2.compute((double) iR);
valor1=Math.round(valor1*precision)/1000000000.0;
valor2=Math.round(valor2*precision)/1000000000.0;
u.addXUniversePoint(new XfvhdlUniversePoint(actual - 1, valor1, valor2));
} else {
if (actual < total) { //avanza una funci�n de pertenencia
fmf1 = fmf2;
fmf2 = (FamiliarMemFunc) inOrderMf.getFamiliarMemFunc()[actual];
minFMF1 = minimoFamilia(actual-1, entrada, total, flc);
maxFMF1 = maximoFamilia(actual-1, entrada, total, flc);
actual++;
}
valor1 = fmf1.compute((double) iR);
valor2 = fmf2.compute((double) iR);
valor1=Math.round(valor1*precision)/1000000000.0;
valor2=Math.round(valor2*precision)/1000000000.0;
u.addXUniversePoint(new XfvhdlUniversePoint(actual - 1, valor1, valor2));
}
}
}
return u;
}
/**@return EntradasNoNormalizadasMayor1*/
public boolean getEntradasNoNormalizadasMayor1(){
return EntradasNoNormalizadasMayor1;
}
/**@return EntradasNoNormalizadasMenor1*/
public boolean getEntradasNoNormalizadasMenor1(){
return EntradasNoNormalizadasMenor1;
}
/**@param actual �ndice de la funci�n de pertenencia actual.
* @param entrada �ndice de la entrada del flc actual.
* @param total N�mero de funciones de pertenencia.
* @param flc M�dulo de inferencia.
* @return M�nimo de la funci�n de pertenencia.*/
public double minimoFamilia(int actual, int entrada, int total, XfvhdlFLC flc){
double min;
if(actual==0)
min=0;
else if(actual==total)
min=flc.getmfcs().get(entrada).getPunto(actual-1);
else//Este es el caso general
min=flc.getmfcs().get(entrada).getPunto(actual-1);
return min;
}
/**@param actual �ndice de la funci�n de pertenencia actual.
* @param entrada �ndice de la entrada del flc actual.
* @param total N�mero de funciones de pertenencia.
* @param flc M�dulo de inferencia.
* @return M�ximo de la funci�n de pertenencia.*/
public double maximoFamilia(int actual, int entrada, int total, XfvhdlFLC flc){
double max;
if(actual==0)
max=flc.getmfcs().get(entrada).getPunto(actual+1);
else if(actual==total)
max=1;
else//Este es el caso general
max=flc.getmfcs().get(entrada).getPunto(actual+1);
return max;
}
} // Fin de la clase