Skip to content

Instantly share code, notes, and snippets.

@PtrMan
Last active October 28, 2015 21:50
Show Gist options
  • Save PtrMan/ca558152d115e05622e6 to your computer and use it in GitHub Desktop.
Save PtrMan/ca558152d115e05622e6 to your computer and use it in GitHub Desktop.
#include "bindings/Array.h"
#include <iostream>
using namespace std;
float interpolateLinear(float t, float a, float b) {
return (1.0f-t)*a + t*b;
}
float isInRange(float x, float min, float max) {
return x >= min && x <= max;
}
struct TriangleFunction {
enum class EnumSide {
NEGATIVE,
POSITIVE
};
float center;
float width;
float calculateYForWholeRange(float x) {
if( isInRange(x) ) {
return calculateY(x);
}
else {
return 0.0f;
}
}
bool isInRange(float x) {
return ::isInRange(x, center-width, center+width);
}
// invariant, x has to be in range
float calculateY(float x) {
float relativeDistance;
EnumSide side;
calculateRelativeAbsoluteDistanceWithSide(x, relativeDistance, side);
return interpolateLinear(relativeDistance, 1.0f, 0.0f);
}
void calculateRelativeAbsoluteDistanceWithSide(float x, float &relativeDistance, EnumSide &side) {
if( x > center ) {
side = EnumSide::POSITIVE;
relativeDistance = (x - center) / width;
}
else {
side = EnumSide::NEGATIVE;
relativeDistance = (-(x - center)) / width;
}
}
};
struct FuzzificationForTriangle {
TriangleFunction::EnumSide side;
float relativeDistance;
float membership;
bool inRange;
};
struct FuzzifierContext {
Array<TriangleFunction> triangleFunctions;
Array<FuzzificationForTriangle> triangleFuzzification;
void calculateMembershipsForValue(float x) {
for( int triangleFunctionI = 0; triangleFunctionI < triangleFunctions.getCount(); triangleFunctionI++ ) {
cout << "index =="<< triangleFunctionI << endl;
bool inRange = triangleFuzzification[triangleFunctionI].inRange = triangleFunctions[triangleFunctionI].isInRange(x);
if( inRange ) {
cout << "INRANGE" << endl;
triangleFuzzification[triangleFunctionI].membership = triangleFunctions[triangleFunctionI].calculateY(x);
triangleFunctions[triangleFunctionI].calculateRelativeAbsoluteDistanceWithSide(x, triangleFuzzification[triangleFunctionI].relativeDistance, triangleFuzzification[triangleFunctionI].side);
}
else {
triangleFuzzification[triangleFunctionI].membership = 0.0f;
}
}
}
// defuzification
// centroid method, see http://www.csee.wvu.edu/classes/cpe521/presentations/DEFUZZ.pdf
// page 10
float defuzificationCentroid(float maxXRange, float stepsize) {
// very stupid implementation, we just iterate and calculate the maximum
float weightSum = 0.0f;
float valueSum = 0.0f;
for( float xi = 0.0f; xi < maxXRange; xi += stepsize ) {
float currentValue = 0.0f;
for( int triangleI = 0; triangleI < triangleFuzzification.getCount(); triangleI++ ) {
float yValue = min( triangleFunctions[triangleI].calculateYForWholeRange(xi), triangleFuzzification[triangleI].membership);
currentValue = max(currentValue, yValue);
}
weightSum += (currentValue * xi);
valueSum += currentValue;
}
// ask< is this correct? >
float centroidX = weightSum / valueSum;
return centroidX;
}
};
main() {
FuzzifierContext fuzzylogicContext;
TriangleFunction a, b;
fuzzylogicContext.triangleFunctions.add(a);
fuzzylogicContext.triangleFunctions[0].center = 1.0f;
fuzzylogicContext.triangleFunctions[0].width = 1.0f;
fuzzylogicContext.triangleFunctions.add(b);
fuzzylogicContext.triangleFunctions[1].center = 2.0f;
fuzzylogicContext.triangleFunctions[1].width = 2.0f;
FuzzificationForTriangle triangleA, triangleB;
fuzzylogicContext.triangleFuzzification.add(triangleA);
fuzzylogicContext.triangleFuzzification.add(triangleB);
fuzzylogicContext.calculateMembershipsForValue(1.4f);
// debug membership
cout << "membership A=" << fuzzylogicContext.triangleFuzzification[0].membership << endl;
cout << "membership B=" << fuzzylogicContext.triangleFuzzification[1].membership << endl;
float centeroid = fuzzylogicContext.defuzificationCentroid(8.0f, 0.05f);
cout << "centeroid " << centeroid << endl;
}
@PtrMan
Copy link
Author

PtrMan commented Oct 27, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment