1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Added fixed FuzzyLite library to sources. It compiles without additional settings under MVS2010 and should also compile with other tools (straightforward include structure).

Did not add it to project files to avoid mess.

Fixed NaN / infinity issues.
This commit is contained in:
DjWarmonger 2012-03-05 12:01:41 +00:00
parent 71e482ce7f
commit 1ea2f3d3bb
80 changed files with 6755 additions and 32 deletions

View File

@ -0,0 +1,165 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "AreaCentroidAlgorithm.h"
#include "FuzzyOperation.h"
#include "LinguisticTerm.h"
namespace fl {
std::string TriangulationAlgorithm::name() const {
return "Triangulation";
}
flScalar TriangulationAlgorithm::area(const LinguisticTerm* term,
int samples) const {
flScalar x, y;
return areaAndCentroid(term, x, y, samples);
}
void TriangulationAlgorithm::centroid(const LinguisticTerm* term,
flScalar& x, flScalar& y, int samples) const {
areaAndCentroid(term, x, y, samples);
}
flScalar TriangulationAlgorithm::areaAndCentroid(
const LinguisticTerm* term, flScalar& centroid_x,
flScalar& centroid_y, int samples) const {
centroid_x = flScalar(0);
centroid_y = flScalar(0);
flScalar sum_area = flScalar(0.0);
flScalar sum_a_x = flScalar(0.0);
flScalar sum_a_y = flScalar(0.0);
flScalar tmp_area = flScalar(0.0);
flScalar range = term->maximum() - term->minimum();
flScalar step_size = range / samples;
int pi = 0;
flScalar x[3];
flScalar y[3];
/*******
* first triangle should include (minimum, 0)
* fix requires y_is_0 to start false & pi to start at 1
* updated by rctaylor 02/08/11
********/
bool y_is_0 = false;
x[0] = term->minimum();
y[0] = term->membership(x[0]);
x[1] = term->minimum();
y[1] = 0;
pi = 1;
// end update 02/08/11
int i = 1;
//Triangulation:
// rctaylor 02/08/11 - updated to <= because that is the only way x will ever equal
// term->maximum (ie. term->maximum = term->minimum + samples * step_size)
while (pi <= samples) {
++i;
if (y_is_0) {
x[i % 3] = x[(i - 1) % 3];
y[i % 3] = 0;
++pi; // rctaylor 02/08/11 - since y_is_0 starts false, this moves here
} else {
x[i % 3] = term->minimum() + pi * step_size;
y[i % 3] = term->membership(x[i % 3]);
}
y_is_0 = !y_is_0;
//Area of triangle:
// |Ax(By - Cy) + Bx(Cy - Ay) + Cx(Ay - By)| / 2
// |x0(y1 - y2) + x1(y2 - y0) + x2(y0 - y1)| / 2
tmp_area = FuzzyOperation::Absolute(x[0] * (y[1] - y[2]) + x[1]
* (y[2] - y[0]) + x[2] * (y[0] - y[1])) / 2;
//Centroid of a triangle:
// x = (x0 + x1 + x2)/3; y = (y0 + y1 + y2)/3;
sum_a_x += tmp_area * (x[0] + x[1] + x[2]) / 3;
sum_a_y += tmp_area * (y[0] + y[1] + y[2]) / 3;
sum_area += tmp_area;
}
centroid_x = sum_a_x / sum_area;
centroid_y = sum_a_y / sum_area;
return sum_area;
}
std::string TrapezoidalAlgorithm::name() const {
return "Trapezoidal";
}
flScalar TrapezoidalAlgorithm::area(const LinguisticTerm* term, int samples) const {
flScalar sum_area = 0.0;
flScalar step_size = (term->maximum() - term->minimum()) / samples;
flScalar step = term->minimum();
flScalar mu, prev_mu = term->membership(step);
for (int i = 0; i < samples; ++i) {
step += step_size;
mu = term->membership(step);
sum_area += step_size * (mu + prev_mu);
prev_mu = mu;
}
sum_area *= 0.5;
return sum_area;
}
void TrapezoidalAlgorithm::centroid(const LinguisticTerm* term,
flScalar& centroid_x, flScalar& centroid_y, int samples) const {
areaAndCentroid(term, centroid_x, centroid_y, samples);
}
flScalar TrapezoidalAlgorithm::areaAndCentroid(const LinguisticTerm* term,
flScalar& centroid_x, flScalar& centroid_y, int samples) const {
flScalar sum_area = 0.0;
flScalar step_size = (term->maximum() - term->minimum()) / samples;
flScalar step = term->minimum();
flScalar mu, prev_mu = term->membership(step);
flScalar area, x, y;
centroid_x = 0.0;
centroid_y = 0.0;
/*
* centroid_x = a (h_1 + 2h_2)/3(h_1+h_2) ; h_1 = prev_mu; h_2 = mu
* centroid_y = (h_1^2/(h_1+h_2) + h_2) * 1/3
*/
for (int i = 0; i <= samples ; ++i) {
step += step_size;
mu = term->membership(step);
area = 0.5 * step_size * (prev_mu + mu);
sum_area += area;
x = ((step_size * (prev_mu + 2 * mu)) / (3.0 * (prev_mu + mu)))
+ (step - step_size);
y = ((prev_mu * prev_mu) / (prev_mu + mu) + mu) / 3.0;
centroid_x += area * x;
centroid_y += area * y;
prev_mu = mu;
}
centroid_x /= sum_area;
centroid_y /= sum_area;
return sum_area;
}
}

View File

@ -0,0 +1,75 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: AreaCentroidAlgorithm.h
* Author: jcrada
*
* Created on April 6, 2010, 5:33 PM
*/
#ifndef FL_AREACENTROIDALGORITHM_H
#define FL_AREACENTROIDALGORITHM_H
#include "flScalar.h"
#include <string>
namespace fl {
class LinguisticTerm;
class AreaCentroidAlgorithm {
public:
virtual ~AreaCentroidAlgorithm(){}
virtual std::string name() const = 0;
virtual flScalar area(const LinguisticTerm* term, int samples) const = 0;
virtual void centroid(const LinguisticTerm* term, flScalar& centroid_x, flScalar& centroid_y,
int samples) const = 0;
virtual flScalar areaAndCentroid(const LinguisticTerm* term, flScalar& centroid_x,
flScalar& centroid_y, int samples) const = 0;
};
class TriangulationAlgorithm : public AreaCentroidAlgorithm {
public:
virtual std::string name() const;
virtual flScalar area(const LinguisticTerm* term, int samples) const;
virtual void centroid(const LinguisticTerm* term, flScalar& centroid_x, flScalar& centroid_y,
int samples) const;
virtual flScalar areaAndCentroid(const LinguisticTerm* term, flScalar& centroid_x,
flScalar& centroid_y, int samples) const;
};
class TrapezoidalAlgorithm : public AreaCentroidAlgorithm {
//Feature suggested by William Roeder
public:
virtual std::string name() const;
virtual flScalar area(const LinguisticTerm* term, int samples) const;
virtual void centroid(const LinguisticTerm* term, flScalar& centroid_x, flScalar& centroid_y,
int samples) const;
virtual flScalar areaAndCentroid(const LinguisticTerm* term, flScalar& centroid_x,
flScalar& centroid_y, int samples) const;
};
}
#endif /* FL_AREACENTROIDALGORITHM_H */

View File

@ -0,0 +1,112 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* CompoundTerm.cpp
*
* Created on: Dec 13, 2009
* Author: jcrada
*/
#include "CompoundTerm.h"
namespace fl {
CompoundTerm::CompoundTerm() :
LinguisticTerm() {
}
CompoundTerm::CompoundTerm(const std::string& name, flScalar minimum,
flScalar maximum) :
LinguisticTerm(name, minimum, maximum) {
}
CompoundTerm::CompoundTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
flScalar minimum, flScalar maximum) :
LinguisticTerm(fuzzy_op, name, minimum, maximum) {
}
CompoundTerm::~CompoundTerm() {
clear();
}
void CompoundTerm::addTerm(const LinguisticTerm& term) {
_terms.push_back(term.clone());
if (term.minimum() < minimum() || isinf(minimum())) {
setMinimum(term.minimum());
}
if (term.maximum() > maximum() || isinf(maximum())) {
setMaximum(term.maximum());
}
}
const LinguisticTerm& CompoundTerm::term(int index) const {
return *this->_terms[index];
}
void CompoundTerm::removeTerm(int index){
LinguisticTerm* t = this->_terms[index];
this->_terms.erase(this->_terms.begin() + index);
delete t;
}
int CompoundTerm::numberOfTerms() const{
return this->_terms.size();
}
void CompoundTerm::clear() {
for (size_t i = 0; i < _terms.size(); ++i) {
delete _terms[i];
}
_terms.clear();
setMinimum(-INFINITY);
setMaximum(INFINITY);
}
CompoundTerm* CompoundTerm::clone() const {
CompoundTerm* result = new CompoundTerm;
for (int i = 0 ; i < numberOfTerms(); ++i){
result->addTerm(term(i));
}
return result;
}
flScalar CompoundTerm::membership(flScalar crisp) const {
flScalar max = flScalar(0);
for (size_t i = 0; i < _terms.size(); ++i) {
max = fuzzyOperator().aggregation().execute(max, _terms[i]->membership(crisp));
}
return fuzzyOperator().modulation().execute(modulation(), max);
}
LinguisticTerm::eMembershipFunction CompoundTerm::type() const {
return MF_COMPOUND;
}
std::string CompoundTerm::toString() const {
std::stringstream ss;
ss << LinguisticTerm::toString();
ss << "Compound (";
for (size_t i = 0; i < _terms.size(); ++i) {
ss << _terms[i]->toString();
if (i < _terms.size() -1 ) ss << " + ";
}
ss << ")";
return ss.str();
}
} // namespace fuzzy_lite

View File

@ -0,0 +1,59 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* CompoundTerm.h
*
* Created on: Dec 13, 2009
* Author: jcrada
*/
#ifndef FL_COMPOUNDTERM_H_
#define FL_COMPOUNDTERM_H_
#include "LinguisticTerm.h"
#include <vector>
namespace fl {
class CompoundTerm : public LinguisticTerm {
private:
std::vector<LinguisticTerm*> _terms;
public:
CompoundTerm();
CompoundTerm(const std::string& name, flScalar minimum = -INFINITY,
flScalar maximum = INFINITY);
CompoundTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
flScalar minimum = -INFINITY, flScalar maximum = INFINITY);
virtual ~CompoundTerm();
virtual void addTerm(const LinguisticTerm& term);
virtual const LinguisticTerm& term(int index) const;
virtual void removeTerm(int index);
virtual int numberOfTerms() const;
virtual void clear();
virtual CompoundTerm* clone() const;
virtual flScalar membership(flScalar crisp) const;
virtual eMembershipFunction type() const;
virtual std::string toString() const;
};
} // namespace fuzzy_lite
#endif /* FL_COMPOUNDTERM_H_ */

View File

@ -0,0 +1,296 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "DescriptiveAntecedent.h"
#include "StrOp.h"
#include <stack>
#include "FuzzyRule.h"
namespace fl {
DescriptiveAntecedent::DescriptiveAntecedent() : FuzzyAntecedent(),
_left(NULL), _right(NULL), _operation(O_NONE), _term(NULL) {
}
DescriptiveAntecedent::DescriptiveAntecedent(const FuzzyOperator& fuzzy_op) :
FuzzyAntecedent(fuzzy_op), _left(NULL), _right(NULL), _operation(O_NONE),
_term(NULL) {
}
DescriptiveAntecedent::~DescriptiveAntecedent() {
if (_left) {
delete _left;
}
if (_right) {
delete _right;
}
}
void DescriptiveAntecedent::setLeft(DescriptiveAntecedent* l_antecedent) {
this->_left = l_antecedent;
}
DescriptiveAntecedent* DescriptiveAntecedent::left() const {
return this->_left;
}
void DescriptiveAntecedent::setRight(DescriptiveAntecedent* r_antecedent) {
this->_right = r_antecedent;
}
DescriptiveAntecedent* DescriptiveAntecedent::right() const {
return this->_right;
}
void DescriptiveAntecedent::setOperation(OPERATION operation) {
this->_operation = operation;
}
DescriptiveAntecedent::OPERATION DescriptiveAntecedent::operation() const {
return this->_operation;
}
void DescriptiveAntecedent::addHedge(Hedge* hedge) {
this->_hedges.push_back(hedge);
}
int DescriptiveAntecedent::numberOfHedges() const {
return this->_hedges.size();
}
Hedge* DescriptiveAntecedent::hedge(int index) const {
return this->_hedges[index];
}
void DescriptiveAntecedent::setTerm(const LinguisticTerm* term) {
this->_term = term;
}
const LinguisticTerm* DescriptiveAntecedent::term() const {
return this->_term;
}
bool DescriptiveAntecedent::isTerminal() const {
return operation() == O_NONE;
}
flScalar DescriptiveAntecedent::degreeOfTruth() const {
if (!isTerminal()) {
if (left() == NULL || right() == NULL) {
throw NullPointerException(FL_AT, toString());
}
switch (operation()) {
case O_AND:
return fuzzyOperator().tnorm().execute(left()->degreeOfTruth(),
right()->degreeOfTruth());
case O_OR:
return fuzzyOperator().snorm().execute(left()->degreeOfTruth(),
right()->degreeOfTruth());
default:
throw InvalidArgumentException(FL_AT, "Operation " + StrOp::IntToString(operation()) + " not available");
}
}
flScalar result = term()->membership(inputLVar()->input());
for (int i = 0; i < numberOfHedges(); ++i) {
result = hedge(i)->hedge(result);
}
return result;
}
std::string DescriptiveAntecedent::toString() const {
std::stringstream ss;
if (isTerminal()) {
ss << inputLVar()->name() + " " + FuzzyRule::FR_IS + " ";
for (int i = 0; i < numberOfHedges(); ++i) {
ss << hedge(i)->name() << " ";
}
ss << term()->name();
} else {
ss << " ( " + (left() ? left()->toString() : "NULL");
ss << " " + (operation() == O_AND ? FuzzyRule::FR_AND : FuzzyRule::FR_OR);
ss << " " + (right() ? right()->toString() : "NULL") + " ) ";
}
return ss.str();
}
void DescriptiveAntecedent::parse(const std::string& antecedent,
const FuzzyEngine& engine) throw (ParsingException) {
enum e_state {
//e.g. Posfix antecedent: Energy is LOW Distance is FAR_AWAY and
S_LVAR = 1, S_IS, S_HEDGE, S_TERM, S_OPERATOR
};
e_state current_state = S_LVAR;
std::string postfix_antecedent = InfixToPostfix(antecedent);
std::stringstream ss(postfix_antecedent);
std::string token;
InputLVar* input = NULL;
std::vector<Hedge*> hedges;
Hedge* hedge = NULL;
LinguisticTerm* term = NULL;
std::stack<DescriptiveAntecedent*> f_antecedents;
DescriptiveAntecedent* tmp_antecedent = NULL;
// <editor-fold desc="State Machine">
while (ss >> token) {
switch (current_state) {
//e.g.Postfix: Energy is LOW Distance is FAR_AWAY and. After term follows Operator or LVar
case S_LVAR:
case S_OPERATOR:
input = engine.inputLVar(token);
if (input) {
current_state = S_IS;
break;
}
if (token != FuzzyRule::FR_AND && token != FuzzyRule::FR_OR) {
//if it is not and InputLVar and not an Operator then exception
throw ParsingException(FL_AT, "Input variable <" +
token + "> not registered in fuzzy engine");
// throw RuleParsingException(FL_AT,
// "Operator expected but found <" + token +
// ">. Antecedent: " + antecedent);
}
//A is a B is b and
if (isTerminal()) {
setLeft(f_antecedents.top());
f_antecedents.pop();
setRight(f_antecedents.top());
f_antecedents.pop();
setOperation(token == FuzzyRule::FR_AND ? DescriptiveAntecedent::O_AND :
DescriptiveAntecedent::O_OR); //I am not terminal anymore
} else {
setLeft(new DescriptiveAntecedent(*this));
setRight(f_antecedents.top());
f_antecedents.pop();
setOperation(token == FuzzyRule::FR_AND ? DescriptiveAntecedent::O_AND :
DescriptiveAntecedent::O_OR); //I am not terminal anymore
}
break;
case S_IS:
if (token == FuzzyRule::FR_IS) {
current_state = S_HEDGE;
} else {
throw ParsingException(FL_AT, "<is> expected but found <" +
token + ">");
}
break;
case S_HEDGE:
hedge = engine.hedgeSet().get(token);
if (hedge) {
hedges.push_back(hedge); //And check for more hedges
break;
}
//intentional fall-through in case there are no hedges
case S_TERM:
term = input->term(token);
if (!term) {
throw ParsingException(FL_AT, "Term <" + token +
"> not found in input variable <" + input->name() +
">");
}
current_state = S_OPERATOR;
tmp_antecedent = new DescriptiveAntecedent(engine.fuzzyOperator());
tmp_antecedent->setInputLVar(input);
tmp_antecedent->setTerm(term);
for (size_t i = 0; i < hedges.size(); ++i) {
tmp_antecedent->addHedge(hedges[i]);
}
f_antecedents.push(tmp_antecedent);
tmp_antecedent = NULL;
hedges.clear();
break;
}
}
//</editor-fold>
if (!f_antecedents.empty()) { //e.g. Rule: if A is a then X is x (one antecedent only)
FL_ASSERT(f_antecedents.size() == 1);
DescriptiveAntecedent* me = f_antecedents.top();
setInputLVar(me->inputLVar());
for (int i = 0; i < me->numberOfHedges(); ++i) {
addHedge(me->hedge(i));
}
setTerm(me->term());
delete me;
}
}
std::string DescriptiveAntecedent::Preprocess(const std::string& infix) {
std::string result;
for (size_t i = 0; i < infix.size(); ++i) {
if (infix[i] == '(') {
result += " ( ";
} else if (infix[i] == ')') {
result += " ) ";
} else {
result += infix[i];
}
}
return result;
}
std::string DescriptiveAntecedent::InfixToPostfix(const std::string& infix) {
std::string p_infix = Preprocess(infix);
std::stringstream ss(p_infix);
std::string token;
std::string tmp;
std::string result;
std::stack<std::string> stack;
while (ss >> token) {
if (token == "(") {
stack.push(token);
} else if (token == ")") {
FL_ASSERT(!stack.empty());
tmp = stack.top();
stack.pop();
while (tmp != "(") {
result += tmp + " ";
FL_ASSERT(!stack.empty());
tmp = stack.top();
stack.pop();
}
} else if (token == FuzzyRule::FR_AND || token == FuzzyRule::FR_OR) {
if (stack.empty()) {
stack.push(token);
} else {
FL_ASSERT(!stack.empty())
tmp = stack.top();
stack.pop();
while (tmp != FuzzyRule::FR_AND && tmp != FuzzyRule::FR_OR && tmp != "(") {
result += tmp + " ";
FL_ASSERT(!stack.empty())
tmp = stack.top();
stack.pop();
}
stack.push(tmp);
stack.push(token);
}
} else {
result += token + " ";
}
}
while (!stack.empty()) {
FL_ASSERT(!stack.empty())
token = stack.top();
stack.pop();
result += token + " ";
}
return result;
}
}

View File

@ -0,0 +1,88 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: DescriptiveAntecedent.h
* Author: jcrada
*
* Created on March 3, 2010, 12:32 AM
*/
#ifndef FL_DESCRIPTIVEANTECEDENT_H
#define FL_DESCRIPTIVEANTECEDENT_H
#include "FuzzyAntecedent.h"
#include "FuzzyOperator.h"
#include "InputLVar.h"
#include "Hedge.h"
#include "LinguisticTerm.h"
#include <vector>
#include <string>
#include "FuzzyEngine.h"
#include "FuzzyExceptions.h"
namespace fl {
class DescriptiveAntecedent : public FuzzyAntecedent {
public:
enum OPERATION {
O_NONE = ' ', O_AND = '&', O_OR = '*',
};
private:
DescriptiveAntecedent* _left;
DescriptiveAntecedent* _right;
OPERATION _operation;
std::vector<Hedge*> _hedges; //very
const LinguisticTerm* _term; //high
public:
DescriptiveAntecedent();
DescriptiveAntecedent(const FuzzyOperator& fuzzy_op);
virtual ~DescriptiveAntecedent();
virtual flScalar degreeOfTruth() const;
virtual std::string toString() const;
virtual void parse(const std::string& antecedent,
const FuzzyEngine& engine) throw (ParsingException);
virtual void setLeft(DescriptiveAntecedent* l_antecedent);
virtual DescriptiveAntecedent* left() const;
virtual void setRight(DescriptiveAntecedent* r_antecedent);
virtual DescriptiveAntecedent* right() const;
virtual void setOperation(OPERATION operation);
virtual OPERATION operation() const;
virtual void addHedge(Hedge* hedge);
virtual int numberOfHedges() const;
virtual Hedge* hedge(int index) const;
virtual void setTerm(const LinguisticTerm* term);
virtual const LinguisticTerm* term() const;
virtual bool isTerminal() const;
// static bool IsValid(const std::string& rule, const FuzzyEngine& engine);
std::string Preprocess(const std::string& infix);
std::string InfixToPostfix(const std::string& infix);
};
}
#endif /* FL_DESCRIPTIVEANTECEDENT_H */

View File

@ -0,0 +1,120 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "DiscreteTerm.h"
namespace fl {
DiscreteTerm::DiscreteTerm() : LinguisticTerm() {
}
DiscreteTerm::DiscreteTerm(const std::string& name, const std::vector<flScalar>& x,
const std::vector<flScalar>& y)
: LinguisticTerm(name) {
setXY(x, y);
}
DiscreteTerm::DiscreteTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
const std::vector<flScalar>& x, const std::vector<flScalar>& y)
: LinguisticTerm(fuzzy_op, name) {
setXY(x, y);
}
DiscreteTerm::~DiscreteTerm() {
}
void DiscreteTerm::setXY(const std::vector<flScalar>& x, const std::vector<flScalar>& y) {
this->_x = x;
this->_y = y;
}
void DiscreteTerm::setXY(int index, flScalar x, flScalar y) {
this->_x.insert(this->_x.begin() + index, x);
this->_y.insert(this->_y.begin() + index, y);
}
void DiscreteTerm::addXY(flScalar x, flScalar y) {
this->_x.push_back(x);
this->_y.push_back(y);
}
void DiscreteTerm::remove(int index) {
this->_x.erase(this->_x.begin() + index);
this->_y.erase(this->_y.begin() + index);
}
void DiscreteTerm::clear() {
this->_x.clear();
this->_y.clear();
}
int DiscreteTerm::numberOfCoords() const {
return (int) this->_x.size();
}
flScalar DiscreteTerm::minimum() const {
flScalar result = INFINITY;
for (int i = 0; i < numberOfCoords(); ++i) {
if (_x[i] < result) {
result = _x[i];
}
}
return isinf(result) ? NAN : result;
}
flScalar DiscreteTerm::maximum() const {
flScalar result = -INFINITY;
for (int i = 0; i < numberOfCoords(); ++i) {
if (_x[i] > result) {
result = _x[i];
}
}
return isinf(result) ? NAN : result;
}
DiscreteTerm* DiscreteTerm::clone() const {
return new DiscreteTerm(*this);
}
flScalar DiscreteTerm::membership(flScalar crisp) const {
flScalar closer = INFINITY;
flScalar result = NAN;
for (int i = 0; i < numberOfCoords(); ++i) {
if (fabs(crisp - _x[i]) < closer) {
closer = fabs(crisp - _x[i]);
result = _y[i];
}
}
return result;
}
LinguisticTerm::eMembershipFunction DiscreteTerm::type() const {
return LinguisticTerm::MF_DISCRETE;
}
std::string DiscreteTerm::toString() const {
std::stringstream ss;
ss << LinguisticTerm::toString();
ss << "Discrete (";
for (int i = 0; i < numberOfCoords(); ++i) {
ss << "{" << _x[i] << "," << _y[i] << "}";
if (i < numberOfCoords() - 1) {
ss << " ";
}
}
ss << ")";
return ss.str();
}
}

View File

@ -0,0 +1,50 @@
/*
* File: DiscreteTerm.h
* Author: jcrada
*
* Created on May 9, 2010, 8:17 PM
*/
#ifndef FL_DISCRETETERM_H
#define FL_DISCRETETERM_H
#include "LinguisticTerm.h"
namespace fl {
class DiscreteTerm : public LinguisticTerm {
private:
std::vector<flScalar> _x;
std::vector<flScalar> _y;
public:
DiscreteTerm();
DiscreteTerm(const std::string& name, const std::vector<flScalar>& x = std::vector<flScalar>(),
const std::vector<flScalar>& y = std::vector<flScalar>());
DiscreteTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
const std::vector<flScalar>& x = std::vector<flScalar>(),
const std::vector<flScalar>& y = std::vector<flScalar>());
virtual ~DiscreteTerm();
virtual void setXY(int index, flScalar x, flScalar y);
virtual void setXY(const std::vector<flScalar>&x, const std::vector<flScalar>&y);
virtual void addXY(flScalar x, flScalar y);
virtual void remove(int index);
virtual void clear();
virtual int numberOfCoords() const;
virtual flScalar minimum() const;
virtual flScalar maximum() const;
virtual DiscreteTerm* clone() const;
virtual flScalar membership(flScalar crisp) const;
virtual eMembershipFunction type() const;
virtual std::string toString() const;
};
}
#endif /* FL_DISCRETETERM_H */

View File

@ -0,0 +1,94 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "FunctionTerm.h"
namespace fl {
FunctionTerm::FunctionTerm() : LinguisticTerm() {
_ip.loadMathOperators();
}
FunctionTerm::FunctionTerm(const std::string& name, const std::string& f_infix,
flScalar minimum, flScalar maximum)
: LinguisticTerm(name, minimum, maximum) {
_ip.loadMathOperators();
setInfixFunction(f_infix);
}
FunctionTerm::FunctionTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
const std::string& f_infix, flScalar minimum, flScalar maximum)
: LinguisticTerm(fuzzy_op, name, minimum, maximum) {
_ip.loadMathOperators();
setInfixFunction(f_infix);
}
FunctionTerm::~FunctionTerm() {
}
void FunctionTerm::setInfixFunction(const std::string& infix) {
this->_infix_function = infix;
setPostfixFunction(_ip.transform(infix));
}
std::string FunctionTerm::infixFunction() const {
return this->_infix_function;
}
void FunctionTerm::setPostfixFunction(const std::string& postfix) {
this->_postfix_function = postfix;
}
std::string FunctionTerm::postfixFunction() const {
return this->_postfix_function;
}
bool FunctionTerm::isValid() const {
std::map<std::string, flScalar> x;
x["x"] = 0;
x["min"] = minimum();
x["max"] = maximum();
try {
_ip.evaluate(postfixFunction(), &x);
return true;
} catch (std::exception ex) {
return false;
}
}
flScalar FunctionTerm::membership(flScalar crisp) const {
std::map<std::string, flScalar> m;
m["x"] = crisp;
m["min"] = minimum();
m["max"] = maximum();
return _ip.evaluate(postfixFunction(), &m);
}
FunctionTerm* FunctionTerm::clone() const {
return new FunctionTerm(*this);
}
LinguisticTerm::eMembershipFunction FunctionTerm::type() const {
return MF_FUNCTION;
}
std::string FunctionTerm::toString() const {
std::stringstream ss;
ss << LinguisticTerm::toString();
ss << "Function f = " << postfixFunction() << " | x=[" << minimum() << " " << maximum() << "]";
return ss.str();
}
}

View File

@ -0,0 +1,60 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: FunctionTerm.h
* Author: jcrada
*
* Created on March 10, 2010, 6:16 PM
*/
#ifndef FL_FUNCTIONTERM_H
#define FL_FUNCTIONTERM_H
#include "LinguisticTerm.h"
#include "InfixToPostfix.h"
namespace fl {
class FunctionTerm : public LinguisticTerm {
private:
InfixToPostfix _ip;
std::string _postfix_function;
std::string _infix_function;
public:
FunctionTerm();
FunctionTerm(const std::string& name, const std::string& f_infix, flScalar minimum = -INFINITY,
flScalar maximum = INFINITY);
FunctionTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
const std::string& f_infix, flScalar minimum = -INFINITY,
flScalar maximum = INFINITY);
virtual ~FunctionTerm();
virtual void setInfixFunction(const std::string& infix);
virtual std::string infixFunction() const;
virtual void setPostfixFunction(const std::string& postfix);
virtual std::string postfixFunction() const;
virtual bool isValid() const;
virtual FunctionTerm* clone() const;
virtual flScalar membership(flScalar crisp) const;
virtual eMembershipFunction type() const;
virtual std::string toString() const;
};
}
#endif /* FL_FUNCTIONTERM_H */

44
AI/FuzzyLite/FuzzyAnd.cpp Normal file
View File

@ -0,0 +1,44 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "FuzzyAnd.h"
namespace fl {
std::string FuzzyAndMin::name() const {
return "Min";
}
flScalar FuzzyAndMin::execute(flScalar mu1, flScalar mu2) const {
return FuzzyOperation::Min(mu1, mu2);
}
std::string FuzzyAndProd::name() const {
return "Prod";
}
flScalar FuzzyAndProd::execute(flScalar mu1, flScalar mu2) const {
return FuzzyOperation::AlgebraicProduct(mu1, mu2);
}
std::string FuzzyAndBDiff::name() const {
return "BDiff";
}
flScalar FuzzyAndBDiff::execute(flScalar mu1, flScalar mu2) const {
return FuzzyOperation::BoundedDiff(mu1, mu2);
}
}

49
AI/FuzzyLite/FuzzyAnd.h Normal file
View File

@ -0,0 +1,49 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: FuzzyAnd.h
* Author: jcrada
*
* Created on April 6, 2010, 5:11 PM
*/
#ifndef FL_FUZZYAND_H
#define FL_FUZZYAND_H
#include "FuzzyOperation.h"
namespace fl {
class FuzzyAndMin : public FuzzyOperation {
public:
virtual std::string name() const;
virtual flScalar execute(flScalar mu1, flScalar mu2) const;
};
class FuzzyAndProd : public FuzzyOperation {
public:
virtual std::string name() const;
virtual flScalar execute(flScalar mu1, flScalar mu2) const;
};
class FuzzyAndBDiff : public FuzzyOperation {
public:
virtual std::string name() const;
virtual flScalar execute(flScalar mu1, flScalar mu2) const;
};
}
#endif /* FL_FUZZYAND_H */

View File

@ -0,0 +1,52 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "FuzzyAntecedent.h"
namespace fl {
FuzzyAntecedent::FuzzyAntecedent() : _input_lvar(NULL) {
setFuzzyOperator(FuzzyOperator::DefaultFuzzyOperator());
}
FuzzyAntecedent::FuzzyAntecedent(const FuzzyOperator& fuzzy_op)
: _fuzzy_operator(&fuzzy_op), _input_lvar(NULL) {
}
FuzzyAntecedent::~FuzzyAntecedent() {
}
void FuzzyAntecedent::setFuzzyOperator(const FuzzyOperator& fuzzy_op) {
this->_fuzzy_operator = &fuzzy_op;
}
const FuzzyOperator& FuzzyAntecedent::fuzzyOperator() const {
return *this->_fuzzy_operator;
}
void FuzzyAntecedent::setInputLVar(const InputLVar* input_lvar) {
this->_input_lvar = input_lvar;
}
const InputLVar* FuzzyAntecedent::inputLVar() const {
return this->_input_lvar;
}
}

View File

@ -0,0 +1,57 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: FuzzyAntecedent.h
* Author: jcrada
*
* Created on March 3, 2010, 12:28 AM
*/
#ifndef FL_FUZZYANTECEDENT_H
#define FL_FUZZYANTECEDENT_H
#include "flScalar.h"
#include <string>
#include "FuzzyExceptions.h"
#include "FuzzyOperator.h"
#include "InputLVar.h"
#include "FuzzyEngine.h"
namespace fl {
class FuzzyAntecedent {
private:
const FuzzyOperator* _fuzzy_operator;
const InputLVar* _input_lvar; //e.g. power
public:
FuzzyAntecedent();
FuzzyAntecedent(const FuzzyOperator& fuzzy_op);
virtual ~FuzzyAntecedent();
virtual void setFuzzyOperator(const FuzzyOperator& fuzzy_op);
virtual const FuzzyOperator& fuzzyOperator() const;
virtual void setInputLVar(const InputLVar* input_lvar);
virtual const InputLVar* inputLVar() const;
virtual flScalar degreeOfTruth() const = 0;
virtual std::string toString() const = 0;
virtual void parse(const std::string& antecedent,
const FuzzyEngine& engine) throw (ParsingException) = 0;
};
}
#endif /* FL_FUZZYANTECEDENT_H */

View File

@ -0,0 +1,46 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "FuzzyConsequent.h"
namespace fl {
FuzzyConsequent::FuzzyConsequent() : _output_lvar(NULL), _weight(1.0) {
}
FuzzyConsequent::~FuzzyConsequent() {
}
void FuzzyConsequent::setOutputLVar(OutputLVar* output_lvar) {
this->_output_lvar = output_lvar;
}
OutputLVar* FuzzyConsequent::outputLVar() const {
return this->_output_lvar;
}
void FuzzyConsequent::setWeight(flScalar weight) {
this->_weight = weight;
}
flScalar FuzzyConsequent::weight() const {
return this->_weight;
}
}

View File

@ -0,0 +1,60 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: FuzzyConsequent.h
* Author: jcrada
*
* Created on March 2, 2010, 7:05 PM
*/
#ifndef FL_FUZZYCONSEQUENT_H
#define FL_FUZZYCONSEQUENT_H
#include "OutputLVar.h"
#include <string>
#include "FuzzyExceptions.h"
#include "FuzzyEngine.h"
namespace fl {
class FuzzyConsequent {
private:
OutputLVar* _output_lvar;
flScalar _weight;
public:
FuzzyConsequent();
virtual ~FuzzyConsequent();
virtual void setOutputLVar(OutputLVar* output_lvar);
virtual OutputLVar* outputLVar() const;
virtual void setWeight(flScalar weight);
virtual flScalar weight() const;
virtual void parse(const std::string& consequent,
const FuzzyEngine& engine) throw (ParsingException) = 0;
virtual void execute(flScalar degree) = 0;
virtual std::string toString() const = 0;
static void main(int argc, char** argv);
};
}
#endif /* FL_FUZZYCONSEQUENT_H */

View File

@ -0,0 +1,62 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "FuzzyDefuzzifier.h"
#include "CompoundTerm.h"
#include "TakagiSugenoTerm.h"
namespace fl {
FuzzyDefuzzifier::~FuzzyDefuzzifier() {
}
std::string CoGDefuzzifier::name() const {
return "CoG";
}
flScalar CoGDefuzzifier::defuzzify(const LinguisticTerm* term, int number_of_samples,
const AreaCentroidAlgorithm* algorithm) const {
flScalar x, y;
algorithm->centroid(term, x, y, number_of_samples);
return x;
}
std::string TakagiSugenoDefuzzifier::name() const {
return "TSK";
}
flScalar TakagiSugenoDefuzzifier::defuzzify(const LinguisticTerm* term, int number_of_samples,
const AreaCentroidAlgorithm* algorithm) const {
const CompoundTerm* out = dynamic_cast<const CompoundTerm*> (term);
if (!out) {
FL_LOG("<CompoundTerm> expected, but <" << term->toString() << "> found." <<
"Takagi-Sugeno defuzzification works only on the output of Takagi-Sugeno Rules." );
return -1;
}
flScalar result = 0;
flScalar sum_wi = 0;
for (int i = 0; i < out->numberOfTerms(); ++i) {
const TakagiSugenoTerm* t = dynamic_cast<const TakagiSugenoTerm*> (&out->term(i));
if (!t) {
FL_LOG("<TakagiSugenoTerm> expected, but <" << out->term(i).toString() << "> found." <<
"Takagi-Sugeno defuzzification works only on the output of Takagi-Sugeno Rules");
return -1;
}
result += t->value() * t->weight();
sum_wi += t->weight();
}
return result / sum_wi;
}
}

View File

@ -0,0 +1,57 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: FuzzyDefuzzifier.h
* Author: jcrada
*
* Created on April 6, 2010, 5:16 PM
*/
#ifndef FL_FUZZYDEFUZZIFIER_H
#define FL_FUZZYDEFUZZIFIER_H
#include "flScalar.h"
#include "AreaCentroidAlgorithm.h"
#include <string>
namespace fl {
class LinguisticTerm;
class FuzzyDefuzzifier {
public:
virtual ~FuzzyDefuzzifier();
virtual std::string name() const = 0;
virtual flScalar defuzzify(const LinguisticTerm* term, int number_of_samples,
const AreaCentroidAlgorithm* algorithm) const = 0;
};
class CoGDefuzzifier : public FuzzyDefuzzifier {
public:
virtual std::string name() const;
virtual flScalar defuzzify(const LinguisticTerm* term, int number_of_samples,
const AreaCentroidAlgorithm* algorithm) const;
};
class TakagiSugenoDefuzzifier : public FuzzyDefuzzifier {
public:
virtual std::string name() const;
virtual flScalar defuzzify(const LinguisticTerm* term, int number_of_samples,
const AreaCentroidAlgorithm* algorithm) const;
};
}
#endif /* FL_FUZZYDEFUZZIFIER_H */

View File

@ -0,0 +1,332 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "FuzzyEngine.h"
#include "MamdaniRule.h"
#include "FuzzyExceptions.h"
#include "defs.h"
#include "StrOp.h"
#include "TriangularTerm.h"
#include "ShoulderTerm.h"
#include <iosfwd>
#include "FuzzyException.h"
namespace fl {
FuzzyEngine::FuzzyEngine() : _name(""),
_fuzzy_op(&FuzzyOperator::DefaultFuzzyOperator()),
_hedge_set(new HedgeSet) {
}
FuzzyEngine::FuzzyEngine(const std::string& name) : _name(name),
_fuzzy_op(&FuzzyOperator::DefaultFuzzyOperator()),
_hedge_set(new HedgeSet) {
}
FuzzyEngine::FuzzyEngine(const std::string& name, FuzzyOperator& fuzzy_operator) : _name(name),
_fuzzy_op(&fuzzy_operator),
_hedge_set(new HedgeSet) {
}
FuzzyEngine::~FuzzyEngine() {
reset();
delete _hedge_set;
}
void FuzzyEngine::setName(const std::string& name) {
this->_name = name;
}
std::string FuzzyEngine::name() const {
return this->_name;
}
void FuzzyEngine::process(bool clear) {
if (clear) {
for (int i = 0; i < numberOfOutputLVars(); ++i) {
outputLVar(i)->output().clear();
}
}
for (int i = 0; i < numberOfRuleBlocks(); ++i) {
ruleBlock(i)->fireRules();
}
}
void FuzzyEngine::process(int ruleblock, bool clear) {
if (clear) {
for (int i = 0; i < numberOfOutputLVars(); ++i) {
outputLVar(i)->output().clear();
}
}
ruleBlock(ruleblock)->fireRules();
}
void FuzzyEngine::reset() {
for (int i = numberOfRuleBlocks() - 1; i >= 0; --i) {
delete removeRuleBlock(i);
}
for (int i = numberOfInputLVars() - 1; i >= 0; --i) {
delete removeInputLVar(i);
}
for (int i = numberOfOutputLVars() - 1; i >= 0; --i) {
delete removeOutputLVar(i);
}
for (int i = hedgeSet().numberOfHedges() - 1; i >= 0; --i) {
delete hedgeSet().remove(i);
}
}
void FuzzyEngine::addInputLVar(InputLVar* lvar) {
_input_lvars.push_back(lvar);
}
InputLVar* FuzzyEngine::inputLVar(int index) const {
return _input_lvars[index];
}
InputLVar* FuzzyEngine::inputLVar(const std::string& name) const {
for (int i = 0; i < numberOfInputLVars(); ++i) {
if (inputLVar(i)->name() == name) {
return inputLVar(i);
}
}
return NULL;
}
InputLVar* FuzzyEngine::removeInputLVar(int index) {
InputLVar* result = inputLVar(index);
_input_lvars.erase(_input_lvars.begin() + index);
return result;
}
InputLVar* FuzzyEngine::removeInputLVar(const std::string& name) {
int index = indexOfInputLVar(name);
return index == -1 ? NULL : removeInputLVar(index);
}
int FuzzyEngine::indexOfInputLVar(const std::string& name) const {
for (int i = 0; i < numberOfInputLVars(); ++i) {
if (inputLVar(i)->name() == name) {
return i;
}
}
return -1;
}
int FuzzyEngine::numberOfInputLVars() const {
return _input_lvars.size();
}
void FuzzyEngine::addOutputLVar(OutputLVar* lvar) {
_output_lvars.push_back(lvar);
}
OutputLVar* FuzzyEngine::outputLVar(int index) const {
return _output_lvars[index];
}
OutputLVar* FuzzyEngine::outputLVar(const std::string& name) const {
for (int i = 0; i < numberOfOutputLVars(); ++i) {
if (outputLVar(i)->name() == name) {
return outputLVar(i);
}
}
return NULL;
}
OutputLVar* FuzzyEngine::removeOutputLVar(int index) {
OutputLVar* result = outputLVar(index);
_output_lvars.erase(_output_lvars.begin() + index);
return result;
}
OutputLVar* FuzzyEngine::removeOutputLVar(const std::string& name) {
int index = indexOfOutputLVar(name);
return index == -1 ? NULL : removeOutputLVar(index);
}
int FuzzyEngine::indexOfOutputLVar(const std::string& name) const {
for (int i = 0; i < numberOfOutputLVars(); ++i) {
if (outputLVar(i)->name() == name) {
return i;
}
}
return -1;
}
int FuzzyEngine::numberOfOutputLVars() const {
return _output_lvars.size();
}
HedgeSet& FuzzyEngine::hedgeSet() const {
return *this->_hedge_set;
}
void FuzzyEngine::setFuzzyOperator(FuzzyOperator& fuzzy_operator) {
this->_fuzzy_op = &fuzzy_operator;
}
FL_INLINE FuzzyOperator& FuzzyEngine::fuzzyOperator() const {
return *this->_fuzzy_op;
}
//RULES
void FuzzyEngine::addRuleBlock(RuleBlock* ruleblock) {
this->_rule_blocks.push_back(ruleblock);
}
RuleBlock* FuzzyEngine::removeRuleBlock(int index) {
RuleBlock* result = ruleBlock(index);
this->_rule_blocks.erase(this->_rule_blocks.begin() + index);
return result;
}
RuleBlock* FuzzyEngine::ruleBlock(int index) const {
return this->_rule_blocks[index];
}
RuleBlock* FuzzyEngine::ruleBlock(const std::string& name) const {
for (int i = 0; i < numberOfRuleBlocks(); ++i) {
if (ruleBlock(i)->name() == name) {
return ruleBlock(i);
}
}
return NULL;
}
int FuzzyEngine::numberOfRuleBlocks() const {
return this->_rule_blocks.size();
}
FL_INLINE void FuzzyEngine::setInput(const std::string& input_lvar, flScalar value) {
InputLVar* input = inputLVar(input_lvar);
if (!input) {
throw InvalidArgumentException(FL_AT, "Input variable <" + input_lvar + "> not registered in fuzzy engine");
}
input->setInput(value);
}
FL_INLINE flScalar FuzzyEngine::output(const std::string& output_lvar) const {
OutputLVar* output = outputLVar(output_lvar);
if (!output) {
throw InvalidArgumentException(FL_AT, "Output variable <" + output_lvar + "> not registered in fuzzy engine");
}
return output->output().defuzzify();
}
std::string FuzzyEngine::fuzzyOutput(const std::string& output_lvar) const {
flScalar defuzzified = output(output_lvar);
OutputLVar* output = outputLVar(output_lvar);
if (!output) {
throw InvalidArgumentException(FL_AT, "Output variable <" + output_lvar + "> not registered in fuzzy engine");
}
return output->fuzzify(defuzzified);
}
// void FuzzyEngine::fromString(const std::string& fcl) {
//
// enum eState {
// WAITING = 0, VAR_INPUT, FUZZIFY, DEFUZZIFY, RULE_BLOCK,
// };
// eState state = WAITING;
// std::string line;
// std::string token;
// std::istringstream is(fcl);
// std::string current_name;
// while (!is.eof()) {
// std::getline(is, line);
// StrOp::FindReplace(line, "(", " ( ");
// StrOp::FindReplace(line, ")", " ) ");
// while (StrOp::FindReplace(line, " ", " ") > 0) {
// //do nothing;
// }
// std::vector<std::string> tokens = StrOp::Tokenize(line, " ");
// if (tokens.size() == 0) continue;
// InputLVar* input = NULL;
// OutputLVar* output = NULL;
// switch (state) {
// case WAITING:
// current_name = tokens.size() > 0 ? tokens[1] : "";
// if (tokens[0] == "FUNCTION_BLOCK") setName(current_name);
// else if (tokens[0] == "VAR_INPUT") state = VAR_INPUT;
// else if (tokens[0] == "FUZZIFY") state = FUZZIFY;
// else if (tokens[0] == "DEFUZZIFY") state = DEFUZZIFY;
// else if (tokens[0] == "RULEBLOCK") state = RULE_BLOCK;
// break;
// case VAR_INPUT:
// if (tokens[0] == "END_VAR") state = WAITING;
// else addInputLVar(new InputLVar(tokens[0]));
// break;
// case FUZZIFY:
// if (tokens[0] == "TERM") {
// input = inputLVar(current_name);
// ParsingException::Assert(FL_AT, input, "Input <" << current_name << "> not registered");
//
// } else if (tokens[0] == "END_FUZZIFY") state = WAITING;
// break;
// case DEFUZZIFY:
// case RULE_BLOCK:
// }
// }
// }
std::string FuzzyEngine::toString() const {
std::stringstream ss;
ss << "FUNCTION_BLOCK " << name() << "\n\n";
ss << "VAR_INPUT\n";
for (int i = 0; i < numberOfInputLVars(); ++i) {
ss << inputLVar(i)->name() << ": REAL;\n";
}
ss << "END_VAR\n\n";
for (int i = 0; i < numberOfInputLVars(); ++i) {
ss << "FUZZIFY " << inputLVar(i)->name() << "\n";
for (int j = 0; j < inputLVar(i)->numberOfTerms(); ++j) {
ss << inputLVar(i)->term(j)->toString() << ";\n";
}
ss << "END_FUZZIFY\n\n";
}
ss << "VAR_OUTPUT\n";
for (int i = 0; i < numberOfOutputLVars(); ++i) {
ss << outputLVar(i)->name() << ": REAL\n";
}
ss << "END_VAR\n\n";
for (int i = 0; i < numberOfOutputLVars(); ++i) {
ss << "DEFUZZIFY " << outputLVar(i)->name() << "\n";
for (int j = 0; j < outputLVar(i)->numberOfTerms(); ++j) {
ss << outputLVar(i)->term(j)->toString() << ";\n";
}
ss << "END_DEFUZZIFY\n\n";
}
for (int i = 0; i < numberOfRuleBlocks(); ++i) {
ss << ruleBlock(i)->toString() << "\n\n";
}
ss << "END_FUNCTION_BLOCK";
return ss.str();
}
}

View File

@ -0,0 +1,96 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: FuzzyEngine.h
* Author: jcrada
*
* Created on November 1, 2009, 4:51 PM
*/
#ifndef FL_FUZZYENGINE_H
#define FL_FUZZYENGINE_H
#include "FuzzyOperator.h"
#include "InputLVar.h"
#include "OutputLVar.h"
#include "Hedge.h"
#include "RuleBlock.h"
#include "HedgeSet.h"
namespace fl {
class FuzzyEngine {
private:
std::string _name;
FuzzyOperator* _fuzzy_op;
HedgeSet* _hedge_set;
std::vector<InputLVar*> _input_lvars;
std::vector<OutputLVar*> _output_lvars;
std::vector<RuleBlock*> _rule_blocks;
public:
FuzzyEngine();
FuzzyEngine(const std::string& name);
FuzzyEngine(const std::string& name, FuzzyOperator& fuzzy_operator);
virtual ~FuzzyEngine();
virtual void setName(const std::string& name);
virtual std::string name() const;
virtual void process(bool clear = true);
virtual void process(int ruleblock, bool clear = true);
virtual void reset();
virtual void addInputLVar(InputLVar* lvar);
virtual InputLVar* inputLVar(int index) const ;
virtual InputLVar* inputLVar(const std::string& name) const;
virtual InputLVar* removeInputLVar(int index) ;
virtual InputLVar* removeInputLVar(const std::string& name);
virtual int indexOfInputLVar(const std::string& name) const;
virtual int numberOfInputLVars() const;
virtual void addOutputLVar(OutputLVar* lvar);
virtual OutputLVar* outputLVar(int index) const ;
virtual OutputLVar* outputLVar(const std::string& name) const;
virtual OutputLVar* removeOutputLVar(int index) ;
virtual OutputLVar* removeOutputLVar(const std::string& name);
virtual int indexOfOutputLVar(const std::string& name) const;
virtual int numberOfOutputLVars() const;
virtual HedgeSet& hedgeSet() const;
virtual void addRuleBlock(RuleBlock* ruleblock);
virtual RuleBlock* removeRuleBlock(int index);
virtual RuleBlock* ruleBlock(int index) const;
virtual RuleBlock* ruleBlock(const std::string& name) const;
virtual int numberOfRuleBlocks() const;
virtual void setFuzzyOperator(FuzzyOperator& fuzzy_operator);
virtual FuzzyOperator& fuzzyOperator() const;
virtual void setInput(const std::string& input_lvar, flScalar value);
virtual flScalar output(const std::string& output_lvar) const;
virtual std::string fuzzyOutput(const std::string& output_lvar) const;
virtual std::string toString() const;
};
}
#endif /* FL_FUZZYENGINE_H */

View File

@ -0,0 +1,100 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <sstream>
#include "FuzzyException.h"
#include "defs.h"
namespace fl {
FuzzyException::FuzzyException(const std::string& file, int line,
const std::string& function) :
exception(), _message(""), _previous_exception(NULL) {
setLocation(file, line, function);
}
FuzzyException::FuzzyException(const std::string& file, int line,
const std::string& function, const std::string& message) :
exception(), _message(message), _previous_exception(NULL) {
setLocation(file, line, function);
}
FuzzyException::FuzzyException(const std::string& file, int line,
const std::string& function, const std::string& message,
const FuzzyException& previous_exception) :
exception(), _message(message), _previous_exception(&previous_exception) {
setLocation(file, line, function);
}
FuzzyException::~FuzzyException() throw () {
}
std::string FuzzyException::name() const throw () {
return "General Error";
}
std::string FuzzyException::message() const throw () {
return this->_message;
}
void FuzzyException::setMessage(const std::string& message) throw () {
this->_message = message;
}
std::string FuzzyException::location() const throw () {
return this->_location;
}
void FuzzyException::setLocation(const std::string& file, int line,
const std::string& function) throw () {
std::stringstream ss;
ss << file + "[" << line << "]::" + function + "()";
this->_location = ss.str();
}
const FuzzyException* FuzzyException::previousException() const throw () {
return this->_previous_exception;
}
void FuzzyException::setPreviousException(const FuzzyException& exception) throw () {
this->_previous_exception = &exception;
}
const char* FuzzyException::what() const throw () {
return toString().c_str();
}
std::string FuzzyException::toString() const throw () {
return name() + ": " + message() + "\n\tIN " + location();
}
std::string FuzzyException::stackTrace() const throw () {
std::string result;
const FuzzyException* stack = this;
do {
result += stack->toString() + "\n";
stack = stack->previousException();
} while (stack);
return result;
}
void FuzzyException::Assert(const std::string& file, int line,
const std::string& function, bool assert, const std::string message) {
if (!assert) {
throw FuzzyException(file, line, function, message);
}
}
}

View File

@ -0,0 +1,66 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: FuzzyException.h
* Author: jcrada
*
* Created on November 11, 2009, 7:15 AM
*/
#ifndef FL_FUZZYEXCEPTION_H
#define FL_FUZZYEXCEPTION_H
#include <string>
#include <exception>
namespace fl {
class FuzzyException : public std::exception {
private:
std::string _message;
std::string _location;
const FuzzyException* _previous_exception;
public:
FuzzyException(const std::string& file, int line, const std::string& function);
FuzzyException(const std::string& file, int line, const std::string& function,
const std::string& message);
FuzzyException(const std::string& file, int line, const std::string& function,
const std::string& message, const FuzzyException& previous_exception);
virtual ~FuzzyException() throw ();
virtual std::string name() const throw ();
virtual void setMessage(const std::string& message) throw ();
virtual std::string message() const throw ();
virtual void setLocation(const std::string& file, int line,
const std::string& function) throw ();
virtual std::string location() const throw ();
virtual void setPreviousException(const FuzzyException& exception) throw ();
virtual const FuzzyException* previousException() const throw ();
virtual const char* what() const throw ();
virtual std::string toString() const throw ();
virtual std::string stackTrace() const throw ();
static void Assert(const std::string& file, int line,
const std::string& function, bool assert, const std::string message = "");
};
}
#endif /* FL_FUZZYEXCEPTION_H */

View File

@ -0,0 +1,124 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "FuzzyExceptions.h"
namespace fl {
OutOfRangeException::OutOfRangeException(const std::string& file, int line,
const std::string& function, const std::string& message)
: FuzzyException(file, line, function, message) {
}
OutOfRangeException::OutOfRangeException(const std::string& file, int line,
const std::string& function, const std::string& message,
const FuzzyException& previous_exception)
: FuzzyException(file, line, function, message, previous_exception) {
}
OutOfRangeException::~OutOfRangeException() throw () {
}
std::string OutOfRangeException::name() const throw () {
return "Out Of Range";
}
void OutOfRangeException::CheckArray(const std::string& file, int line, const std::string& function,
int index, int max) {
if (index < 0 || index >= max) {
std::stringstream ss;
ss << "index=" << index << " and maximum value is " << max - 1;
throw OutOfRangeException(file, line, function, ss.str());
}
}
}
namespace fl {
InvalidArgumentException::InvalidArgumentException(const std::string& file,
int line, const std::string& function, const std::string& message)
: FuzzyException(file, line, function, message) {
}
InvalidArgumentException::InvalidArgumentException(const std::string& file,
int line, const std::string& function, const std::string& message,
const FuzzyException& previous_exception)
: FuzzyException(file, line, function, message, previous_exception) {
}
InvalidArgumentException::~InvalidArgumentException() throw () {
}
std::string InvalidArgumentException::name() const throw () {
return "Invalid Argument";
}
}
namespace fl {
NullPointerException::NullPointerException(const std::string& file, int line,
const std::string& function, const std::string& message)
: FuzzyException(file, line, function, message) {
}
NullPointerException::NullPointerException(const std::string& file, int line,
const std::string& function, const std::string& message,
const FuzzyException& previous_exception)
: FuzzyException(file, line, function, message, previous_exception) {
}
NullPointerException::~NullPointerException() throw () {
}
std::string NullPointerException::name() const throw () {
return "Null Pointer";
}
}
namespace fl {
ParsingException::ParsingException(const std::string& file, int line,
const std::string& function, const std::string& message)
: FuzzyException(file, line, function, message) {
}
ParsingException::ParsingException(const std::string& file, int line,
const std::string& function, const std::string& message,
const FuzzyException& previous_exception)
: FuzzyException(file, line, function, message, previous_exception) {
}
ParsingException::~ParsingException() throw () {
}
std::string ParsingException::name() const throw () {
return "Rule Error";
}
}

View File

@ -0,0 +1,79 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: FuzzyExceptions.h
* Author: jcrada
*
* Created on November 13, 2009, 3:34 PM
*/
#ifndef FL_FUZZYEXCEPTIONS_H
#define FL_FUZZYEXCEPTIONS_H
#include "FuzzyException.h"
#include <sstream>
namespace fl {
class OutOfRangeException : public FuzzyException {
public:
OutOfRangeException(const std::string& file, int line, const std::string& function,
const std::string& message);
OutOfRangeException(const std::string& file, int line, const std::string& function,
const std::string& message, const FuzzyException& previous_exception);
virtual ~OutOfRangeException() throw ();
virtual std::string name() const throw ();
static void CheckArray(const std::string& file, int line, const std::string& function,
int index, int max);
};
class InvalidArgumentException : public FuzzyException {
public:
InvalidArgumentException(const std::string& file, int line, const std::string& function,
const std::string& message);
InvalidArgumentException(const std::string& file, int line, const std::string& function,
const std::string& message, const FuzzyException& previous_exception);
virtual ~InvalidArgumentException() throw ();
virtual std::string name() const throw ();
};
class NullPointerException : public FuzzyException {
public:
NullPointerException(const std::string& file, int line, const std::string& function,
const std::string& message);
NullPointerException(const std::string& file, int line, const std::string& function,
const std::string& message, const FuzzyException& previous_exception);
virtual ~NullPointerException() throw ();
virtual std::string name() const throw ();
};
class ParsingException : public FuzzyException {
public:
ParsingException(const std::string& file, int line, const std::string& function,
const std::string& message);
ParsingException(const std::string& file, int line, const std::string& function,
const std::string& message, const FuzzyException& previous_exception);
virtual ~ParsingException() throw ();
virtual std::string name() const throw ();
};
}
#endif /* FL_FUZZYEXCEPTIONS_H */

65
AI/FuzzyLite/FuzzyLite.h Normal file
View File

@ -0,0 +1,65 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: FuzzyLite.h
* Author: jcrada
*
* Created on December 5, 2009, 9:54 PM
*/
#ifndef FL_FUZZYLITE_H
#define FL_FUZZYLITE_H
#include "AreaCentroidAlgorithm.h"
#include "CompoundTerm.h"
#include "DescriptiveAntecedent.h"
#include "DiscreteTerm.h"
#include "FunctionTerm.h"
#include "FuzzyAnd.h"
#include "FuzzyAntecedent.h"
#include "FuzzyConsequent.h"
#include "FuzzyDefuzzifier.h"
#include "FuzzyEngine.h"
#include "FuzzyException.h"
#include "FuzzyExceptions.h"
#include "FuzzyModulation.h"
#include "FuzzyOperation.h"
#include "FuzzyOperator.h"
#include "FuzzyOr.h"
#include "FuzzyRule.h"
#include "Hedge.h"
#include "HedgeSet.h"
#include "InfixToPostfix.h"
#include "InputLVar.h"
#include "LinguisticTerm.h"
#include "LinguisticVariable.h"
#include "MamdaniConsequent.h"
#include "MamdaniRule.h"
#include "OutputLVar.h"
#include "RectangularTerm.h"
#include "RuleBlock.h"
#include "ShoulderTerm.h"
#include "SingletonTerm.h"
#include "StrOp.h"
#include "TakagiSugenoConsequent.h"
#include "TakagiSugenoRule.h"
#include "TakagiSugenoTerm.h"
#include "TrapezoidalTerm.h"
#include "TriangularTerm.h"
#include "defs.h"
#include "flScalar.h"
#endif /* FL_FUZZYLITE_H */

View File

@ -0,0 +1,35 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "FuzzyModulation.h"
namespace fl {
std::string FuzzyModClip::name() const {
return "Clip";
}
flScalar FuzzyModClip::execute(flScalar mu1, flScalar mu2) const {
return FuzzyOperation::Min(mu1, mu2);
}
std::string FuzzyModScale::name() const {
return "Scale";
}
flScalar FuzzyModScale::execute(flScalar mu1, flScalar mu2) const {
return FuzzyOperation::AlgebraicProduct(mu1, mu2);
}
}

View File

@ -0,0 +1,44 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: FuzzyModulation.h
* Author: jcrada
*
* Created on April 6, 2010, 6:53 PM
*/
#ifndef FL_FUZZYMODULATION_H
#define FL_FUZZYMODULATION_H
#include "FuzzyOperation.h"
namespace fl {
class FuzzyModClip : public FuzzyOperation {
public:
virtual std::string name() const;
virtual flScalar execute(flScalar mu1, flScalar mu2) const;
};
class FuzzyModScale : public FuzzyOperation {
public:
virtual std::string name() const;
virtual flScalar execute(flScalar mu1, flScalar mu2) const;
};
}
#endif /* FL_FUZZYMODULATION_H */

View File

@ -0,0 +1,78 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "FuzzyOperation.h"
#include <math.h>
namespace fl {
FuzzyOperation::~FuzzyOperation() {
}
//TNORMS
flScalar FuzzyOperation::Min(flScalar mu1, flScalar mu2) {
return mu1 < mu2 ? mu1 : mu2;
}
flScalar FuzzyOperation::AlgebraicProduct(flScalar mu1, flScalar mu2) {
return mu1 * mu2;
}
flScalar FuzzyOperation::BoundedDiff(flScalar mu1, flScalar mu2) {
return Max(0, mu1 + mu2 -1);
}
//SNORMS
flScalar FuzzyOperation::Max(flScalar mu1, flScalar mu2) {
return mu1 > mu2 ? mu1 : mu2;
}
flScalar FuzzyOperation::AlgebraicSum(flScalar mu1, flScalar mu2) {
return mu1 + mu2 - (mu1 * mu2);
}
flScalar FuzzyOperation::BoundedSum(flScalar mu1, flScalar mu2) {
return Min(1, mu1 + mu2);
}
//Other operators
flScalar FuzzyOperation::Absolute(flScalar value) {
return value < flScalar(0.0) ? value * flScalar(-1.0) : value;
}
bool FuzzyOperation::IsEq(flScalar x1, flScalar x2, flScalar epsilon) {
//http://stackoverflow.com/questions/17333/most-effective-way-for-float-and-double-comparison
// return fabs(x1 - x2) < std::numeric_limits<flScalar>::epsilon() ;
return fabs(x1 - x2) < epsilon;
}
bool FuzzyOperation::IsLEq(flScalar x1, flScalar x2, flScalar epsilon) {
return IsEq(x1, x2, epsilon) ? true : x1 < x2;
}
bool FuzzyOperation::IsGEq(flScalar x1, flScalar x2, flScalar epsilon) {
return IsEq(x1, x2,epsilon) ? true : x1 > x2;
}
flScalar FuzzyOperation::Scale(flScalar src_min, flScalar src_max, flScalar value,
flScalar target_min, flScalar target_max) {
//Courtesy of Rubén Parma :)
return (target_max - target_min) / (src_max - src_min) * (value - src_min)
+ target_min;
}
}

View File

@ -0,0 +1,58 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: FuzzyOperation.h
* Author: jcrada
*
* Created on April 6, 2010, 6:42 PM
*/
#ifndef FL_FUZZYOPERATION_H
#define FL_FUZZYOPERATION_H
#include "flScalar.h"
#include <string>
namespace fl {
class FuzzyOperation {
public:
virtual ~FuzzyOperation();
virtual std::string name() const = 0;
virtual flScalar execute(flScalar mu1, flScalar mu2) const = 0;
//TNORMS
static flScalar Min(flScalar mu1, flScalar mu2);
static flScalar AlgebraicProduct(flScalar mu1, flScalar mu2);
static flScalar BoundedDiff(flScalar mu1, flScalar mu2);
//SNORMS
static flScalar Max(flScalar mu1, flScalar mu2);
static flScalar AlgebraicSum(flScalar mu1, flScalar mu2);
static flScalar BoundedSum(flScalar mu1, flScalar mu2);
//Other operators
static flScalar Absolute(flScalar value);
static bool IsEq(flScalar x1, flScalar x2, flScalar epsilon = FL_EPSILON);
static bool IsLEq(flScalar x1, flScalar x2, flScalar epsilon = FL_EPSILON);
static bool IsGEq(flScalar x1, flScalar x2, flScalar epsilon = FL_EPSILON);
static flScalar Scale(flScalar src_min, flScalar src_max, flScalar value,
flScalar target_min, flScalar target_max);
};
}
#endif /* FL_FUZZYOPERATION_H */

View File

@ -0,0 +1,125 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "FuzzyOperator.h"
#include "StrOp.h"
#include <limits>
#include <math.h>
#include "CompoundTerm.h"
#include "TakagiSugenoTerm.h"
#include "MamdaniRule.h"
namespace fl {
FuzzyOperator::FuzzyOperator(const FuzzyOperation* tnorm,
const FuzzyOperation* snorm,
const FuzzyOperation* cmod,
const FuzzyOperation* aggregation,
const FuzzyDefuzzifier* defuzzifier,
const AreaCentroidAlgorithm* algorithm,
int number_of_samples)
: _tnorm(tnorm), _snorm(snorm), _cmodulation(cmod), _aggregation(aggregation),
_defuzzifier(defuzzifier), _acalgorithm(algorithm),
_number_of_samples(number_of_samples) {
}
FuzzyOperator::~FuzzyOperator() {
}
void FuzzyOperator::setTnorm(const FuzzyOperation* tnorm) {
delete this->_tnorm;
this->_tnorm = tnorm;
}
void FuzzyOperator::setSnorm(const FuzzyOperation* snorm) {
delete this->_snorm;
this->_snorm = snorm;
}
void FuzzyOperator::setModulation(const FuzzyOperation* modulation) {
delete this->_cmodulation;
this->_cmodulation = modulation;
}
void FuzzyOperator::setAggregation(const FuzzyOperation* aggregation) {
delete this->_aggregation;
this->_aggregation = aggregation;
}
void FuzzyOperator::setDefuzzifier(const FuzzyDefuzzifier* defuzzifier) {
delete this->_defuzzifier;
this->_defuzzifier = defuzzifier;
}
void FuzzyOperator::setAreaCentroidAlgorithm(const AreaCentroidAlgorithm* algorithm) {
delete this->_acalgorithm;
this->_acalgorithm = algorithm;
}
void FuzzyOperator::setNumberOfSamples(int samples) {
this->_number_of_samples = samples;
}
const FuzzyOperation& FuzzyOperator::tnorm() const {
return *this->_tnorm;
}
const FuzzyOperation& FuzzyOperator::snorm() const {
return *this->_snorm;
}
const FuzzyOperation& FuzzyOperator::modulation() const {
return *this->_cmodulation;
}
const FuzzyOperation& FuzzyOperator::aggregation() const {
return *this->_aggregation;
}
const FuzzyDefuzzifier& FuzzyOperator::defuzzifier() const {
return *this->_defuzzifier;
}
const AreaCentroidAlgorithm& FuzzyOperator::acAlgorithm() const {
return *this->_acalgorithm;
}
int FuzzyOperator::numberOfSamples() const {
return this->_number_of_samples;
}
flScalar FuzzyOperator::defuzzify(const LinguisticTerm* term) const {
return defuzzifier().defuzzify(term, numberOfSamples(), &acAlgorithm());
}
flScalar FuzzyOperator::area(const LinguisticTerm* term) const {
return acAlgorithm().area(term, numberOfSamples());
}
void FuzzyOperator::centroid(const LinguisticTerm* term, flScalar& x, flScalar& y) const {
acAlgorithm().centroid(term, x, y, numberOfSamples());
}
flScalar FuzzyOperator::areaAndCentroid(const LinguisticTerm* term, flScalar& x, flScalar& y) const {
return acAlgorithm().areaAndCentroid(term, x, y, numberOfSamples());
}
FuzzyOperator& FuzzyOperator::DefaultFuzzyOperator() {
static FuzzyOperator* FUZZY_OP = new fl::FuzzyOperator;
return *FUZZY_OP;
}
}

View File

@ -0,0 +1,84 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: FuzzyOperator.h
* Author: jcrada
*
* Created on November 1, 2009, 3:05 PM
*/
#ifndef FL_FUZZYOPERATOR_H
#define FL_FUZZYOPERATOR_H
#include "defs.h"
#include "flScalar.h"
#include "FuzzyOperation.h"
#include "FuzzyAnd.h"
#include "FuzzyOr.h"
#include "FuzzyModulation.h"
#include "AreaCentroidAlgorithm.h"
#include "FuzzyDefuzzifier.h"
namespace fl {
class LinguisticTerm;
class FuzzyOperator {
private:
const FuzzyOperation* _tnorm;
const FuzzyOperation* _snorm;
const FuzzyOperation* _cmodulation;
const FuzzyOperation* _aggregation;
const FuzzyDefuzzifier* _defuzzifier;
const AreaCentroidAlgorithm* _acalgorithm;
int _number_of_samples;
public:
FuzzyOperator(const FuzzyOperation* tnorm = new FuzzyAndMin,
const FuzzyOperation* snorm = new FuzzyOrMax,
const FuzzyOperation* cmod = new FuzzyModClip,
const FuzzyOperation* aggregation = new FuzzyOrMax,
const FuzzyDefuzzifier* defuzzifier = new CoGDefuzzifier,
const AreaCentroidAlgorithm* algorithm = new TriangulationAlgorithm, //bugfix
int number_of_samples = FL_SAMPLE_SIZE);
virtual ~FuzzyOperator();
virtual void setTnorm(const FuzzyOperation* tnorm);
virtual void setSnorm(const FuzzyOperation* snorm);
virtual void setModulation(const FuzzyOperation* modulation);
virtual void setAggregation(const FuzzyOperation* aggregation);
virtual void setDefuzzifier(const FuzzyDefuzzifier* defuzzifier);
virtual void setAreaCentroidAlgorithm(const AreaCentroidAlgorithm* algorithm);
virtual void setNumberOfSamples(int samples);
virtual const FuzzyOperation& tnorm() const;
virtual const FuzzyOperation& snorm() const;
virtual const FuzzyOperation& modulation() const;
virtual const FuzzyOperation& aggregation() const;
virtual const FuzzyDefuzzifier& defuzzifier() const;
virtual const AreaCentroidAlgorithm& acAlgorithm() const;
virtual int numberOfSamples() const;
virtual flScalar defuzzify(const LinguisticTerm* term) const;
virtual flScalar area(const LinguisticTerm* term) const;
virtual void centroid(const LinguisticTerm* term, flScalar& x, flScalar& y) const;
virtual flScalar areaAndCentroid(const LinguisticTerm* term, flScalar& x, flScalar& y) const;
static FuzzyOperator& DefaultFuzzyOperator();
};
}
#endif /* FL_FUZZYOPERATOR_H */

44
AI/FuzzyLite/FuzzyOr.cpp Normal file
View File

@ -0,0 +1,44 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "FuzzyOr.h"
namespace fl {
std::string FuzzyOrMax::name() const{
return "Max";
}
flScalar FuzzyOrMax::execute(flScalar mu1, flScalar mu2) const{
return FuzzyOperation::Max(mu1,mu2);
}
std::string FuzzyOrSum::name() const{
return "Sum";
}
flScalar FuzzyOrSum::execute(flScalar mu1, flScalar mu2) const{
return FuzzyOperation::AlgebraicSum(mu1,mu2);
}
std::string FuzzyOrBSum::name() const{
return "BSum";
}
flScalar FuzzyOrBSum::execute(flScalar mu1, flScalar mu2) const{
return FuzzyOperation::BoundedSum(mu1,mu2);
}
}

49
AI/FuzzyLite/FuzzyOr.h Normal file
View File

@ -0,0 +1,49 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: FuzzyOr.h
* Author: jcrada
*
* Created on April 6, 2010, 5:13 PM
*/
#ifndef FL_FUZZYOR_H
#define FL_FUZZYOR_H
#include "FuzzyOperation.h"
namespace fl {
class FuzzyOrMax : public FuzzyOperation {
public:
virtual std::string name() const;
virtual flScalar execute(flScalar mu1, flScalar mu2) const;
};
class FuzzyOrSum : public FuzzyOperation {
public:
virtual std::string name() const;
virtual flScalar execute(flScalar mu1, flScalar mu2) const;
};
class FuzzyOrBSum : public FuzzyOperation {
public:
virtual std::string name() const;
virtual flScalar execute(flScalar mu1, flScalar mu2) const;
};
}
#endif /* FL_FUZZYOR_H */

135
AI/FuzzyLite/FuzzyRule.cpp Normal file
View File

@ -0,0 +1,135 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* FuzzyRule.cpp
*
* Created on: Dec 13, 2009
* Author: jcrada
*/
#include "FuzzyRule.h"
#include <stack>
#include <iosfwd>
#include "StrOp.h"
namespace fl {
const std::string FuzzyRule::FR_IF = "if";
const std::string FuzzyRule::FR_IS = "is";
const std::string FuzzyRule::FR_THEN = "then";
const std::string FuzzyRule::FR_AND = "and";
const std::string FuzzyRule::FR_OR = "or";
const std::string FuzzyRule::FR_WITH = "with";
FuzzyRule::FuzzyRule() : _antecedent(NULL) {
setFuzzyOperator(fuzzyOperator().DefaultFuzzyOperator());
}
FuzzyRule::FuzzyRule(const FuzzyOperator& fuzzy_op)
: _fuzzy_operator(&fuzzy_op), _antecedent(NULL) {
}
FuzzyRule::~FuzzyRule() {
if (_antecedent) {
delete _antecedent;
}
FuzzyConsequent* fconsequent = NULL;
for (int i = numberOfConsequents() - 1; i >= 0; --i) {
fconsequent = consequent(i);
_consequents.pop_back();
delete fconsequent;
}
}
void FuzzyRule::setFuzzyOperator(const FuzzyOperator& fuzzy_op){
this->_fuzzy_operator = &fuzzy_op;
if (antecedent()){
antecedent()->setFuzzyOperator(fuzzy_op);
}
//Todo: check if consequents must have a fuzzyoperator
for (int i =0 ; i < numberOfConsequents() ;++i){
}
}
const FuzzyOperator& FuzzyRule::fuzzyOperator() const{
return *this->_fuzzy_operator;
}
void FuzzyRule::setAntecedent(FuzzyAntecedent* antecedent) {
this->_antecedent = antecedent;
}
FuzzyAntecedent* FuzzyRule::antecedent() const {
return this->_antecedent;
}
FuzzyConsequent* FuzzyRule::consequent(int index) const {
return this->_consequents[index];
}
void FuzzyRule::addConsequent(FuzzyConsequent* consequent) {
this->_consequents.push_back(consequent);
}
int FuzzyRule::numberOfConsequents() const {
return this->_consequents.size();
}
bool FuzzyRule::isValid() const {
return this->_antecedent && this->_consequents.size() > 0;
}
flScalar FuzzyRule::firingStrength() const {
if (antecedent()) {
return antecedent()->degreeOfTruth();
}
throw InvalidArgumentException(FL_AT,"Antecedent was not parsed correctly");
}
void FuzzyRule::fire(flScalar strength) {
if (!FuzzyOperation::IsEq(strength, flScalar(0.0))) {
// FL_LOG("DoT: " << strength << " - Fired: " << toString());
for (int i = 0; i < numberOfConsequents(); ++i) {
consequent(i)->execute(strength);
}
}
}
std::string FuzzyRule::toString() const {
std::stringstream ss;
ss << FR_IF << " " << _antecedent->toString() << " " << FR_THEN;
for (int i = 0; i < numberOfConsequents(); ++i) {
ss << " " + consequent(i)->toString() + (i < numberOfConsequents() - 1 ? FR_AND : "");
}
return ss.str();
}
void FuzzyRule::ExtractFromRule(const std::string& rule, std::string& antecedent, std::string& consequent) {
std::vector<std::string> parse = StrOp::SplitByWord(rule, FR_IF);
if (parse.size() != 1) {
antecedent = "invalid";
consequent = "invalid";
return;
}
parse = StrOp::SplitByWord(parse[0], FR_THEN);
if (parse.size() != 2){
antecedent = "invalid";
consequent = "invalid";
return;
}
antecedent = parse[0];
consequent = parse[1];
}
}// namespace fuzzy_lite

79
AI/FuzzyLite/FuzzyRule.h Normal file
View File

@ -0,0 +1,79 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: FuzzyRule.h
* Author: jcrada
*
* Created on November 5, 2009, 11:11 AM
*/
#ifndef FL_FUZZYRULE_H
#define FL_FUZZYRULE_H
#include "FuzzyOperator.h"
#include "FuzzyAntecedent.h"
#include "FuzzyConsequent.h"
#include <string>
#include <vector>
#include "flScalar.h"
#include "FuzzyExceptions.h"
namespace fl {
class FuzzyRule {
public:
static const std::string FR_IF;
static const std::string FR_IS;
static const std::string FR_THEN;
static const std::string FR_AND;
static const std::string FR_OR;
static const std::string FR_WITH;
private:
const FuzzyOperator* _fuzzy_operator;
FuzzyAntecedent* _antecedent;
std::vector<FuzzyConsequent*> _consequents;
public:
FuzzyRule();
FuzzyRule(const FuzzyOperator& fuzzy_op);
virtual ~FuzzyRule();
virtual void setFuzzyOperator(const FuzzyOperator& fuzzy_op);
virtual const FuzzyOperator& fuzzyOperator() const;
virtual FuzzyAntecedent* antecedent() const;
virtual void setAntecedent(FuzzyAntecedent* antecedent);
virtual FuzzyConsequent* consequent(int index) const;
virtual void addConsequent(FuzzyConsequent* consequent);
virtual int numberOfConsequents() const;
virtual bool isValid() const;
virtual flScalar firingStrength() const;
virtual void fire(flScalar strength);
virtual std::string toString() const;
virtual void parse(const std::string& rule, const FuzzyEngine& engine) = 0;
static void ExtractFromRule(const std::string& rule, std::string& antecedent, std::string& consequent);
};
}
#endif /* _FUZZYRULE_H */

59
AI/FuzzyLite/Hedge.cpp Normal file
View File

@ -0,0 +1,59 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* Hedge.cpp
*
* Created on: Dec 13, 2009
* Author: jcrada
*/
#include "Hedge.h"
namespace fl {
Hedge::~Hedge() {
}
std::string HedgeNot::name() const {
return "not";
}
flScalar HedgeNot::hedge(flScalar mu) const {
return 1 - mu;
}
std::string HedgeSomewhat::name() const {
return "somewhat";
}
flScalar HedgeSomewhat::hedge(flScalar mu) const {
return sqrt(mu);
}
std::string HedgeVery::name() const {
return "very";
}
flScalar HedgeVery::hedge(flScalar mu) const {
return mu * mu;
}
std::string HedgeAny::name() const {
return "any";
}
flScalar HedgeAny::hedge(flScalar mu) const {
return 1.0;
}
}

66
AI/FuzzyLite/Hedge.h Normal file
View File

@ -0,0 +1,66 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: Hedge.h
* Author: jcrada
*
* Created on November 1, 2009, 2:55 PM
*/
#ifndef FL_HEDGE_H
#define FL_HEDGE_H
#include <string>
#include <math.h>
#include "flScalar.h"
#include "defs.h"
namespace fl {
class Hedge {
public:
virtual ~Hedge();
virtual std::string name() const = 0;
virtual flScalar hedge(flScalar mu) const = 0;
};
class HedgeNot : public Hedge {
public:
std::string name() const;
flScalar hedge(flScalar mu) const;
};
class HedgeSomewhat : public Hedge {
public:
std::string name() const;
flScalar hedge(flScalar mu) const;
};
class HedgeVery : public Hedge {
public:
std::string name() const;
flScalar hedge(flScalar mu) const;
};
class HedgeAny : public Hedge {
public:
std::string name() const;
flScalar hedge(flScalar mu) const;
};
}
#endif /* FL_HEDGE_H */

58
AI/FuzzyLite/HedgeSet.cpp Normal file
View File

@ -0,0 +1,58 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "HedgeSet.h"
namespace fl {
HedgeSet::HedgeSet() {
}
HedgeSet::~HedgeSet() {
}
void HedgeSet::add(Hedge* hedge) {
this->_hedges.push_back(hedge);
}
Hedge* HedgeSet::remove(int index) {
Hedge* result = this->_hedges[index];
this->_hedges.erase(this->_hedges.begin() + index);
return result;
}
Hedge* HedgeSet::get(const std::string hedge) const {
int index = indexOf(hedge);
return index == -1 ? NULL : this->_hedges[index];
}
Hedge* HedgeSet::get(int index) const {
return this->_hedges[index];
}
int HedgeSet::indexOf(const std::string& hedge) const {
for (int i = 0; i < numberOfHedges(); ++i) {
if (get(i)->name() == hedge) {
return i;
}
}
return -1;
}
int HedgeSet::numberOfHedges() const {
return this->_hedges.size();
}
}

46
AI/FuzzyLite/HedgeSet.h Normal file
View File

@ -0,0 +1,46 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: HedgeSet.h
* Author: jcrada
*
* Created on March 5, 2010, 1:09 AM
*/
#ifndef FL_HEDGESET_H
#define FL_HEDGESET_H
#include <vector>
#include "Hedge.h"
namespace fl{
class HedgeSet{
private:
std::vector<Hedge*> _hedges;
public:
HedgeSet();
virtual ~HedgeSet();
virtual void add(Hedge* hedge);
virtual Hedge* remove(int index);
virtual Hedge* get(const std::string hedge) const;
virtual Hedge* get(int index) const;
virtual int indexOf(const std::string& hedge) const;
virtual int numberOfHedges() const;
};
}
#endif /* FL_HEDGESET_H */

View File

@ -0,0 +1,250 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "InfixToPostfix.h"
#include <stack>
#include "defs.h"
#include <sstream>
#include "StrOp.h"
#include <math.h>
#include <stdlib.h>
namespace fl {
InfixToPostfix::InfixToPostfix() {
}
InfixToPostfix::~InfixToPostfix() {
}
void InfixToPostfix::addOperator(const std::string& op, int precedence) {
this->_operators.insert(this->_operators.begin() + precedence, op);
}
std::string InfixToPostfix::removeOperator(int index) {
std::string result = getOperator(index);
this->_operators.erase(this->_operators.begin() + index);
return result;
}
std::string InfixToPostfix::getOperator(int index) const {
return this->_operators.at(index);
}
int InfixToPostfix::operatorPrecedence(const std::string& op) const {
for (int i = 0; i < numberOfOperators(); ++i) {
std::stringstream ss(getOperator(i));
std::string token;
while (ss >> token) {
if (token == op) {
return i;
}
}
}
return -1;
}
int InfixToPostfix::numberOfOperators() const {
return this->_operators.size();
}
bool InfixToPostfix::isOperator(const std::string& op) const {
return operatorPrecedence(op) != -1;
}
bool InfixToPostfix::isUnaryOperator(const std::string op) const {
return op == "!" || op == "sin" || op == "cos" || op == "tan" ||
op == "sinh" || op == "cosh" || op == "tanh";
}
void InfixToPostfix::loadLogicalOperators() {
addOperator("!");
addOperator("or");
addOperator("and");
}
void InfixToPostfix::loadMathOperators() {
addOperator("^");
addOperator("/ * %");
addOperator("sin cos tan sinh cosh tanh");
addOperator("+ -");
}
bool InfixToPostfix::isOperand(const std::string& op) const {
return !isOperator(op) ;
}
bool InfixToPostfix::isNumeric(const std::string& x) const {
return (int) x.find_first_not_of("0123456789.-+") == -1;
}
std::string InfixToPostfix::preprocess(const std::string& infix) const {
std::string result = infix;
StrOp::FindReplace(result,"(", " ( ");
StrOp::FindReplace(result, ")", " ) ");
return result;
}
//TODO: Be Careful: sin(x) / x => x x / sin. The expected is obtained: (sin x) / x => x sin x /
std::string InfixToPostfix::transform(const std::string& infix) const {
std::string p_infix = preprocess(infix);
std::string postfix;
std::stack<std::string> stack;
std::stringstream ss(p_infix);
std::string token;
while (ss >> token) {
if (token == "(") {
stack.push(token);
} else if (token == ")") {
while (!stack.empty()) {
if (stack.top() == "(") {
stack.pop();
break;
}
postfix += stack.top() + " ";
stack.pop();
}
} else if (isOperand(token)) {
postfix += token + " ";
} else if (isOperator(token)) {
while (!stack.empty() &&
operatorPrecedence(token) <= operatorPrecedence(stack.top())) {
postfix += stack.top() + " ";
stack.pop();
}
stack.push(token);
}
}
while (!stack.empty()) {
postfix += stack.top() + " ";
stack.pop();
}
return postfix;
}
flScalar InfixToPostfix::evaluate(const std::string postfix,
const std::map<std::string, flScalar>* variables) const {
std::stack<flScalar> stack;
std::stringstream ss(postfix);
std::string token;
while (ss >> token) {
if (isOperand(token)) {
if (isNumeric(token)) {
stack.push(atof(token.c_str()));
} else {
if (!variables) {
throw FuzzyException(FL_AT, "Impossible to compute operand <" + token + "> because no map was supplied");
}
std::map<std::string, flScalar>::const_iterator it = variables->find(token);
if (it == variables->end()) {
throw FuzzyException(FL_AT, "Operand <" + token + "> not found in map");
}
stack.push(it->second);
}
} else if (isOperator(token)) {
if (isUnaryOperator(token)) {
if (stack.empty()) {
throw FuzzyException(FL_AT, "Error evaluating postfix expression <" + postfix + ">");
}
flScalar a = stack.top();
stack.pop();
stack.push(compute(token, a, 0));
} else {
if (stack.size() < 2) {
throw FuzzyException(FL_AT, "Error evaluating postfix expression <" + postfix + ">");
}
flScalar b = stack.top();
stack.pop();
flScalar a = stack.top();
stack.pop();
stack.push(compute(token, a, b));
}
}
}
if (stack.size() == 1){
return stack.top();
}
throw FuzzyException(FL_AT, "Error evaluating postfix expression <" + postfix + ">");
}
flScalar InfixToPostfix::compute(const std::string& op, flScalar a, flScalar b) const {
if (op == "!") {
return !(bool)a;
}
if (op == "and") {
return (bool)a && (bool)b;
}
if (op == "or") {
return (bool)a || (bool)b;
}
if (op == "+") {
return a + b;
}
if (op == "-") {
return a - b;
}
if (op == "*") {
return a * b;
}
if (op == "/") {
return a / b;
}
if (op == "%") {
return (long) a % (long) b;
}
if (op == "^") {
return pow(a, b);
}
if (op == "sin") {
return sin(a);
}
if (op == "cos") {
return cos(a);
}
if (op == "tan") {
return tan(a);
}
if (op == "sinh") {
return sinh(a);
}
if (op == "cosh") {
return cosh(a);
}
if (op == "tanh") {
return tanh(a);
}
throw FuzzyException(FL_AT, "Operator <" + op + "> not defined");
}
void InfixToPostfix::main(int args, char** argv) {
std::map<std::string, flScalar> m;
m["x"] = 4;
m["y"] = 2;
m["z"] = -4;
std::string x = "(sin x) / x";
FL_LOG(x);
InfixToPostfix ip;
ip.loadMathOperators();
std::string postfix = ip.transform(x);
FL_LOG(postfix);
for (flScalar x = 0.0 ; x < 10.5 ; x+=0.5){
m["x"] = x;
FL_LOG(ip.evaluate(postfix, &m));
}
}
}

View File

@ -0,0 +1,67 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: InfixToPostfix.h
* Author: jcrada
*
* Created on March 6, 2010, 1:14 AM
*/
#ifndef _INFIXTOPOSTFIX_H
#define _INFIXTOPOSTFIX_H
#include <vector>
#include <string>
#include <map>
#include "flScalar.h"
namespace fl {
class InfixToPostfix {
private:
std::vector<std::string> _operators;
protected:
virtual std::string preprocess(const std::string& infix) const;
public:
InfixToPostfix();
virtual ~InfixToPostfix();
virtual void addOperator(const std::string& op, int precedence = 0);
virtual std::string removeOperator(int index);
virtual std::string getOperator(int index) const;
virtual int operatorPrecedence(const std::string& op) const;
virtual int numberOfOperators() const;
virtual bool isOperator(const std::string& op) const;
virtual bool isUnaryOperator(const std::string op) const;
virtual bool isOperand(const std::string& op) const;
virtual bool isNumeric(const std::string& op) const;
virtual void loadLogicalOperators();
virtual void loadMathOperators();
virtual std::string transform(const std::string& infix) const;
virtual flScalar evaluate(const std::string postfix,
const std::map<std::string, flScalar>* variables = NULL) const;
virtual flScalar compute(const std::string& op, flScalar a, flScalar b) const;
static void main(int args, char** argv);
};
}
#endif /* _INFIXTOPOSTFIX_H */

View File

@ -0,0 +1,39 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "InputLVar.h"
namespace fl {
InputLVar::InputLVar() : LinguisticVariable(), _input(flScalar(0.0)) {
}
InputLVar::InputLVar(const std::string& name) : LinguisticVariable(name),
_input(flScalar(0.0)) {
}
InputLVar::~InputLVar() {
}
void InputLVar::setInput(flScalar input) {
this->_input = input;
}
flScalar InputLVar::input() const {
return this->_input;
}
}

44
AI/FuzzyLite/InputLVar.h Normal file
View File

@ -0,0 +1,44 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: InputLVar.h
* Author: jcrada
*
* Created on November 1, 2009, 2:25 PM
*/
#ifndef FL_INPUTLVAR_H
#define FL_INPUTLVAR_H
#include "LinguisticVariable.h"
namespace fl {
class InputLVar : public LinguisticVariable {
private:
flScalar _input;
public:
InputLVar();
InputLVar(const std::string& name);
virtual ~InputLVar();
virtual void setInput(flScalar input);
virtual flScalar input() const;
};
}
#endif /* FL_INPUTLVAR_H */

View File

@ -0,0 +1,118 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "LinguisticTerm.h"
#include "TriangularTerm.h"
#include "TrapezoidalTerm.h"
#include "ShoulderTerm.h"
#include "FuzzyException.h"
namespace fl {
LinguisticTerm::LinguisticTerm() :
_fuzzy_operator(NULL), _name(""), _minimum(-INFINITY), _maximum(INFINITY),
_modulation(flScalar(1.0)) {
setFuzzyOperator(FuzzyOperator::DefaultFuzzyOperator());
}
LinguisticTerm::LinguisticTerm(const std::string& name, flScalar minimum,
flScalar maximum) :
_fuzzy_operator(NULL), _name(name), _minimum(minimum), _maximum(maximum),
_modulation(flScalar(1.0)) {
setFuzzyOperator(FuzzyOperator::DefaultFuzzyOperator());
}
LinguisticTerm::LinguisticTerm(const FuzzyOperator& fuzzy_op,
const std::string& name, flScalar minimum, flScalar maximum) :
_fuzzy_operator(&fuzzy_op), _name(name), _minimum(minimum), _maximum(maximum),
_modulation(flScalar(1.0)) {
}
LinguisticTerm::~LinguisticTerm() {
}
void LinguisticTerm::setFuzzyOperator(const FuzzyOperator& fuzzy_operator) {
this->_fuzzy_operator = &fuzzy_operator;
}
const FuzzyOperator& LinguisticTerm::fuzzyOperator() const {
return *this->_fuzzy_operator;
}
void LinguisticTerm::setName(const std::string& name) {
this->_name = name;
}
std::string LinguisticTerm::name() const {
return this->_name;
}
void LinguisticTerm::setMinimum(flScalar min) {
this->_minimum = min;
}
flScalar LinguisticTerm::minimum() const {
return _minimum;
}
void LinguisticTerm::setMaximum(flScalar max) {
this->_maximum = max;
}
flScalar LinguisticTerm::maximum() const {
return _maximum;
}
void LinguisticTerm::setModulation(flScalar degree) {
this->_modulation = degree;
}
flScalar LinguisticTerm::modulation() const {
return this->_modulation;
}
flScalar LinguisticTerm::defuzzify() const {
return fuzzyOperator().defuzzify(this);
}
flScalar LinguisticTerm::area() const {
return fuzzyOperator().area(this);
}
void LinguisticTerm::centroid(flScalar& x, flScalar& y) const {
fuzzyOperator().centroid(this, x, y);
}
flScalar LinguisticTerm::areaAndCentroid(flScalar& x, flScalar& y) const {
return fuzzyOperator().areaAndCentroid(this, x, y);
}
void LinguisticTerm::samples(std::vector<flScalar>& x, std::vector<flScalar>& y,
int samples, int out_of_range) const {
flScalar step_size = (maximum() - minimum()) / samples;
flScalar step = minimum() - (out_of_range * step_size);
for (int i = 0 - out_of_range; i < samples + out_of_range + 1; ++i, step
+= step_size) {
x.push_back(step);
y.push_back(membership(step));
}
}
std::string LinguisticTerm::toString() const {
return "TERM " + name() + " := ";
}
}

View File

@ -0,0 +1,96 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: Term.h
* Author: jcrada
*
* Created on December 9, 2009, 12:27 AM
*/
#ifndef FL_TERM_H
#define FL_TERM_H
#include "flScalar.h"
#include <vector>
#include <math.h>
#include <string>
#include "defs.h"
#include "FuzzyOperation.h"
#include "FuzzyOperator.h"
namespace fl {
class FuzzyOperator; //forward-declaration
class LinguisticTerm {
public:
enum eMembershipFunction {
MF_TRIANGULAR = 0, MF_TRAPEZOIDAL, MF_RECTANGULAR, MF_SHOULDER, MF_SINGLETON,
MF_COMPOUND, MF_FUNCTION, MF_TAKAGI_SUGENO, MF_DISCRETE,
//to implement
MF_SIGMOIDAL, MF_COSINE, MF_GAUSSIAN,
};
private:
const FuzzyOperator* _fuzzy_operator;
std::string _name;
flScalar _minimum;
flScalar _maximum;
flScalar _modulation;
public:
LinguisticTerm();
LinguisticTerm(const std::string& name, flScalar minimum = -INFINITY,
flScalar maximum = INFINITY);
LinguisticTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
flScalar minimum = -INFINITY, flScalar maximum = INFINITY);
virtual ~LinguisticTerm();
virtual void setFuzzyOperator(const FuzzyOperator& fuzzy_op);
virtual const FuzzyOperator& fuzzyOperator() const;
virtual void setName(const std::string& name);
virtual std::string name() const;
virtual void setMinimum(flScalar min);
virtual flScalar minimum() const;
virtual void setMaximum(flScalar max);
virtual flScalar maximum() const;
virtual void setModulation(flScalar degree);
virtual flScalar modulation() const;
virtual flScalar defuzzify() const;
virtual std::string toString() const;
virtual LinguisticTerm* clone() const = 0;
virtual flScalar membership(flScalar crisp) const = 0;
virtual eMembershipFunction type() const = 0;
virtual void samples(std::vector<flScalar>& x, std::vector<flScalar>& y,
int samples = FL_SAMPLE_SIZE, int out_of_range = 0) const;
virtual flScalar area() const;
virtual void centroid(flScalar&x, flScalar& y) const;
virtual flScalar areaAndCentroid(flScalar& x, flScalar& y) const;
};
}
#endif /* FL_TERM_H */

View File

@ -0,0 +1,238 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "LinguisticVariable.h"
#include "FuzzyExceptions.h"
#include "StrOp.h"
#include <algorithm>
#include <math.h>
#include "ShoulderTerm.h"
#include "TriangularTerm.h"
#include "TrapezoidalTerm.h"
namespace fl {
LinguisticVariable::LinguisticVariable() :
_fuzzy_operator(NULL) {
setFuzzyOperator(FuzzyOperator::DefaultFuzzyOperator());
}
LinguisticVariable::LinguisticVariable(const std::string& name) :
_fuzzy_operator(NULL), _name(name) {
setFuzzyOperator(FuzzyOperator::DefaultFuzzyOperator());
}
LinguisticVariable::LinguisticVariable(const FuzzyOperator& fuzzy_op,
const std::string& name) :
_fuzzy_operator(&fuzzy_op), _name(name) {
}
LinguisticVariable::~LinguisticVariable() {
for (int i = numberOfTerms() - 1; i >= 0; --i) {
delete removeTerm(i);
}
}
std::string LinguisticVariable::name() const {
return this->_name;
}
void LinguisticVariable::setName(const std::string& name) {
this->_name = name;
}
void LinguisticVariable::setFuzzyOperator(const FuzzyOperator& fuzzy_operator) {
this->_fuzzy_operator = &fuzzy_operator;
}
const FuzzyOperator& LinguisticVariable::fuzzyOperator() const {
return *this->_fuzzy_operator;
}
int LinguisticVariable::positionFor(const LinguisticTerm* lterm) {
for (int i = 0; i < numberOfTerms(); ++i) {
if (FuzzyOperation::IsLEq(lterm->minimum(), term(i)->minimum())) {
if (FuzzyOperation::IsEq(lterm->minimum(), term(i)->minimum())) {
return lterm->membership(lterm->minimum()) > term(i)->membership(lterm->minimum())
? i : i + 1;
}
return i;
}
}
return numberOfTerms();
}
void LinguisticVariable::addTerm(LinguisticTerm* term) {
int pos = positionFor(term);
_terms.insert(_terms.begin() + pos, term);
}
LinguisticTerm* LinguisticVariable::term(int index) const {
return _terms[index];
}
LinguisticTerm* LinguisticVariable::term(const std::string& name) const {
int index = indexOf(name);
return index == -1 ? NULL : term(index);
}
int LinguisticVariable::indexOf(const std::string& name) const {
for (int i = 0; i < numberOfTerms(); ++i) {
if (term(i)->name() == name) {
return i;
}
}
return -1;
}
LinguisticTerm* LinguisticVariable::removeTerm(int index) {
LinguisticTerm* result = _terms[index];
_terms.erase(_terms.begin() + index);
return result;
}
LinguisticTerm* LinguisticVariable::removeTerm(const std::string& name) {
int index = indexOf(name);
return index == -1 ? NULL : removeTerm(index);
}
LinguisticTerm* LinguisticVariable::firstTerm() const {
return numberOfTerms() > 0 ? term(0) : NULL;
}
LinguisticTerm* LinguisticVariable::lastTerm() const {
return numberOfTerms() > 0 ? term(numberOfTerms() - 1) : NULL;
}
bool LinguisticVariable::isEmpty() const {
return numberOfTerms() == 0;
}
int LinguisticVariable::numberOfTerms() const {
return _terms.size();
}
flScalar LinguisticVariable::minimum() const {
return numberOfTerms() == 0 ? NAN : firstTerm()->minimum();
}
flScalar LinguisticVariable::maximum() const {
return numberOfTerms() == 0 ? NAN : lastTerm()->maximum();
}
CompoundTerm LinguisticVariable::compound() const {
CompoundTerm result("Accumulated " + name(), minimum(), maximum());
for (int i = 0; i < numberOfTerms(); ++i) {
result.addTerm(*term(i));
}
return result;
}
std::string LinguisticVariable::fuzzify(flScalar crisp) const {
std::vector<std::string> fuzzyness;
for (int i = 0; i < numberOfTerms(); ++i) {
flScalar degree = term(i)->membership(crisp);
fuzzyness.push_back(StrOp::ScalarToString(degree) + "/"
+ term(i)->name());
}
// StringOperator::sort(fuzzyness, false);
std::string result;
for (size_t i = 0; i < fuzzyness.size(); ++i) {
result += fuzzyness[i] + (i < fuzzyness.size() - 1 ? " + " : "");
}
return result;
}
LinguisticTerm* LinguisticVariable::bestFuzzyApproximation(flScalar crisp) {
LinguisticTerm* result = NULL;
flScalar highest_degree = -1.0;
for (int i = 0; i < numberOfTerms(); ++i) {
flScalar degree = term(i)->membership(crisp);
if (degree > highest_degree) {
result = term(i);
highest_degree = degree;
}
}
return result;
}
void LinguisticVariable::createTerms(int number_of_terms,
LinguisticTerm::eMembershipFunction mf, flScalar min, flScalar max,
const std::vector<std::string>& labels) {
std::vector<std::string> final_labels;
for (int i = 0; i < number_of_terms; ++i) {
if ((int) labels.size() <= i) {
final_labels.push_back(name() + "-" + StrOp::IntToString(i + 1));
} else {
final_labels.push_back(labels[i]);
}
}
fl::flScalar intersection = NAN; //Proportion of intersection between terms
if (mf == LinguisticTerm::MF_TRAPEZOIDAL) {
intersection = 4.0 / 5.0;
} else {
intersection = 0.5;
}
//TODO: What is the intersection in other terms?
fl::flScalar term_range = (max - min) / (number_of_terms - number_of_terms / 2);
fl::flScalar current_step = min + (1 - intersection) * term_range;
for (int i = 0; i < number_of_terms; ++i) {
fl::LinguisticTerm* term = NULL;
switch (mf) {
case LinguisticTerm::MF_TRIANGULAR:
term = new fl::TriangularTerm(final_labels.at(i),
current_step - (1 - intersection) * term_range,
current_step + intersection * term_range);
break;
case LinguisticTerm::MF_SHOULDER:
if (i == 0 || i == number_of_terms - 1) {
term = new fl::ShoulderTerm(final_labels[i],
current_step - (1 - intersection) * term_range,
current_step + intersection * term_range, i == 0);
} else {
term = new fl::TriangularTerm(final_labels.at(i),
current_step - (1 - intersection) * term_range,
current_step + intersection * term_range);
}
break;
case LinguisticTerm::MF_TRAPEZOIDAL:
term = new fl::TrapezoidalTerm(final_labels.at(i),
current_step - (1 - intersection) * term_range,
current_step + intersection * term_range);
// term = new fl::TriangularTerm(final_labels.at(i), current_step
// - (1 - intersection) * term_range, current_step + intersection
// * term_range);
break;
default:
throw fl::InvalidArgumentException(FL_AT, "Invalid option for membership function");
}
current_step += intersection * term_range;
addTerm(term);
}
}
std::string LinguisticVariable::toString() const {
std::string result(name());
result += "={ ";
for (int i = 0; i < numberOfTerms(); ++i) {
result += term(i)->name() + " ";
}
result += "}";
return result;
}
}

View File

@ -0,0 +1,83 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: LinguisticVariable.h
* Author: jcrada
*
* Created on November 1, 2009, 1:56 PM
*/
#ifndef FL_LINGUISTICVARIABLE_H
#define FL_LINGUISTICVARIABLE_H
#include <string>
#include <vector>
#include "LinguisticTerm.h"
#include "FuzzyExceptions.h"
#include "defs.h"
#include "CompoundTerm.h"
namespace fl {
class LinguisticVariable {
private:
const FuzzyOperator* _fuzzy_operator;
std::string _name;
std::vector<LinguisticTerm*> _terms;
protected:
virtual int positionFor(const LinguisticTerm* term);
public:
LinguisticVariable();
LinguisticVariable(const std::string& name);
LinguisticVariable(const FuzzyOperator& fuzzy_op, const std::string& name);
virtual ~LinguisticVariable();
virtual std::string name() const;
virtual void setName(const std::string& name);
virtual void setFuzzyOperator(const FuzzyOperator& fuzzy_op);
virtual const FuzzyOperator& fuzzyOperator() const;
virtual void addTerm(LinguisticTerm* term);
virtual LinguisticTerm* term(int index) const;
virtual LinguisticTerm* term(const std::string& name) const;
virtual int indexOf(const std::string& name) const;
virtual LinguisticTerm* removeTerm(int index);
virtual LinguisticTerm* removeTerm(const std::string& name);
virtual LinguisticTerm* firstTerm() const;
virtual LinguisticTerm* lastTerm() const;
virtual bool isEmpty() const;
virtual int numberOfTerms() const;
virtual void createTerms(int number_of_terms, LinguisticTerm::eMembershipFunction mf,
flScalar min, flScalar max,
const std::vector<std::string>& labels = std::vector<std::string>());
virtual flScalar minimum() const;
virtual flScalar maximum() const;
virtual CompoundTerm compound() const;
virtual std::string fuzzify(flScalar crisp) const;
virtual LinguisticTerm* bestFuzzyApproximation(flScalar crisp);
virtual std::string toString() const;
};
}
#endif /* FL_LINGUISTICVARIABLE_H */

View File

@ -0,0 +1,152 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "MamdaniConsequent.h"
#include "FuzzyRule.h"
#include <stdlib.h>
#include "StrOp.h"
namespace fl {
MamdaniConsequent::MamdaniConsequent() : _term(NULL) {
}
MamdaniConsequent::~MamdaniConsequent() {
}
void MamdaniConsequent::setTerm(const LinguisticTerm* term) {
this->_term = term;
}
const LinguisticTerm* MamdaniConsequent::term() const {
return this->_term;
}
void MamdaniConsequent::addHedge(Hedge* hedge) {
this->_hedges.push_back(hedge);
}
Hedge* MamdaniConsequent::hedge(int index) const {
return _hedges[index];
}
int MamdaniConsequent::numberOfHedges() const {
return _hedges.size();
}
void MamdaniConsequent::execute(flScalar degree) {
LinguisticTerm* rule_output = term()->clone();
flScalar modulation = degree * weight();
for (int i = 0; i < numberOfHedges(); ++i) {
modulation = hedge(i)->hedge(modulation);
}
rule_output->setModulation(modulation);
outputLVar()->output().addTerm(*rule_output);
delete rule_output;
}
std::string MamdaniConsequent::toString() const {
std::stringstream ss;
ss << outputLVar()->name() << " " << FuzzyRule::FR_IS;
for (int i = 0; i < numberOfHedges(); ++i) {
ss << " " << hedge(i)->name();
}
ss << " " << term()->name();
if (weight() < flScalar(1.0)) {
ss << " " + FuzzyRule::FR_WITH + " " << weight();
}
return ss.str();
}
void MamdaniConsequent::parse(const std::string& consequent,
const FuzzyEngine& engine) throw (ParsingException) {
std::stringstream ss(consequent);
std::string token;
enum e_state {
S_LVAR = 1, S_IS, S_HEDGE, S_TERM, S_WITH, S_WEIGHT, S_END
};
e_state current_state = S_LVAR;
OutputLVar* output = NULL;
LinguisticTerm* term = NULL;
std::vector<Hedge*> hedges;
Hedge* hedge = NULL;
while (ss >> token) {
switch (current_state) {
case S_LVAR:
output = engine.outputLVar(token);
if (!output) {
throw ParsingException(FL_AT, "Output variable <" +
token + "> not registered in fuzzy engine");
}
current_state = S_IS;
break;
case S_IS:
if (token == FuzzyRule::FR_IS) {
current_state = S_HEDGE;
} else {
throw ParsingException(FL_AT, "<" + FuzzyRule::FR_IS + "> expected but found <" +
token + ">");
}
break;
case S_HEDGE:
hedge = engine.hedgeSet().get(token);
if (hedge) {
hedges.push_back(hedge); //And check for more hedges
break;
}
//intentional fall-through if a term follows
case S_TERM:
term = output->term(token);
if (!term) {
throw ParsingException(FL_AT, "Term <" + token +
"> not found in output variable <" + output->name() + ">");
}
setOutputLVar(output);
setTerm(term);
for (size_t i = 0; i < hedges.size(); ++i) {
addHedge(hedges[i]);
}
setWeight(1.0);
current_state = S_WITH;
break;
case S_WITH:
if (token != FuzzyRule::FR_WITH) {
throw ParsingException(FL_AT, "<" + FuzzyRule::FR_WITH + "> expected but found <"
+ token + ">");
}
current_state = S_WEIGHT;
break;
case S_WEIGHT:
setWeight(atof(token.c_str()));
if (weight() > 1.0){
throw ParsingException(FL_AT, "Weight [0.0, 1.0] expected but found <" +
StrOp::ScalarToString(weight()) + ">");
}
current_state = S_END;
break;
case S_END:
throw ParsingException(FL_AT, "End of line expected but found <" + token + ">");
}
}
if (current_state == S_WEIGHT){
throw ParsingException(FL_AT, "Weight [0.0, 1.0] expected after <" + FuzzyRule::FR_WITH +
"> but found nothing");
}
}
}

View File

@ -0,0 +1,60 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: MamdaniConsequent.h
* Author: jcrada
*
* Created on March 3, 2010, 12:17 AM
*/
#ifndef FL_MAMDANICONSEQUENT_H
#define FL_MAMDANICONSEQUENT_H
#include "FuzzyConsequent.h"
#include "LinguisticTerm.h"
#include "Hedge.h"
#include <vector>
#include "FuzzyExceptions.h"
#include "FuzzyEngine.h"
namespace fl {
class MamdaniConsequent : public FuzzyConsequent {
private:
const LinguisticTerm* _term;
std::vector<Hedge*> _hedges;
public:
MamdaniConsequent();
virtual ~MamdaniConsequent();
virtual void setTerm(const LinguisticTerm* term);
virtual const LinguisticTerm* term() const;
virtual void addHedge(Hedge* hedge);
virtual Hedge* hedge(int index) const ;
virtual int numberOfHedges() const;
//Override
virtual void execute(flScalar degree);
virtual std::string toString() const;
virtual void parse(const std::string& consequent,
const FuzzyEngine& engine) throw (ParsingException) ;
};
}
#endif /* FL_MAMDANICONSEQUENT_H */

View File

@ -0,0 +1,67 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "MamdaniRule.h"
#include "defs.h"
#include "StrOp.h"
#include "FuzzyOperator.h"
#include <sstream>
#include <stack>
#include "DescriptiveAntecedent.h"
#include "MamdaniConsequent.h"
namespace fl {
MamdaniRule::MamdaniRule()
: FuzzyRule() {
}
MamdaniRule::MamdaniRule(const std::string& rule, const FuzzyEngine& engine)
: FuzzyRule() {
try{
parse(rule,engine);
}catch(ParsingException& e){
FL_LOG(e.toString());
}
}
MamdaniRule::~MamdaniRule() {
}
void MamdaniRule::parse(const std::string& rule, const FuzzyEngine& engine) throw (ParsingException) {
std::string str_antecedent, str_consequent;
ExtractFromRule(rule, str_antecedent, str_consequent);
DescriptiveAntecedent* obj_antecedent = new DescriptiveAntecedent;
obj_antecedent->parse(str_antecedent, engine);
setAntecedent(obj_antecedent);
std::vector<std::string> consequents = StrOp::SplitByWord(str_consequent, FuzzyRule::FR_AND);
MamdaniConsequent* obj_consequent = NULL;
for (size_t i = 0; i < consequents.size(); ++i) {
obj_consequent = new MamdaniConsequent;
try {
obj_consequent->parse(consequents[i], engine);
} catch (ParsingException& e) {
delete obj_consequent;
throw e;
}
addConsequent(obj_consequent);
}
}
}

View File

@ -0,0 +1,42 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: MamdaniRule.h
* Author: jcrada
*
* Created on November 5, 2009, 11:15 AM
*/
#ifndef FL_MAMDANIRULE_H
#define FL_MAMDANIRULE_H
#include "FuzzyRule.h"
namespace fl {
class MamdaniRule : public FuzzyRule {
public:
MamdaniRule();
MamdaniRule(const std::string& rule, const FuzzyEngine& engine);
virtual ~MamdaniRule();
virtual void parse(const std::string& rule, const FuzzyEngine& engine) throw (ParsingException);
};
}
#endif /* FL_MAMDANIRULE_H */

View File

@ -0,0 +1,36 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "OutputLVar.h"
namespace fl {
OutputLVar::OutputLVar() : LinguisticVariable(),
_output(new CompoundTerm("output")){
}
OutputLVar::OutputLVar(const std::string& name) : LinguisticVariable(name),
_output(new CompoundTerm("output")) {
}
OutputLVar::~OutputLVar() {
delete _output;
}
CompoundTerm& OutputLVar::output() const {
return *this->_output;
}
}

44
AI/FuzzyLite/OutputLVar.h Normal file
View File

@ -0,0 +1,44 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: OutputLVar.h
* Author: jcrada
*
* Created on November 1, 2009, 2:30 PM
*/
#ifndef FL_OUTPUTLVAR_H
#define FL_OUTPUTLVAR_H
#include "LinguisticVariable.h"
#include "CompoundTerm.h"
namespace fl {
class OutputLVar : public LinguisticVariable {
private:
CompoundTerm* _output;
public:
OutputLVar();
OutputLVar(const std::string& name);
virtual ~OutputLVar();
virtual CompoundTerm& output() const;
};
}
#endif /* FL_OUTPUTLVAR_H */

View File

@ -0,0 +1,69 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* RectangularTerm.cpp
*
* Created on: Jan 7, 2010
* Author: jcrada
*/
#include "RectangularTerm.h"
namespace fl {
RectangularTerm::RectangularTerm() :
LinguisticTerm() {
}
RectangularTerm::RectangularTerm(const std::string& name, flScalar minimum,
flScalar maximum) :
LinguisticTerm(name, minimum, maximum) {
}
RectangularTerm::RectangularTerm(const FuzzyOperator& fuzzy_op,
const std::string& name, flScalar minimum, flScalar maximum) :
LinguisticTerm(fuzzy_op, name, minimum, maximum) {
}
RectangularTerm::~RectangularTerm() {
}
RectangularTerm* RectangularTerm::clone() const {
return new RectangularTerm(*this);
}
flScalar RectangularTerm::membership(flScalar crisp) const {
if (crisp > maximum() || crisp < minimum()) {
return flScalar(0.0);
}
return fuzzyOperator().modulation().execute(1.0, modulation());
}
LinguisticTerm::eMembershipFunction RectangularTerm::type() const {
return MF_RECTANGULAR;
}
std::string RectangularTerm::toString() const {
std::stringstream ss;
ss << LinguisticTerm::toString();
ss << "Rectangular (" << minimum() << " " << maximum() << ")";
return ss.str();
}
} // namespace fl

View File

@ -0,0 +1,49 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* RectangularTerm.h
*
* Created on: Jan 7, 2010
* Author: jcrada
*/
#ifndef FL_RECTANGULARTERM_H_
#define FL_RECTANGULARTERM_H_
#include "LinguisticTerm.h"
namespace fl {
class RectangularTerm : public LinguisticTerm {
public:
RectangularTerm();
RectangularTerm(const std::string& name, flScalar minimum = -INFINITY,
flScalar maximum = INFINITY);
RectangularTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
flScalar minimum = -INFINITY, flScalar maximum = INFINITY);
virtual ~RectangularTerm();
virtual RectangularTerm* clone() const;
virtual flScalar membership(flScalar crisp) const;
virtual eMembershipFunction type() const;
virtual std::string toString() const;
};
} // namespace fl
#endif /* FL_RECTANGULARTERM_H_ */

View File

@ -0,0 +1,94 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "RuleBlock.h"
#include "FuzzyRule.h"
#include <iosfwd>
namespace fl {
RuleBlock::RuleBlock(const std::string& name)
: _name(name) {
setFuzzyOperator(FuzzyOperator::DefaultFuzzyOperator());
}
RuleBlock::RuleBlock(const std::string& name, const FuzzyOperator& fuzzy_operator)
: _name(name), _fuzzy_operator(&fuzzy_operator) {
}
RuleBlock::~RuleBlock() {
reset();
}
void RuleBlock::setName(const std::string& name) {
this->_name = name;
}
std::string RuleBlock::name() const {
return this->_name;
}
FuzzyRule* RuleBlock::rule(int index) const {
return this->_rules[index];
}
void RuleBlock::addRule(FuzzyRule* rule) {
this->_rules.push_back(rule);
}
FuzzyRule* RuleBlock::removeRule(int index) {
FuzzyRule* result = rule(index);
this->_rules.erase(this->_rules.begin() + index);
return result;
}
int RuleBlock::numberOfRules() const {
return this->_rules.size();
}
const FuzzyOperator& RuleBlock::fuzzyOperator() const {
return *this->_fuzzy_operator;
}
void RuleBlock::setFuzzyOperator(const FuzzyOperator& fuzzy_op) {
this->_fuzzy_operator = &fuzzy_op;
for (int i = 0; i < numberOfRules(); ++i) {
rule(i)->setFuzzyOperator(fuzzy_op);
}
}
void RuleBlock::fireRules() {
for (int i = 0; i < numberOfRules(); ++i) {
rule(i)->fire(rule(i)->firingStrength());
}
}
void RuleBlock::reset() {
for (int i = numberOfRules() - 1; i >= 0; --i) {
delete removeRule(i);
}
}
std::string RuleBlock::toString() const{
std::stringstream ss;
ss << "RULEBLOCK " << name() << "\n";
for (int i = 0 ; i < numberOfRules() ; ++i){
ss << " RULE " << i + 1 << ": " << rule(i)->toString() << ";\n";
}
ss << "END_RULEBLOCK";
return ss.str();
}
}

61
AI/FuzzyLite/RuleBlock.h Normal file
View File

@ -0,0 +1,61 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* RuleBlock.h
*
* Created on: Jan 2, 2010
* Author: jcrada
*/
#ifndef FL_RULEBLOCK_H_
#define FL_RULEBLOCK_H_
#include "FuzzyOperator.h"
#include <vector>
#include <string>
namespace fl {
class FuzzyRule;
class RuleBlock {
private:
std::string _name;
const FuzzyOperator* _fuzzy_operator;
std::vector<FuzzyRule*> _rules;
public:
RuleBlock(const std::string& name = "");
RuleBlock(const std::string& name, const FuzzyOperator& fuzzy_operator);
virtual ~RuleBlock();
virtual void setName(const std::string& name);
virtual std::string name() const;
virtual FuzzyRule* rule(int index) const;
virtual void addRule(FuzzyRule* rule);
virtual FuzzyRule* removeRule(int index);
virtual int numberOfRules() const;
virtual const FuzzyOperator& fuzzyOperator() const;
virtual void setFuzzyOperator(const FuzzyOperator& fuzzy_op);
virtual void fireRules();
virtual void reset();
virtual std::string toString() const;
};
} // namespace fl
#endif /* FL_RULEBLOCK_H_ */

View File

@ -0,0 +1,133 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* ShoulderTerm.cpp
*
* Created on: Dec 13, 2009
* Author: jcrada
*/
#include "ShoulderTerm.h"
namespace fl {
ShoulderTerm::ShoulderTerm() :
LinguisticTerm(), _left(true) {
}
ShoulderTerm::ShoulderTerm(const std::string& name, flScalar minimum,
flScalar maximum, bool left) :
LinguisticTerm(name, minimum, maximum), _left(left) {
}
ShoulderTerm::ShoulderTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
flScalar minimum, flScalar maximum, bool left) :
LinguisticTerm(fuzzy_op, name, minimum, maximum), _left(left) {
}
ShoulderTerm::~ShoulderTerm() {
}
void ShoulderTerm::setLeft(bool left) {
this->_left = left;
}
bool ShoulderTerm::isLeft() const {
return this->_left;
}
void ShoulderTerm::setRight(bool right) {
this->_left = !right;
}
bool ShoulderTerm::isRight() const {
return !this->_left;
}
ShoulderTerm* ShoulderTerm::clone() const {
return new ShoulderTerm(*this);
}
flScalar ShoulderTerm::membership(flScalar crisp) const {
if (isLeft()) {
if (crisp < minimum())
return flScalar(1.0);
if (crisp > maximum())
return flScalar(0.0);
return FuzzyOperation::Scale(minimum(), maximum(), crisp, 1, 0);
} else {
if (crisp < minimum())
return flScalar(0.0);
if (crisp > maximum())
return flScalar(1.0);
return FuzzyOperation::Scale(minimum(), maximum(), crisp, 0, 1);
}
}
LinguisticTerm::eMembershipFunction ShoulderTerm::type() const {
return MF_SHOULDER;
}
std::string ShoulderTerm::toString() const {
std::stringstream ss;
ss << LinguisticTerm::toString();
ss << "Shoulder " << (isLeft() ? "left" : "right") << "(" << minimum() << " " << maximum() << ")";
return ss.str();
}
//**********Right and left...
RightShoulderTerm::RightShoulderTerm() : ShoulderTerm() {
setRight(true);
}
RightShoulderTerm::RightShoulderTerm(const std::string& name, flScalar minimum, flScalar maximum)
: ShoulderTerm(name, minimum, maximum) {
setRight(true);
}
RightShoulderTerm::RightShoulderTerm(const FuzzyOperator& fuzzy_op, const std::string& name, flScalar minimum, flScalar maximum)
: ShoulderTerm(fuzzy_op, name, minimum, maximum) {
setRight(true);
}
RightShoulderTerm::~RightShoulderTerm() {
}
LeftShoulderTerm::LeftShoulderTerm() : ShoulderTerm() {
setLeft(true);
}
LeftShoulderTerm::LeftShoulderTerm(const std::string& name, flScalar minimum, flScalar maximum)
: ShoulderTerm(name, minimum, maximum) {
setLeft(true);
}
LeftShoulderTerm::LeftShoulderTerm(const FuzzyOperator& fuzzy_op, const std::string& name, flScalar minimum, flScalar maximum)
: ShoulderTerm(fuzzy_op, name, minimum, maximum) {
setLeft(true);
}
LeftShoulderTerm::~LeftShoulderTerm() {
}
} // namespace fuzzy_lite

View File

@ -0,0 +1,77 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* ShoulderTerm.h
*
* Created on: Dec 13, 2009
* Author: jcrada
*/
#ifndef FL_SHOULDERTERM_H_
#define FL_SHOULDERTERM_H_
#include "LinguisticTerm.h"
#include <math.h>
namespace fl {
class ShoulderTerm : public LinguisticTerm {
private:
bool _left;
public:
ShoulderTerm();
ShoulderTerm(const std::string& name, flScalar minimum = -INFINITY,
flScalar maximum = INFINITY, bool left = true);
ShoulderTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
flScalar minimum = -INFINITY, flScalar maximum = INFINITY, bool left = true);
virtual ~ShoulderTerm();
virtual void setLeft(bool left);
virtual bool isLeft() const;
virtual void setRight(bool right);
virtual bool isRight() const;
virtual ShoulderTerm* clone() const;
virtual flScalar membership(flScalar crisp) const;
virtual eMembershipFunction type() const;
virtual std::string toString() const;
};
class RightShoulderTerm : public ShoulderTerm{
public:
RightShoulderTerm();
RightShoulderTerm(const std::string& name, flScalar minimum = -INFINITY,
flScalar maximum = INFINITY);
RightShoulderTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
flScalar minimum = -INFINITY, flScalar maximum = INFINITY);
virtual ~RightShoulderTerm();
};
class LeftShoulderTerm : public ShoulderTerm{
public:
LeftShoulderTerm();
LeftShoulderTerm(const std::string& name, flScalar minimum = -INFINITY,
flScalar maximum = INFINITY);
LeftShoulderTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
flScalar minimum = -INFINITY, flScalar maximum = INFINITY);
virtual ~LeftShoulderTerm();
};
} // namespace fuzzy_lite
#endif /* FL_SHOULDERTERM_H_ */

View File

@ -0,0 +1,77 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* SingletonTerm.cpp
*
* Created on: Jan 7, 2010
* Author: jcrada
*/
#include "SingletonTerm.h"
namespace fl {
SingletonTerm::SingletonTerm() :
LinguisticTerm() {
}
SingletonTerm::SingletonTerm(const std::string& name, flScalar value) :
LinguisticTerm(name, value - 5 * FL_EPSILON, value + 5 * FL_EPSILON), _value(value) {
}
SingletonTerm::SingletonTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
flScalar value) :
LinguisticTerm(fuzzy_op, name, value - 5 * FL_EPSILON, value + 5 * FL_EPSILON), _value(
value) {
}
SingletonTerm::~SingletonTerm() {
}
void SingletonTerm::setValue(flScalar value) {
this->_value = value;
setMinimum(value - 5 * FL_EPSILON);
setMaximum(value + 5 * FL_EPSILON);
}
flScalar SingletonTerm::value() const {
return this->_value;
}
SingletonTerm* SingletonTerm::clone() const {
return new SingletonTerm(*this);
}
flScalar SingletonTerm::membership(flScalar crisp) const {
return fuzzyOperator().modulation().execute(modulation(), FuzzyOperation::IsEq(crisp, value())
? flScalar(1.0) : flScalar(0.0));
}
LinguisticTerm::eMembershipFunction SingletonTerm::type() const {
return MF_SINGLETON;
}
std::string SingletonTerm::toString() const {
std::stringstream ss;
ss << LinguisticTerm::toString();
ss << "Singleton (" << value() << ")";
return ss.str();
}
} // namespace fl

View File

@ -0,0 +1,52 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* SingletonTerm.h
*
* Created on: Jan 7, 2010
* Author: jcrada
*/
#ifndef FL_SINGLETONTERM_H_
#define FL_SINGLETONTERM_H_
#include "LinguisticTerm.h"
namespace fl {
class SingletonTerm : public LinguisticTerm {
private:
flScalar _value;
public:
SingletonTerm();
SingletonTerm(const std::string& name, flScalar value = NAN);
SingletonTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
flScalar value = NAN);
virtual ~SingletonTerm();
virtual void setValue(flScalar value);
virtual flScalar value() const;
virtual SingletonTerm* clone() const;
virtual flScalar membership(flScalar crisp) const;
virtual eMembershipFunction type() const;
virtual std::string toString() const;
};
} // namespace fl
#endif /* FL_SINGLETONTERM_H_ */

149
AI/FuzzyLite/StrOp.cpp Normal file
View File

@ -0,0 +1,149 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "StrOp.h"
#include <iomanip>
#include <sstream>
#include <algorithm>
#include <iosfwd>
namespace fl {
bool StrOp::AscendantSorter(const std::string &left, const std::string &right) {
for (std::string::const_iterator lit = left.begin(), rit = right.begin();
lit != left.end() && rit != right.end();
++lit, ++rit) {
if (tolower(*lit) < tolower(*rit))
return true;
else if (tolower(*lit) > tolower(*rit))
return false;
}
if (left.size() < right.size()) {
return true;
}
return false;
}
bool StrOp::DescendantSorter(const std::string &left, const std::string &right) {
for (std::string::const_iterator lit = left.begin(), rit = right.begin();
lit != left.end() && rit != right.end();
++lit, ++rit) {
if (tolower(*lit) < tolower(*rit))
return false;
else if (tolower(*lit) > tolower(*rit))
return true;
}
if (left.size() < right.size()) {
return false;
}
return true;
}
void StrOp::LeftTrim(std::string& text) {
text.erase(text.begin(), text.begin() + text.find_first_not_of(" "));
}
void StrOp::RightTrim(std::string& text) {
text.erase(text.find_last_not_of(" ") + 1);
}
void StrOp::Trim(std::string& text) {
RightTrim(text);
LeftTrim(text);
}
// std::string StrOp::Substring(const std::string& text,
// const std::string substring) throw (OutOfRangeException) {
// int index = text.find_last_of(substring) - substring.size();
// OutOfRangeException::CheckArray(FL_AT, index, text.size());
// return text.substr(index);
// }
std::string StrOp::IntToString(int value) {
std::stringstream ss;
ss << value;
return ss.str();
}
std::string StrOp::ScalarToString(flScalar value, int precision) {
std::stringstream ss;
ss << std::fixed << std::setprecision(precision) << value;
return ss.str();
}
void StrOp::Sort(std::vector<std::string>& vector, bool asc) {
std::sort(vector.begin(), vector.end(), (asc ? AscendantSorter : DescendantSorter));
}
std::vector<std::string> StrOp::Tokenize(const std::string& str, const std::string delimiters) {
std::vector<std::string> result;
std::string::size_type last_pos = str.find_first_not_of(delimiters, 0);
// Find first "non-delimiter".
std::string::size_type pos = str.find_first_of(delimiters, last_pos);
while (std::string::npos != pos || std::string::npos != last_pos) {
// Found a token, add it to the vector.
result.push_back(str.substr(last_pos, pos - last_pos));
// Skip delimiters. Note the "not_of"
last_pos = str.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
pos = str.find_first_of(delimiters, last_pos);
}
return result;
}
std::vector<std::string> StrOp::SplitByWord(const std::string& str, const std::string word) {
std::vector<std::string> result;
std::stringstream ss(str);
std::string accum_token;
std::string token;
while (ss >> token) {
if (token == word) {
if (accum_token != "") {
result.push_back(accum_token);
}
accum_token = "";
} else {
accum_token += " " + token;
}
}
if (accum_token != "") {
result.push_back(accum_token);
}
return result;
}
int StrOp::FindReplace(std::string& str, const std::string& find,
const std::string& replace, bool all) {
if (find.length() == 0) return 0;
int result = 0;
size_t index = -abs((int)(find.length() - replace.length()));
do {
index = str.find(find, index + abs((int)(find.length() - replace.length())));
if (index != std::string::npos) {
str.replace(index, find.length(), replace);
++result;
}
} while (all && index != std::string::npos);
return result;
}
void StrOp::main(int argc, char** argv) {
std::string x = "Esto es= que y=o diga t=d=o= sin ='s =D";
FL_LOG(x);
FindReplace(x,"="," = ");
FL_LOG(x);
}
}

63
AI/FuzzyLite/StrOp.h Normal file
View File

@ -0,0 +1,63 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: StrOp.h
* Author: jcrada
*
* Created on November 5, 2009, 12:23 PM
*/
#ifndef FL_STROP_H
#define FL_STROP_H
#include "defs.h"
#include "flScalar.h"
#include "FuzzyExceptions.h"
#include <string>
#include <vector>
namespace fl {
class StrOp {
protected:
static bool AscendantSorter(const std::string &left, const std::string &right);
static bool DescendantSorter(const std::string &left, const std::string &right);
public:
static void LeftTrim(std::string& text);
static void RightTrim(std::string& text);
static void Trim(std::string& text);
// static std::string Substring(const std::string& text,
// const std::string substring) throw (OutOfRangeException);
static std::string IntToString(int value) ;
static std::string ScalarToString(flScalar value, int precision = 3);
static void Sort(std::vector<std::string>& vector, bool asc = true);
static std::vector<std::string> Tokenize(const std::string& str, const std::string delimiter = " ");
static std::vector<std::string> SplitByWord(const std::string& str, const std::string word);
static int FindReplace(std::string& str, const std::string& find, const std::string& replace, bool all = true);
static void main(int args, char** argv);
};
}
#endif /* FL_STROP_H */

View File

@ -0,0 +1,121 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "TakagiSugenoConsequent.h"
#include <stack>
#include <iosfwd>
#include "FunctionTerm.h"
#include "SingletonTerm.h"
#include "TakagiSugenoTerm.h"
namespace fl {
TakagiSugenoConsequent::TakagiSugenoConsequent() {
_infix2postfix.loadMathOperators();
}
TakagiSugenoConsequent::~TakagiSugenoConsequent() {
}
const FuzzyEngine& TakagiSugenoConsequent::fuzzyEngine() const {
return *this->_fuzzy_engine;
}
void TakagiSugenoConsequent::setFuzzyEngine(const FuzzyEngine& fuzzy_engine) {
this->_fuzzy_engine = &fuzzy_engine;
}
std::string TakagiSugenoConsequent::consequent() const {
return this->_consequent;
}
void TakagiSugenoConsequent::setConsequent(const std::string& consequent) {
this->_consequent = consequent;
}
std::string TakagiSugenoConsequent::postfixFunction() const {
return this->_postfix_function;
}
void TakagiSugenoConsequent::setPostfixFunction(const std::string& postfix) {
this->_postfix_function = postfix;
}
void TakagiSugenoConsequent::parse(const std::string& consequent,
const FuzzyEngine& engine) throw (ParsingException) {
setFuzzyEngine(engine);
setConsequent(consequent);
std::stringstream ss(consequent);
std::string output_lvar;
ss >> output_lvar;
if (!fuzzyEngine().outputLVar(output_lvar)) {
throw ParsingException(FL_AT, "Output variable <" + output_lvar +
"> not found in fuzzy engine");
}
setOutputLVar(fuzzyEngine().outputLVar(output_lvar));
std::string equal;
ss >> equal;
if (equal != "=") {
throw ParsingException(FL_AT, "<=> expected but found <" + equal + ">");
}
std::string right_side;
std::string token;
while (ss >> token) {
right_side += token + " ";
}
setPostfixFunction(_infix2postfix.transform(right_side));
std::map<std::string, flScalar> variables;
for (int i = 0; i < fuzzyEngine().numberOfInputLVars(); ++i) {
variables[fuzzyEngine().inputLVar(i)->name()] =
fuzzyEngine().inputLVar(i)->input();
}
for (int i = 0; i < fuzzyEngine().numberOfOutputLVars(); ++i) {
variables[fuzzyEngine().outputLVar(i)->name()] =
fuzzyEngine().outputLVar(i)->output().defuzzify();
}
try {
_infix2postfix.evaluate(postfixFunction(), &variables);
} catch (FuzzyException& e) {
throw ParsingException(FL_AT, e.message(), e);
}
}
void TakagiSugenoConsequent::execute(flScalar degree) {
std::map<std::string, flScalar> variables;
for (int i = 0; i < fuzzyEngine().numberOfInputLVars(); ++i) {
variables[fuzzyEngine().inputLVar(i)->name()] =
fuzzyEngine().inputLVar(i)->input();
}
for (int i = 0; i < fuzzyEngine().numberOfOutputLVars(); ++i) {
variables[fuzzyEngine().outputLVar(i)->name()] =
fuzzyEngine().outputLVar(i)->output().defuzzify();
}
TakagiSugenoTerm result(fuzzyEngine().fuzzyOperator(), postfixFunction());
result.setValue(_infix2postfix.evaluate(postfixFunction(), &variables));
result.setWeight(degree);
outputLVar()->output().addTerm(result);
}
std::string TakagiSugenoConsequent::toString() const {
return consequent();
}
void TakagiSugenoConsequent::main(int args, char** argv) {
}
}

View File

@ -0,0 +1,64 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: TakagiSugenoConsequent.h
* Author: jcrada
*
* Created on March 4, 2010, 12:18 AM
*/
#ifndef FL_TAKAGISUGENOCONSEQUENT_H
#define FL_TAKAGISUGENOCONSEQUENT_H
#include "FuzzyConsequent.h"
#include "InfixToPostfix.h"
namespace fl {
class TakagiSugenoConsequent : public FuzzyConsequent {
private:
const FuzzyEngine* _fuzzy_engine;
std::string _consequent;
std::string _postfix_function;
InfixToPostfix _infix2postfix;
protected:
const FuzzyEngine& fuzzyEngine() const;
void setFuzzyEngine(const FuzzyEngine& fuzzy_engine);
std::string consequent() const;
void setConsequent(const std::string& consequent);
std::string postfixFunction() const;
void setPostfixFunction(const std::string& postfix);
public:
TakagiSugenoConsequent();
virtual ~TakagiSugenoConsequent();
virtual void parse(const std::string& consequent,
const FuzzyEngine& engine) throw (ParsingException);
virtual void execute(flScalar degree);
virtual std::string toString() const;
static void main(int args, char** argv);
};
}
#endif /* FL_TAKAGISUGENOCONSEQUENT_H */

View File

@ -0,0 +1,63 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "TakagiSugenoRule.h"
#include "TakagiSugenoConsequent.h"
#include "DescriptiveAntecedent.h"
#include "StrOp.h"
namespace fl {
TakagiSugenoRule::TakagiSugenoRule() : FuzzyRule() {
}
TakagiSugenoRule::TakagiSugenoRule(const std::string& rule, const FuzzyEngine& engine)
: FuzzyRule() {
try {
parse(rule, engine);
} catch (ParsingException& e) {
FL_LOG(e.toString());
}
}
TakagiSugenoRule::~TakagiSugenoRule() {
}
void TakagiSugenoRule::parse(const std::string& rule, const FuzzyEngine& engine) {
std::string str_antecedent, str_consequent;
ExtractFromRule(rule, str_antecedent, str_consequent);
DescriptiveAntecedent* obj_antecedent = new DescriptiveAntecedent;
obj_antecedent->parse(str_antecedent, engine);
setAntecedent(obj_antecedent);
std::vector<std::string> consequents = StrOp::SplitByWord(str_consequent, FuzzyRule::FR_AND);
TakagiSugenoConsequent* obj_consequent = NULL;
for (size_t i = 0; i < consequents.size(); ++i) {
obj_consequent = new TakagiSugenoConsequent;
try {
std::string x = consequents[i];
StrOp::FindReplace(x,"="," = ");
obj_consequent->parse(x, engine);
} catch (ParsingException& e) {
delete obj_consequent;
throw e;
}
addConsequent(obj_consequent);
}
}
}

View File

@ -0,0 +1,40 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: TakagiSugenoRule.h
* Author: jcrada
*
* Created on March 4, 2010, 12:22 AM
*/
#ifndef FL_TAKAGISUGENORULE_H
#define FL_TAKAGISUGENORULE_H
#include "FuzzyRule.h"
namespace fl {
class TakagiSugenoRule : public FuzzyRule {
public:
TakagiSugenoRule();
TakagiSugenoRule(const std::string& rule, const FuzzyEngine& engine);
virtual ~TakagiSugenoRule();
virtual void parse(const std::string& rule, const FuzzyEngine& engine);
};
}
#endif /* FL_TAKAGISUGENORULE_H */

View File

@ -0,0 +1,61 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "TakagiSugenoTerm.h"
namespace fl {
TakagiSugenoTerm::TakagiSugenoTerm() : SingletonTerm() {
}
TakagiSugenoTerm::TakagiSugenoTerm(const std::string& name, flScalar value,
flScalar weight)
: SingletonTerm(name, value), _weight(weight) {
}
TakagiSugenoTerm::TakagiSugenoTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
flScalar value, flScalar weight)
: SingletonTerm(fuzzy_op, name, value), _weight(weight) {
}
TakagiSugenoTerm::~TakagiSugenoTerm() {
}
void TakagiSugenoTerm::setWeight(flScalar weight) {
this->_weight = weight;
}
flScalar TakagiSugenoTerm::weight() const {
return this->_weight;
}
TakagiSugenoTerm* TakagiSugenoTerm::clone() const {
return new TakagiSugenoTerm(*this);
}
LinguisticTerm::eMembershipFunction TakagiSugenoTerm::type() const {
return MF_TAKAGI_SUGENO;
}
std::string TakagiSugenoTerm::toString() const {
std::stringstream ss;
ss << LinguisticTerm::toString();
ss << "TakagiSugeno (" << value() << " " << weight() << ")";
return ss.str();
}
}

View File

@ -0,0 +1,48 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: TakagiSugenoTerm.h
* Author: jcrada
*
* Created on March 10, 2010, 7:28 PM
*/
#ifndef FL_TAKAGISUGENOTERM_H
#define FL_TAKAGISUGENOTERM_H
#include "SingletonTerm.h"
namespace fl{
class TakagiSugenoTerm : public SingletonTerm{
private:
flScalar _weight;
public:
TakagiSugenoTerm();
TakagiSugenoTerm(const std::string& name, flScalar value = NAN, flScalar weight = 1.0);
TakagiSugenoTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
flScalar value = NAN, flScalar weight = 1.0);
virtual ~TakagiSugenoTerm();
virtual void setWeight(flScalar weight);
virtual flScalar weight() const;
virtual TakagiSugenoTerm* clone() const;
virtual eMembershipFunction type() const;
virtual std::string toString() const;
};
}
#endif /* FL_TAKAGISUGENOTERM_H */

View File

@ -0,0 +1,113 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* TrapezoidalTerm.cpp
*
* Created on: Dec 13, 2009
* Author: jcrada
*/
#include "TrapezoidalTerm.h"
namespace fl {
TrapezoidalTerm::TrapezoidalTerm() :
LinguisticTerm(), _b(0), _c(0) {
}
TrapezoidalTerm::TrapezoidalTerm(const std::string& name, flScalar minimum,
flScalar maximum) :
LinguisticTerm(name, minimum, maximum), _b(0), _c(0) {
setB(minimum + (maximum - minimum) * 1 / 5);
setC(minimum + (maximum - minimum) * 4 / 5);
}
TrapezoidalTerm::TrapezoidalTerm(const FuzzyOperator& fuzzy_op,
const std::string& name, flScalar minimum, flScalar maximum) :
LinguisticTerm(fuzzy_op, name, minimum, maximum), _b(0), _c(0) {
setB(minimum + (maximum - minimum) * 1 / 5);
setC(minimum + (maximum - minimum) * 4 / 5);
}
TrapezoidalTerm::~TrapezoidalTerm() {
}
void TrapezoidalTerm::setA(flScalar a) {
setMinimum(a);
}
flScalar TrapezoidalTerm::a() const {
return minimum();
}
void TrapezoidalTerm::setB(flScalar b) {
this->_b = b;
}
flScalar TrapezoidalTerm::b() const {
return this->_b;
}
void TrapezoidalTerm::setC(flScalar c) {
this->_c = c;
}
flScalar TrapezoidalTerm::c() const {
return this->_c;
}
void TrapezoidalTerm::setD(flScalar d) {
setMaximum(d);
}
flScalar TrapezoidalTerm::d() const {
return maximum();
}
TrapezoidalTerm* TrapezoidalTerm::clone() const {
return new TrapezoidalTerm(*this);
}
flScalar TrapezoidalTerm::membership(flScalar crisp) const {
if (crisp < minimum() || crisp > maximum()) {
return flScalar(0);
}
if (crisp < b()) {
return fuzzyOperator().modulation().execute(modulation(),
FuzzyOperation::Scale(a(), b(), crisp, 0, 1));
}
if (crisp < c()) {
return fuzzyOperator().modulation().execute(modulation(), flScalar(1.0));
}
if (crisp < d()) {
return fuzzyOperator().modulation().execute(modulation(),
FuzzyOperation::Scale(c(), d(), crisp, 1, 0));
}
return flScalar(0.0);
}
LinguisticTerm::eMembershipFunction TrapezoidalTerm::type() const {
return MF_TRAPEZOIDAL;
}
std::string TrapezoidalTerm::toString() const {
std::stringstream ss;
ss << LinguisticTerm::toString();
ss << "Trapezoidal (" << a() << " " << b() << " " << c() << " " << d() << ")";
return ss.str();
}
} // namespace fuzzy_lite

View File

@ -0,0 +1,63 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* TrapezoidalTerm.h
*
* Created on: Dec 13, 2009
* Author: jcrada
*/
#ifndef FL_TRAPEZOIDALTERM_H_
#define FL_TRAPEZOIDALTERM_H_
#include "LinguisticTerm.h"
namespace fl {
class TrapezoidalTerm : public LinguisticTerm {
private:
flScalar _b;
flScalar _c;
public:
TrapezoidalTerm();
TrapezoidalTerm(const std::string& name, flScalar minimum = -INFINITY,
flScalar maximum = INFINITY);
TrapezoidalTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
flScalar minimum = -INFINITY, flScalar maximum = INFINITY);
virtual ~TrapezoidalTerm();
virtual void setA(flScalar a);
virtual flScalar a() const;
virtual void setB(flScalar b);
virtual flScalar b() const;
virtual void setC(flScalar c);
virtual flScalar c() const;
virtual void setD(flScalar d);
virtual flScalar d() const;
virtual TrapezoidalTerm* clone() const;
virtual flScalar membership(flScalar crisp) const;
virtual eMembershipFunction type() const;
virtual std::string toString() const;
};
} // namespace fuzzy_lite
#endif /* FL_TRAPEZOIDALTERM_H_ */

View File

@ -0,0 +1,94 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* TriangularTerm.cpp
*
* Created on: Dec 13, 2009
* Author: jcrada
*/
#include "TriangularTerm.h"
namespace fl {
TriangularTerm::TriangularTerm() :
LinguisticTerm(), _b(0) {
}
TriangularTerm::TriangularTerm(const std::string& name, flScalar minimum,
flScalar maximum) :
LinguisticTerm(name, minimum, maximum), _b((minimum + maximum) / 2) {
}
TriangularTerm::TriangularTerm(const FuzzyOperator& fuzzy_op,
const std::string& name, flScalar minimum, flScalar maximum) :
LinguisticTerm(fuzzy_op, name, minimum, maximum), _b((minimum + maximum) / 2) {
}
TriangularTerm::~TriangularTerm() {
}
void TriangularTerm::setA(flScalar a) {
setMinimum(a);
}
flScalar TriangularTerm::a() const {
return minimum();
}
void TriangularTerm::setB(flScalar b) {
this->_b = b;
}
flScalar TriangularTerm::b() const {
return this->_b;
}
void TriangularTerm::setC(flScalar c) {
setMaximum(c);
}
flScalar TriangularTerm::c() const {
return maximum();
}
TriangularTerm* TriangularTerm::clone() const {
return new TriangularTerm(*this);
}
flScalar TriangularTerm::membership(flScalar crisp) const {
if (crisp > maximum() || crisp < minimum()) {
return flScalar(0.0);
}
flScalar result = crisp < b() ? FuzzyOperation::Scale(a(), b(), crisp, 0, 1)
: FuzzyOperation::Scale(b(), c(), crisp, 1, 0);
return fuzzyOperator().modulation().execute(result, modulation());
}
LinguisticTerm::eMembershipFunction TriangularTerm::type() const {
return MF_TRIANGULAR;
}
std::string TriangularTerm::toString() const {
std::stringstream ss;
ss << LinguisticTerm::toString();
ss << "Triangular (" << a() << " " << b() << " " << c() << ")";
return ss.str();
}
} // namespace fuzzy_lite

View File

@ -0,0 +1,60 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* TriangularTerm.h
*
* Created on: Dec 13, 2009
* Author: jcrada
*/
#ifndef FL_TRIANGULARTERM_H_
#define FL_TRIANGULARTERM_H_
#include "LinguisticTerm.h"
namespace fl {
class TriangularTerm : public LinguisticTerm {
private:
flScalar _b;
public:
TriangularTerm();
TriangularTerm(const std::string& name, flScalar minimum = -INFINITY,
flScalar maximum = INFINITY);
TriangularTerm(const FuzzyOperator& fuzzy_op, const std::string& name,
flScalar minimum = -INFINITY, flScalar maximum = INFINITY);
virtual ~TriangularTerm();
virtual void setA(flScalar a);
virtual flScalar a() const;
virtual void setB(flScalar b);
virtual flScalar b() const;
virtual void setC(flScalar c);
virtual flScalar c() const;
virtual TriangularTerm* clone() const;
virtual flScalar membership(flScalar crisp) const;
virtual eMembershipFunction type() const;
virtual std::string toString() const;
};
} // namespace fuzzy_lite
#endif /* FL_TRIANGULARTERM_H_ */

74
AI/FuzzyLite/defs.h Normal file
View File

@ -0,0 +1,74 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: defs.h
* Author: jcrada
*
* Created on October 30, 2009, 7:09 PM
*/
#ifndef FL_DEFS_H
#define FL_DEFS_H
#include <iostream>
#include <sstream>
#include <assert.h>
namespace fl {
#define FL_AT __FILE__, __LINE__, __FUNCTION__
#ifdef FL_USE_INLINE
#define FL_INLINE inline
#else
#define FL_INLINE
#endif
#ifdef FL_USE_ASSERT
#define FL_ASSERT(assertion) assert(assertion);
#define FL_ASSERTM(value,assertion) if (!(assertion)){FL_LOGM(value);} assert(assertion);
#else
#define FL_ASSERT(assertion)
#define FL_ASSERTM(value,assertion)
#endif
#ifdef FL_USE_LOG
#define FL_LOG_PREFIX __FILE__ << " [" << __LINE__ << "]:"
#define FL_LOG(message) std::cout << FL_LOG_PREFIX << message << std::endl
#define FL_LOGW(message) std::cout << FL_LOG_PREFIX << "WARNING: " << message << std::endl
#else
#define FL_LOG(message)
#define FL_LOGW(message)
#endif
#ifdef FL_USE_DEBUG
#define FL_DEBUG_PREFIX __FILE__ << " [" << __LINE__ << "]::" << __FUNCTION__ << ": "
#define FL_DEBUG(message) std::cout << FL_DEBUG_PREFIX << message << std::endl
#define FL_DEBUGI std::cout << FL_DEBUG_PREFIX << ++FL_DEBUG_COUNTER << std::endl
#else
#define FL_DEBUG(message)
#define FL_DEBUGI
#endif
#ifndef FL_SAMPLE_SIZE
#define FL_SAMPLE_SIZE 100
#endif
}
#endif /* FL_DEFS_H */

37
AI/FuzzyLite/flScalar.h Normal file
View File

@ -0,0 +1,37 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: flScalar.h
* Author: jcrada
*
* Created on October 30, 2009, 7:11 PM
*/
#ifndef FL_FLSCALAR_H
#define FL_FLSCALAR_H
namespace fl {
#ifdef FL_USE_DOUBLE_PRECISION
typedef double flScalar;
#define FL_EPSILON 1e-14
#else
typedef float flScalar;
#define FL_EPSILON 1e-5
#endif
}
#endif /* FL_FLSCALAR_H */

34
AI/FuzzyLite/main.cpp Normal file
View File

@ -0,0 +1,34 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: main.cpp
* Author: jcrada
*
* Created on October 28, 2009, 2:29 PM
*/
#include <stdlib.h>
#include <vector>
#include "FuzzyLite.h"
#include "test.h"
#include <iomanip>
int main(int argc, char** argv) {
FL_LOG(std::fixed << std::setprecision(3));
fl::Test::main(argc, argv);
return (EXIT_SUCCESS);
}

269
AI/FuzzyLite/test.cpp Normal file
View File

@ -0,0 +1,269 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "test.h"
#include "FuzzyLite.h"
#include <limits>
#include "FunctionTerm.h"
namespace fl {
void Test::SimpleMamdani() {
FuzzyOperator& op = FuzzyOperator::DefaultFuzzyOperator();
FuzzyEngine engine("simple-mamdani", op);
engine.hedgeSet().add(new fl::HedgeNot);
engine.hedgeSet().add(new fl::HedgeSomewhat);
engine.hedgeSet().add(new fl::HedgeVery);
fl::InputLVar* energy = new fl::InputLVar("Energy");
energy->addTerm(new fl::ShoulderTerm("LOW", 0.25, 0.5, true));
energy->addTerm(new fl::TriangularTerm("MEDIUM", 0.25, 0.75));
energy->addTerm(new fl::ShoulderTerm("HIGH", 0.50, 0.75, false));
engine.addInputLVar(energy);
fl::OutputLVar* health = new fl::OutputLVar("Health");
health->addTerm(new fl::TriangularTerm("BAD", 0.0, 0.50));
health->addTerm(new fl::TriangularTerm("REGULAR", 0.25, 0.75));
health->addTerm(new fl::TriangularTerm("GOOD", 0.50, 1.00));
engine.addOutputLVar(health);
fl::RuleBlock* block = new fl::RuleBlock();
block->addRule(new fl::MamdaniRule("if Energy is LOW then Health is BAD", engine));
block->addRule(new fl::MamdaniRule("if Energy is MEDIUM then Health is REGULAR", engine));
block->addRule(new fl::MamdaniRule("if Energy is HIGH then Health is GOOD", engine));
engine.addRuleBlock(block);
for (fl::flScalar in = 0.0; in < 1.1; in += 0.1) {
energy->setInput(in);
engine.process();
fl::flScalar out = health->output().defuzzify();
(void)out; //Just to avoid warning when building
FL_LOG("Energy=" << in);
FL_LOG("Energy is " << energy->fuzzify(in));
FL_LOG("Health=" << out);
FL_LOG("Health is " << health->fuzzify(out));
FL_LOG("--");
}
}
void Test::ComplexMamdani() {
FuzzyOperator& op = FuzzyOperator::DefaultFuzzyOperator();
FuzzyEngine engine("complex-mamdani", op);
engine.hedgeSet().add(new fl::HedgeNot);
engine.hedgeSet().add(new fl::HedgeSomewhat);
engine.hedgeSet().add(new fl::HedgeVery);
fl::InputLVar* energy = new fl::InputLVar("Energy");
energy->addTerm(new fl::TriangularTerm("LOW", 0.0, 0.50));
energy->addTerm(new fl::TriangularTerm("MEDIUM", 0.25, 0.75));
energy->addTerm(new fl::TriangularTerm("HIGH", 0.50, 1.00));
engine.addInputLVar(energy);
fl::InputLVar* distance = new fl::InputLVar("Distance");
distance->addTerm(new fl::TriangularTerm("NEAR", 0, 500));
distance->addTerm(new fl::TriangularTerm("FAR", 250, 750));
distance->addTerm(new fl::TriangularTerm("FAR_AWAY", 500, 1000));
engine.addInputLVar(distance);
fl::OutputLVar* power = new fl::OutputLVar("Power");
power->addTerm(new fl::ShoulderTerm("LOW", 0.25, 0.5, true));
power->addTerm(new fl::TriangularTerm("MEDIUM", 0.25, 0.75));
power->addTerm(new fl::ShoulderTerm("HIGH", 0.50, 0.75, false));
engine.addOutputLVar(power);
fl::RuleBlock* block = new fl::RuleBlock();
block->addRule(new fl::MamdaniRule("if Energy is LOW and Distance is FAR_AWAY then Power is LOW", engine));
block->addRule(new fl::MamdaniRule("if Energy is LOW and Distance is FAR then Power is very MEDIUM", engine));
block->addRule(new fl::MamdaniRule("if Energy is LOW and Distance is NEAR then Power is HIGH", engine));
block->addRule(new fl::MamdaniRule("if Energy is MEDIUM and Distance is FAR_AWAY then Power is LOW with 0.8", engine));
block->addRule(new fl::MamdaniRule("if Energy is MEDIUM and Distance is FAR then Power is MEDIUM with 1.0", engine));
block->addRule(new fl::MamdaniRule("if Energy is MEDIUM and Distance is NEAR then Power is HIGH with 0.3", engine));
block->addRule(new fl::MamdaniRule("if Energy is HIGH and Distance is FAR_AWAY then Power is LOW with 0.43333", engine));
block->addRule(new fl::MamdaniRule("if Energy is HIGH and Distance is FAR then Power is MEDIUM", engine));
block->addRule(new fl::MamdaniRule("if Energy is HIGH and Distance is NEAR then Power is HIGH", engine));
engine.addRuleBlock(block);
for (int i = 0; i < block->numberOfRules(); ++i) {
FL_LOG(block->rule(i)->toString());
}
return;
for (fl::flScalar in = 0.0; in < 1.1; in += 0.1) {
energy->setInput(in);
distance->setInput(500);
engine.process();
fl::flScalar out = power->output().defuzzify();
(void)out; //Just to avoid warning when building
FL_LOG("Energy=" << in);
FL_LOG("Energy is " << power->fuzzify(in));
FL_LOG("Health=" << out);
FL_LOG("Health is " << energy->fuzzify(out));
FL_LOG("--");
}
}
void Test::SimpleTakagiSugeno() {
FuzzyOperator& op = FuzzyOperator::DefaultFuzzyOperator();
op.setDefuzzifier(new TakagiSugenoDefuzzifier);
FuzzyEngine engine("takagi-sugeno", op);
fl::InputLVar* x = new fl::InputLVar("x");
x->addTerm(new fl::TriangularTerm("NEAR_1", 0, 2));
x->addTerm(new fl::TriangularTerm("NEAR_2", 1, 3));
x->addTerm(new fl::TriangularTerm("NEAR_3", 2, 4));
x->addTerm(new fl::TriangularTerm("NEAR_4", 3, 5));
x->addTerm(new fl::TriangularTerm("NEAR_5", 4, 6));
x->addTerm(new fl::TriangularTerm("NEAR_6", 5, 7));
x->addTerm(new fl::TriangularTerm("NEAR_7", 6, 8));
x->addTerm(new fl::TriangularTerm("NEAR_8", 7, 9));
x->addTerm(new fl::TriangularTerm("NEAR_9", 8, 10));
engine.addInputLVar(x);
fl::OutputLVar* f_x = new fl::OutputLVar("f_x");
f_x->addTerm(new fl::FunctionTerm("function", "(sin x) / x", 0, 10));
engine.addOutputLVar(f_x);
fl::RuleBlock* block = new fl::RuleBlock();
block->addRule(new fl::TakagiSugenoRule("if x is NEAR_1 then f_x=0.84", engine));
block->addRule(new fl::TakagiSugenoRule("if x is NEAR_2 then f_x=0.45", engine));
block->addRule(new fl::TakagiSugenoRule("if x is NEAR_3 then f_x=0.04", engine));
block->addRule(new fl::TakagiSugenoRule("if x is NEAR_4 then f_x=-0.18", engine));
block->addRule(new fl::TakagiSugenoRule("if x is NEAR_5 then f_x=-0.19", engine));
block->addRule(new fl::TakagiSugenoRule("if x is NEAR_6 then f_x=-0.04", engine));
block->addRule(new fl::TakagiSugenoRule("if x is NEAR_7 then f_x=0.09", engine));
block->addRule(new fl::TakagiSugenoRule("if x is NEAR_8 then f_x=0.12", engine));
block->addRule(new fl::TakagiSugenoRule("if x is NEAR_9 then f_x=0.04", engine));
engine.addRuleBlock(block);
int n = 40;
flScalar mse = 0;
for (fl::flScalar in = x->minimum(); in < x->maximum() ;
in += (x->minimum() + x->maximum()) / n) {
x->setInput(in);
engine.process();
flScalar expected = f_x->term(0)->membership(in);
flScalar obtained = f_x->output().defuzzify();
flScalar se = (expected - obtained) * (expected - obtained);
mse += isnan(se) ? 0 : se;
FL_LOG("x=" << in << "\texpected_out=" << expected << "\tobtained_out=" << obtained
<< "\tse=" << se);
}
FL_LOG("MSE=" << mse / n);
}
void Test::SimplePendulum() {
FuzzyOperator& op = FuzzyOperator::DefaultFuzzyOperator();
FuzzyEngine engine("pendulum-3d",op);
InputLVar* anglex = new InputLVar("AngleX");
std::vector<std::string> labels;
labels.push_back("NEAR_0");
labels.push_back("NEAR_45");
labels.push_back("NEAR_90");
labels.push_back("NEAR_135");
labels.push_back("NEAR_180");
anglex->createTerms(5, LinguisticTerm::MF_SHOULDER, 0, 180, labels);
engine.addInputLVar(anglex);
InputLVar* anglez = new InputLVar("AngleZ");
labels.clear();
labels.push_back("NEAR_0");
labels.push_back("NEAR_45");
labels.push_back("NEAR_90");
labels.push_back("NEAR_135");
labels.push_back("NEAR_180");
anglez->createTerms(5, LinguisticTerm::MF_SHOULDER, 0, 180, labels);
engine.addInputLVar(anglez);
OutputLVar* forcex = new OutputLVar("ForceX");
labels.clear();
labels.push_back("NL");
labels.push_back("NS");
labels.push_back("ZR");
labels.push_back("PS");
labels.push_back("PL");
forcex->createTerms(5, LinguisticTerm::MF_TRIANGULAR, -1, 1, labels);
engine.addOutputLVar(forcex);
OutputLVar* forcez = new OutputLVar("ForceZ");
labels.clear();
labels.push_back("NL");
labels.push_back("NS");
labels.push_back("ZR");
labels.push_back("PS");
labels.push_back("PL");
forcez->createTerms(5, LinguisticTerm::MF_TRIANGULAR, -1, 1, labels);
engine.addOutputLVar(forcez);
RuleBlock* ruleblock = new RuleBlock("Rules");
ruleblock->addRule(new MamdaniRule("if AngleX is NEAR_180 then ForceX is NL", engine));
ruleblock->addRule(new MamdaniRule("if AngleX is NEAR_135 then ForceX is NS", engine));
ruleblock->addRule(new MamdaniRule("if AngleX is NEAR_90 then ForceX is ZR", engine));
ruleblock->addRule(new MamdaniRule("if AngleX is NEAR_45 then ForceX is PS", engine));
ruleblock->addRule(new MamdaniRule("if AngleX is NEAR_0 then ForceX is PL", engine));
ruleblock->addRule(new MamdaniRule("if AngleZ is NEAR_180 then ForceZ is NL", engine));
ruleblock->addRule(new MamdaniRule("if AngleZ is NEAR_135 then ForceZ is NS", engine));
ruleblock->addRule(new MamdaniRule("if AngleZ is NEAR_90 then ForceZ is ZR", engine));
ruleblock->addRule(new MamdaniRule("if AngleZ is NEAR_45 then ForceZ is PS", engine));
ruleblock->addRule(new MamdaniRule("if AngleZ is NEAR_0 then ForceZ is PL", engine));
engine.addRuleBlock(ruleblock);
FL_LOG(engine.toString());
for (int i = 0; i < 180; i += 20) {
engine.setInput("AngleX", i);
engine.process();
FL_LOG("angle=" << i << "\tforce=" << engine.output("ForceX"));
}
}
void Test::main(int args, char** argv) {
FL_LOG("Starting in 2 second");
FL_LOG("Example: Simple Mamdani");
FL_LOG("=======================");
sleep(2);
SimpleMamdani();
FL_LOG("=======================\n");
FL_LOG("Starting in 2 second");
FL_LOG("Example: Complex Mamdani");
FL_LOG("========================");
sleep(2);
ComplexMamdani();
FL_LOG("=======================\n");
FL_LOG("Starting in 2 second");
FL_LOG("Example: Simple Pendulum");
FL_LOG("========================");
sleep(2);
SimplePendulum();
FL_LOG("=======================\n");
FL_LOG("Starting in 2 second");
FL_LOG("Example: Simple Takagi-Sugeno");
FL_LOG("========================");
sleep(2);
SimpleTakagiSugeno();
FL_LOG("=======================\n");
FL_LOG("For further examples build the GUI...");
}
}

39
AI/FuzzyLite/test.h Normal file
View File

@ -0,0 +1,39 @@
/* Copyright 2010 Juan Rada-Vilela
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: test.h
* Author: jcrada
*
* Created on December 8, 2009, 11:11 PM
*/
#ifndef FL_TEST_H
#define FL_TEST_H
namespace fl {
class Test {
public:
static void SimpleMamdani();
static void ComplexMamdani();
static void SimpleTakagiSugeno();
static void SimplePendulum();
static void main(int args, char** argv);
};
}
#endif /* FL_TEST_H */

View File

@ -1,35 +1,35 @@
#include "StdInc.h"
#include "Fuzzy.h"
#include "../../lib/CObjectHandler.h"
#include "AreaCentroidAlgorithm.cpp"
#include "CompoundTerm.cpp"
#include "DescriptiveAntecedent.cpp"
#include "FuzzyEngine.cpp"
#include "FuzzyAnd.cpp"
#include "FuzzyOr.cpp"
#include "InputLVar.cpp"
#include "OutputLVar.cpp"
#include "FuzzyAntecedent.cpp"
#include "FuzzyConsequent.cpp"
#include "FuzzyDefuzzifier.cpp"
#include "FuzzyModulation.cpp"
#include "FuzzyOperator.cpp"
#include "FuzzyOperation.cpp"
#include "FuzzyException.cpp"
#include "FuzzyExceptions.cpp"
#include "FuzzyRule.cpp"
#include "HedgeSet.cpp"
#include "Hedge.cpp"
#include "SingletonTerm.cpp"
#include "TrapezoidalTerm.cpp"
#include "TriangularTerm.cpp"
#include "LinguisticTerm.cpp"
#include "LinguisticVariable.cpp"
#include "RuleBlock.cpp"
#include "ShoulderTerm.cpp"
#include "StrOp.cpp"
#include "MamdaniRule.cpp"
#include "MamdaniConsequent.cpp"
#include "..\FuzzyLite\AreaCentroidAlgorithm.cpp"
#include "..\FuzzyLite\CompoundTerm.cpp"
#include "..\FuzzyLite\DescriptiveAntecedent.cpp"
#include "..\FuzzyLite\FuzzyEngine.cpp"
#include "..\FuzzyLite\FuzzyAnd.cpp"
#include "..\FuzzyLite\FuzzyOr.cpp"
#include "..\FuzzyLite\InputLVar.cpp"
#include "..\FuzzyLite\OutputLVar.cpp"
#include "..\FuzzyLite\FuzzyAntecedent.cpp"
#include "..\FuzzyLite\FuzzyConsequent.cpp"
#include "..\FuzzyLite\FuzzyDefuzzifier.cpp"
#include "..\FuzzyLite\FuzzyModulation.cpp"
#include "..\FuzzyLite\FuzzyOperator.cpp"
#include "..\FuzzyLite\FuzzyOperation.cpp"
#include "..\FuzzyLite\FuzzyException.cpp"
#include "..\FuzzyLite\FuzzyExceptions.cpp"
#include "..\FuzzyLite\FuzzyRule.cpp"
#include "..\FuzzyLite\HedgeSet.cpp"
#include "..\FuzzyLite\Hedge.cpp"
#include "..\FuzzyLite\SingletonTerm.cpp"
#include "..\FuzzyLite\TrapezoidalTerm.cpp"
#include "..\FuzzyLite\TriangularTerm.cpp"
#include "..\FuzzyLite\LinguisticTerm.cpp"
#include "..\FuzzyLite\LinguisticVariable.cpp"
#include "..\FuzzyLite\RuleBlock.cpp"
#include "..\FuzzyLite\ShoulderTerm.cpp"
#include "..\FuzzyLite\StrOp.cpp"
#include "..\FuzzyLite\MamdaniRule.cpp"
#include "..\FuzzyLite\MamdaniConsequent.cpp"
/*
* Fuzzy.cpp, part of VCMI engine

View File

@ -1,6 +1,21 @@
#define INFINITY 1000000000 //definition required by FuzzyLite (?)
#define NAN 1000000001
#include "FuzzyLite.h"
#ifndef NAN
static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
#define NAN (*(const float *) __nan)
#endif
#ifdef _MSC_VER
#ifndef INFINITY
union MSVC_FL
{
unsigned __int8 Bytes[4];
float Value;
};
static union MSVC_FL INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}};
#define INFINITY (INFINITY_HACK.Value)
#endif
#endif
#include "..\FuzzyLite\FuzzyLite.h"
/*
* Fuzzy.h, part of VCMI engine