/**
* Inference method
* Add membershipfunction to deffuzifier (using 'min' as inference)
*/
public void imply(FuzzyRuleTerm fuzzyRuleTerm, double degreeOfSupport) {
Variable variable = fuzzyRuleTerm.getVariable();
Defuzzifier defuzzifier = variable.getDefuzzifier();
MembershipFunction mf = fuzzyRuleTerm.getMembershipFunction();
double membership, y, x, aggregated = 0;
// Both are equal? (both discrete or both continuous?)
if( mf.isDiscrete() != defuzzifier.isDiscrete() ) throw new RuntimeException("MembershipFunction and Defuzzifier are neither both discrete nor both continuous\n\tTerm: " + fuzzyRuleTerm + "\n\tMembership function: " + mf + "\n\tDefuzzifier: " + defuzzifier + "\n");
if( mf.isDiscrete() ) {
//---
// Discrete case
//---
DefuzzifierDiscrete defuzzifierDiscrete = (DefuzzifierDiscrete) defuzzifier;
MembershipFunctionDiscrete mfd = (MembershipFunctionDiscrete) mf;
// Add membershipfunction to deffuzifier
int i, size = mfd.size();
for( i = 0; i < size; i++ ) {
// Get 'x' value
x = mfd.valueX(i);
// Is term negated?
if( fuzzyRuleTerm.isNegated() ) membership = 1 - mf.membership(x);
else membership = mf.membership(x);
y = imply(degreeOfSupport, membership); // Call to abstract implication method described above
// Aggregate value
aggregated = variable.getRuleAggregationMethod().aggregate(defuzzifierDiscrete.getDiscreteValue(x), y);
defuzzifierDiscrete.setPoint(x, aggregated);
}
} else {
//---
// Continuous case
//---
DefuzzifierContinuous defuzzifierContinuous = (DefuzzifierContinuous) defuzzifier;
x = defuzzifierContinuous.getMin();
double step = defuzzifierContinuous.getStepSize();
// Do some sanitychecks
if( Double.isNaN(x) || Double.isInfinite(x) ) throw new RuntimeException("Universe minimum not calculated for term '" + fuzzyRuleTerm.getTermName() + "' : " + x);
if( Double.isNaN(step) || Double.isInfinite(step) ) throw new RuntimeException("Step not calculated for term '" + fuzzyRuleTerm.getTermName() + "' : " + step);
int i, length = defuzzifierContinuous.getLength();
// Add membershipfunction to deffuzifier
for( i = 0; i < length; i++, x += step ) {
// Is term negated?
if( fuzzyRuleTerm.isNegated() ) membership = 1 - mf.membership(x);
else membership = mf.membership(x);
y = imply(degreeOfSupport, membership); // Call to abstract implication method described above
// Aggregate value
aggregated = variable.getRuleAggregationMethod().aggregate(defuzzifierContinuous.getValue(i), y);
defuzzifierContinuous.setValue(i, aggregated);
}
}
}