alvesoaj / eFLL

eFLL (Embedded Fuzzy Logic Library) is a standard library for Embedded Systems
MIT License
211 stars 91 forks source link

The defuzzification value seems incorrect. #41

Open dapeipa opened 10 months ago

dapeipa commented 10 months ago

I checked the result with Matlab and a Python library, which is the same (-1.22). But with this library, the result is -0.833557. The fuzzy output seems correct, but I think the fuzzy composition points of the output are incorrectly calculated. Then, the defuzzification process gives an incorrect value.

#include <iostream>
#include "../include/Fuzzy.h"

int main(int argc, char *argv[]) {

    //FIS
    Fuzzy *fuzzy = new Fuzzy();

    //INPUTS
    FuzzyInput* temperatura = new FuzzyInput(1);    
    FuzzySet* tbaja         = new FuzzySet( 10, 15, 15, 20);    
    FuzzySet* tnormal       = new FuzzySet( 18, 20, 20, 22);            
    temperatura->addFuzzySet(tbaja);
    temperatura->addFuzzySet(tnormal);      
    fuzzy->addFuzzyInput(temperatura);

    FuzzyInput* humedad     = new FuzzyInput(2);        
    FuzzySet* halta         = new FuzzySet( 40, 55,  55,  70);    
    FuzzySet* hmuyalta      = new FuzzySet( 60, 70, 100, 100);    
    humedad->addFuzzySet(halta);
    humedad->addFuzzySet(hmuyalta);
    fuzzy->addFuzzyInput(humedad);

    //OUTPUTS
    FuzzyOutput *variacionTemperatura = new FuzzyOutput(1);    
    FuzzySet* bajadapequeña           = new FuzzySet(-7.5, -2.5, -2.5,    0);    
    FuzzySet* mantener                = new FuzzySet(  -1,    0,    0,    1);    
    FuzzySet* subidapequeña           = new FuzzySet(  0,   2.5,  2.5,  7.5);    
    FuzzySet* subidanormal            = new FuzzySet(2.5,    5,     5,   10);            
    variacionTemperatura->addFuzzySet(bajadapequeña);
    variacionTemperatura->addFuzzySet(mantener);
    variacionTemperatura->addFuzzySet(subidapequeña);
    variacionTemperatura->addFuzzySet(subidanormal);

    fuzzy->addFuzzyOutput(variacionTemperatura);

    //RULES    

    FuzzyRuleAntecedent *ifBA = new FuzzyRuleAntecedent();
    ifBA->joinWithAND(tbaja, halta);        
    FuzzyRuleAntecedent *ifBMA = new FuzzyRuleAntecedent();
    ifBMA->joinWithAND(tbaja, hmuyalta);        

    FuzzyRuleAntecedent *ifNA = new FuzzyRuleAntecedent();
    ifNA->joinWithAND(tnormal, halta);        
    FuzzyRuleAntecedent *ifNMA = new FuzzyRuleAntecedent();
    ifNMA->joinWithAND(tnormal, hmuyalta);        

    FuzzyRuleConsequent *thenSP = new FuzzyRuleConsequent();
    thenSP->addOutput(subidapequeña);
    FuzzyRuleConsequent *thenSN = new FuzzyRuleConsequent();
    thenSN->addOutput(subidanormal);    
    FuzzyRuleConsequent *thenM = new FuzzyRuleConsequent();
    thenM->addOutput(mantener);
    FuzzyRuleConsequent *thenBP = new FuzzyRuleConsequent();
    thenBP->addOutput(bajadapequeña);    

    FuzzyRule *fuzzyRule9  = new FuzzyRule(9, ifBA,  thenSP);
    FuzzyRule *fuzzyRule10 = new FuzzyRule(10, ifBMA, thenSN);    
    FuzzyRule *fuzzyRule14 = new FuzzyRule(14, ifNA,  thenM);
    FuzzyRule *fuzzyRule15 = new FuzzyRule(15, ifNMA, thenBP);

    fuzzy->addFuzzyRule(fuzzyRule9);
    fuzzy->addFuzzyRule(fuzzyRule10);    
    fuzzy->addFuzzyRule(fuzzyRule14);
    fuzzy->addFuzzyRule(fuzzyRule15);

    fuzzy->setInput(1, 19.5);
    fuzzy->setInput(2, 65);

    fuzzy->fuzzify();

    //float o = fuzzy->defuzzify(1);
    //std::cout << "Running with: Temperature->" << 19.5 << ", Humidity->" << 65 << ". Result: " << o << std::endl;        

    temperatura->calculateFuzzySetPertinences();
    std::cout << "Input: \n\tTemperatura:  Baja->" << tbaja->getPertinence() << ", Normal->" << tnormal->getPertinence() <<  std::endl;
    humedad->calculateFuzzySetPertinences();
    std::cout << "\tHumedad: Alta-> " << halta->getPertinence() << ", Muy Alta->" << hmuyalta->getPertinence() << std::endl;

    std::cout << "Output: \n\tVariación temperatura: Bajada pequeña-> " << bajadapequeña->getPertinence()  << ", Mantener-> " << mantener->getPertinence() << std::endl;
    std::cout << "\tVariación temperatura: Subida pequeña-> " << subidapequeña->getPertinence() << ", Subida Normal->" << subidanormal->getPertinence() <<  std::endl;

    std::cout << "RESULT: " << variacionTemperatura->getCrispOutput() << std::endl;

    return 0;
}

The ouput is:

Input: 
        Temperatura:  Baja->0.1, Normal->0.75
        Humedad: Alta-> 0.333333, Muy Alta->0.5
Output: 
        Variación temperatura: Bajada pequeña-> 0.5, Mantener-> 0.333333
        Variación temperatura: Subida pequeña-> 0.1, Subida Normal->0.1
RESULT: -0.833557

The correct output (MATLAB): matlabFIS