///////////////////////////////////////////////////////////////////////////// // ruletree.cc // // SIMLIB version: 2.16.3 // Date: 2001-04-04 // Copyright (c) 1999-2001 David Martinek, Dr. Ing. Petr Peringer // // This library is licensed under GNU Library GPL. See the file COPYING. // // Warning: this is EXPERIMENTAL code, interfaces can be changed // // Fuzzy subsystem for SIMLIB // version 0.6 --- We apr 4 10:33:52 CEST 2001 // ///////////////////////////////////////////////////////////////////////////// // Implementation of genereal interface for typing in, representation and // evaluation of inference rules in a tree structure. ///////////////////////////////////////////////////////////////////////////// #include "fuzzy.h" #include #include #include /** * Constructor for an unary operator.
Konstruktor pro unární operátor. */ FOperation::FOperation(FONode *operand, FuzzyInferenceRules::Operations operation) : //FONode(FONode::ntOperation), op(operation), L(operand), R(NULL) { if (operation != FuzzyInferenceRules::opNOT) { SIMLIB_error("FOperation::FOperation: if operand is single then operation have to be opNOT!"); } } /** * Constructor is protected against user. Object of this class can create only * object of class FuzzyInferenceRules.
* Konstruktor je chráněn před uživatelem. Objekt této třídy může vytvořit * pouze objekt třídy FuzzyInferenceRules. */ FuzzyRuleFactory::FuzzyRuleFactory(FuzzyInferenceRules * owner) { this->owner = owner; rule = new FuzzyRule(); } /** * It safely creates fuzzy inference rule.
* Vrací bezpečným způsobem vytvořené pravidlo. */ FuzzyRule * FuzzyRuleFactory::createRule() { FuzzyRule *result = rule; rule = new FuzzyRule(); return result; } /** * It creates a leaf knot of rule.
* Vytvoří listový uzel pravidla. */ FPair * FuzzyRuleFactory::createNode(FuzzyVariable *var, const char * wordvalue, bool equal) { if (typeid(*var) == typeid(FuzzyInput)) { std::vector::iterator where = find(owner->in.begin(), owner->in.end(), var); if (where == owner->in.end()) SIMLIB_error("FuzzyRuleFactory::createNode: can not find this FuzzyInput inside FuzzyInferenceRules!"); } else if (typeid(*var) == typeid(FuzzyOutput)) { std::vector::iterator where = find(owner->out.begin(), owner->out.end(), var); if (where == owner->out.end()) SIMLIB_error("FuzzyRuleFactory::createNode: can not find this FuzzyOutput inside FuzzyInferenceRules!"); } return new FPair(var, wordvalue, equal); } /** * It creates a nonleaf knot of rule representing binary operator.
* Vytvoří nelistový uzel pravidla reprezentující binární operátor. */ FOperation * FuzzyRuleFactory::createNode(FONode *left, FONode *right, FuzzyInferenceRules::Operations operation) { return new FOperation(left, right, operation); } /** * It creates a nonleaf knot of rule representing unary operator.
* Vytvoří nelistový uzel pravidla reprezentující unární operátor. */ FOperation * FuzzyRuleFactory::createNode(FONode *operand, FuzzyInferenceRules::Operations operation) { return new FOperation(operand, operation); } /** * It adds condition of rule.
* Přidá podmínkovou část do pravidla. */ void FuzzyRuleFactory::addCondition(FOperation * operation) { // if (operation->getNodeType() != FONode::ntOperation) // if (typeid(*operation) != typeid(FOperation)) // { // SIMLIB_error("FuzzyRuleFactory::addCondition: operation have to be ntOperation!"); // } // rule->addLeft(operation); } /** * It adds next assign command into rule.
* Přidá další přiřazovací příkaz do příkazové části pravidla (konsekvent). */ void FuzzyRuleFactory::addConsequent(FPair * consequent) { // if (consequent->getNodeType() != FONode::ntPair) // if (typeid(*consequent) != typeid(FPair)) // { // SIMLIB_error("FuzzyRuleFactory::addConsequent: consequent have to be ntPair!"); // } // FPair * consq = dynamic_cast(consequent); if (typeid(*(consequent->var)) != typeid(FuzzyOutput)) { SIMLIB_error("FuzzyRuleFactory::addConsequent: consequent have to contain FuzzyOutput!"); } rule->addRight(consequent); } /** * Constructor. */ FuzzyRule::FuzzyRule() { left = NULL; } /** * Function for deleting objects in vector.
* Funkce pro mazání objektů ve vektoru. */ void del(FPair *p) { delete p; } /** * Destructor releases memory alocated by tree.
Destruktor uvolní paměť alokovanou stromem. */ FuzzyRule::~FuzzyRule() { if (left != NULL) for_each(right.begin(), right.end(), del); right.erase(right.begin(), right.end()); TRACE(printf("~FuzzyRule\n")); } /** * It adds the lvalue of rule.
Přidá levou stranu pravidla. */ void FuzzyRule::addLeft(FOperation *left) { this->left = left; } /** * It adds one command into list.
Přidá další příkaz do seznamu. */ void FuzzyRule::addRight(FPair *right) { this->right.push_back(right); } //////////////////////////////////////////////////////////////////////////////////// // Rule evaluation //////////////////////////////////////////////////////////////////////////////////// /** * If var is the FuzzyInput then this method returns fuzzified value of input. * In other words - value of membership function with name wordValue. Do not use if var is * a class FuzzyOutput. * * Jestliže parametr var je FuzzyInput, tato metoda vrací fuzzifikovanou hodnotu vstupu. * Jinými slovy - hodnotu funkce příslušnosti se jménem wordValue. Nepoužívejte jestliže je * var třídy FuzzyOutput. */ double FPair::getValue() { return (*var)[indexWV]; } /* pomocné funkce */ inline double rmin(double x, double y) { return (x < y) ? x : y; } inline double rmax(double x, double y) { return (x > y) ? x : y; } /** * It returns value after doing operation op.
Vrací hodnotu po provedení operace op. */ double FOperation::getValue() { switch (op) { case FuzzyInferenceRules::opAND: return rmin(L->getValue(), R->getValue()); break; case FuzzyInferenceRules::opOR: return rmax(L->getValue(), R->getValue()); break; case FuzzyInferenceRules::opNAND: return 1 - rmin(L->getValue(), R->getValue()); break; case FuzzyInferenceRules::opNOR: return 1 - rmax(L->getValue(), R->getValue()); break; case FuzzyInferenceRules::opNOT: return 1 - L->getValue(); break; default: return 0; break; } } /** * It evaluates one inference rule according to fuzzy model Mamdani.
* Vyhodnotí jedno inferenční pravidlo podle fuzzy modelu Mamdani. */ void FuzzyRule::evaluate() { for (unsigned int i = 0; i < right.size(); i++) { FuzzyVariable *out = right[i]->var; int indexWV = right[i]->indexWV; (*out)[indexWV] = rmax((*out)[indexWV], left->getValue()); } }