//-------------------------------------------------------------------------------- // Code generated by jFuzzyLogic // jFuzzyLogic Version : JFuzzyLogic 3.2g (build 2013-10-20), by Pablo Cingolani // jFuzzyLogic creted by Pablo Cingolani //-------------------------------------------------------------------------------- #include #include double ruleAccumulationMethod_max(double defuzzifierValue, double valueToAggregate) { return ( defuzzifierValue > valueToAggregate ? defuzzifierValue : valueToAggregate ); } double ruleActivationMethod_min(double degreeOfSupport, double membership) { return (degreeOfSupport < membership ? degreeOfSupport : membership); } double ruleConnectionMethod_and(double antecedent1, double antecedent2) { return (antecedent1 < antecedent2 ? antecedent1 : antecedent2); } double ruleConnectionMethod_or(double antecedent1, double antecedent2) { return (antecedent1 > antecedent2 ? antecedent1 : antecedent2); } class FunctionBlock_tipper { public: // VAR_INPUT double food; double service; // VAR_OUTPUT double tip; private: // FUZZIFY food double food_delicious; double food_rancid; // FUZZIFY service double service_excellent; double service_good; double service_poor; // DEFUZZIFY tip double defuzzify_tip[1000]; public: FunctionBlock_tipper(); void calc(); void print(); private: void defuzzify(); void fuzzify(); void reset(); double membership_food_delicious(double x); double membership_food_rancid(double x); double membership_service_excellent(double x); double membership_service_good(double x); double membership_service_poor(double x); double membership_tip_average(double x); double membership_tip_cheap(double x); double membership_tip_generous(double x); void calc_No1(); }; // Constructor FunctionBlock_tipper::FunctionBlock_tipper() { tip = 0.0; } // Calculate function block void FunctionBlock_tipper::calc() { reset(); fuzzify(); calc_No1(); defuzzify(); } // RULEBLOCK No1 void FunctionBlock_tipper::calc_No1() { // RULE 1 : IF (service IS poor) OR (food IS rancid) THEN tip IS cheap; double degreeOfSupport_1 = 1.0 * ( ruleConnectionMethod_or(service_poor , food_rancid) ); if( degreeOfSupport_1 > 0 ) { for (int i = 0 ; i < 1000 ; i++ ) { double x = 0.0 + i * 0.03; double membership = membership_tip_cheap(x); double y = ruleActivationMethod_min( degreeOfSupport_1 , membership ); defuzzify_tip[i] += ruleAccumulationMethod_max( defuzzify_tip[i], y ); } } // RULE 2 : IF service IS good THEN tip IS average; double degreeOfSupport_2 = 1.0 * ( service_good ); if( degreeOfSupport_2 > 0 ) { for (int i = 0 ; i < 1000 ; i++ ) { double x = 0.0 + i * 0.03; double membership = membership_tip_average(x); double y = ruleActivationMethod_min( degreeOfSupport_2 , membership ); defuzzify_tip[i] += ruleAccumulationMethod_max( defuzzify_tip[i], y ); } } // RULE 3 : IF (service IS excellent) AND (food IS delicious) THEN tip IS generous; double degreeOfSupport_3 = 1.0 * ( ruleConnectionMethod_and(service_excellent , food_delicious) ); if( degreeOfSupport_3 > 0 ) { for (int i = 0 ; i < 1000 ; i++ ) { double x = 0.0 + i * 0.03; double membership = membership_tip_generous(x); double y = ruleActivationMethod_min( degreeOfSupport_3 , membership ); defuzzify_tip[i] += ruleAccumulationMethod_max( defuzzify_tip[i], y ); } } } // Defuzzify void FunctionBlock_tipper::defuzzify() { double sum_tip = 0.0; double wsum_tip = 0.0; for (int i = 0; i < 1000 ; i++ ) { double x = 0.0 + i * 0.03; sum_tip += defuzzify_tip[i]; wsum_tip += x * defuzzify_tip[i]; } tip = wsum_tip / sum_tip; } // Fuzzify all variables void FunctionBlock_tipper::fuzzify() { food_delicious = membership_food_delicious(food); food_rancid = membership_food_rancid(food); service_excellent = membership_service_excellent(service); service_good = membership_service_good(service); service_poor = membership_service_poor(service); } // Membership functions double FunctionBlock_tipper::membership_food_delicious(double x) { if ( x <= 7.0 ) return 0.0; if ( x > 9.0 ) return 1.0; if ( x <= 9.0 ) return 0.0 + ( 1.0 - 0.0 ) * ( ( x - 7.0 ) / ( 9.0 - 7.0 ) ); } double FunctionBlock_tipper::membership_food_rancid(double x) { if ( x <= 0.0 ) return 1.0; if ( x > 3.0 ) return 0.0; if ( x <= 1.0 ) return 1.0 + ( 1.0 - 1.0 ) * ( ( x - 0.0 ) / ( 1.0 - 0.0 ) ); if ( x <= 3.0 ) return 1.0 + ( 0.0 - 1.0 ) * ( ( x - 1.0 ) / ( 3.0 - 1.0 ) ); } double FunctionBlock_tipper::membership_service_excellent(double x) { if ( x <= 6.0 ) return 0.0; if ( x > 9.0 ) return 1.0; if ( x <= 9.0 ) return 0.0 + ( 1.0 - 0.0 ) * ( ( x - 6.0 ) / ( 9.0 - 6.0 ) ); } double FunctionBlock_tipper::membership_service_good(double x) { if ( x <= 1.0 ) return 0.0; if ( x > 9.0 ) return 0.0; if ( x <= 4.0 ) return 0.0 + ( 1.0 - 0.0 ) * ( ( x - 1.0 ) / ( 4.0 - 1.0 ) ); if ( x <= 6.0 ) return 1.0 + ( 1.0 - 1.0 ) * ( ( x - 4.0 ) / ( 6.0 - 4.0 ) ); if ( x <= 9.0 ) return 1.0 + ( 0.0 - 1.0 ) * ( ( x - 6.0 ) / ( 9.0 - 6.0 ) ); } double FunctionBlock_tipper::membership_service_poor(double x) { if ( x <= 0.0 ) return 1.0; if ( x > 4.0 ) return 0.0; if ( x <= 4.0 ) return 1.0 + ( 0.0 - 1.0 ) * ( ( x - 0.0 ) / ( 4.0 - 0.0 ) ); } double FunctionBlock_tipper::membership_tip_average(double x) { if ( x <= 10.0 ) return 0.0; if ( x > 20.0 ) return 0.0; if ( x <= 15.0 ) return 0.0 + ( 1.0 - 0.0 ) * ( ( x - 10.0 ) / ( 15.0 - 10.0 ) ); if ( x <= 20.0 ) return 1.0 + ( 0.0 - 1.0 ) * ( ( x - 15.0 ) / ( 20.0 - 15.0 ) ); } double FunctionBlock_tipper::membership_tip_cheap(double x) { if ( x <= 0.0 ) return 0.0; if ( x > 10.0 ) return 0.0; if ( x <= 5.0 ) return 0.0 + ( 1.0 - 0.0 ) * ( ( x - 0.0 ) / ( 5.0 - 0.0 ) ); if ( x <= 10.0 ) return 1.0 + ( 0.0 - 1.0 ) * ( ( x - 5.0 ) / ( 10.0 - 5.0 ) ); } double FunctionBlock_tipper::membership_tip_generous(double x) { if ( x <= 20.0 ) return 0.0; if ( x > 30.0 ) return 0.0; if ( x <= 25.0 ) return 0.0 + ( 1.0 - 0.0 ) * ( ( x - 20.0 ) / ( 25.0 - 20.0 ) ); if ( x <= 30.0 ) return 1.0 + ( 0.0 - 1.0 ) * ( ( x - 25.0 ) / ( 30.0 - 25.0 ) ); } // Print void FunctionBlock_tipper::print() { printf("Function block tipper:\n"); printf(" Input %20s : %f\n", "food" , food); printf(" %20s : %f\n", "food_delicious" , food_delicious); printf(" %20s : %f\n", "food_rancid" , food_rancid); printf(" Input %20s : %f\n", "service" , service); printf(" %20s : %f\n", "service_excellent" , service_excellent); printf(" %20s : %f\n", "service_good" , service_good); printf(" %20s : %f\n", "service_poor" , service_poor); printf(" Output %20s : %f\n", "tip" , tip); } // Reset output void FunctionBlock_tipper::reset() { for( int i=0 ; i < 1000 ; i++ ) { defuzzify_tip[i] = 0.0; } } int main(int argc, char *argv[]) { // Create function blocks FunctionBlock_tipper tipper; // Parse input if( argc > 1 ) { tipper.food = atof(argv[1]); } if( argc > 2 ) { tipper.service = atof(argv[2]); } // Calculate tipper.calc(); // Show results tipper.print(); }