home Forums # Technical Support Migration to jfuzzylite

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #6262
    Unknown
    Member

    I’m trying to migrate from fuzzylogic to jfuzzylite, but the defuzzification results seem very different.

    Input values:
    signal: 30
    distance: 40

    Output values:
    fuzzylogic: 24.473140
    jfuzzylite: 57.058

    What I’m doing wrong?

    FCL:

    
    FUNCTION_BLOCK proximity
    
    VAR_INPUT
        signal : REAL;
        distance : REAL;
    END_VAR
    
    VAR_OUTPUT
        proximity : REAL;
    END_VAR
    
    FUZZIFY signal
        TERM strong := (0,1) (30,1) (65, 0);
        TERM decent := (25, 0) (60,1) (90, 0);
        TERM weak := (80, 0) (120, 1);
    END_FUZZIFY
    
    FUZZIFY distance
        TERM low := (0,1) (20,0);
        TERM medium := (15, 0) (30,1) (70, 0);
        TERM high := (60, 0) (200, 1);
    END_FUZZIFY
    
    DEFUZZIFY proximity
        TERM immediate := (0, 1) (30, 0);
        TERM near := (20, 0) (40, 1) (80, 0);
        TERM far := (70, 0) (100, 1);
            
            
        METHOD : COG;        // Use 'Center Of Gravity' defuzzification method
        DEFAULT := 0;        // Default value is 0 (if no rule activates defuzzifier)
    END_DEFUZZIFY
    
    RULEBLOCK first     
        AND : MIN;
            
        ACCU : MAX;
        ACT : MIN;
            
        RULE 1 : IF signal IS strong AND distance IS low THEN proximity IS immediate;
        RULE 2 : IF signal IS strong AND distance IS medium THEN proximity IS immediate;
        RULE 3 : IF signal IS strong AND distance IS high THEN proximity IS immediate;
        RULE 4 : IF signal IS decent AND distance IS low THEN proximity IS immediate;
        RULE 5 : IF signal IS decent AND distance IS medium THEN proximity IS near;
        RULE 6 : IF signal IS decent AND distance IS high THEN proximity IS near;
        RULE 7 : IF signal IS weak AND distance IS low THEN proximity IS immediate;
        RULE 8 : IF signal IS weak AND distance IS medium THEN proximity IS near;
        RULE 9 : IF signal IS weak AND distance IS high THEN proximity IS far;
    END_RULEBLOCK
    
    END_FUNCTION_BLOCK
    

    jfuzzylite:

    
    Engine engine = new Engine();
    engine.setName("Proximity");
    engine.setDescription("");
            
    InputVariable signal = new InputVariable();
    signal.setName("signal");
    signal.setDescription("");
    signal.setEnabled(true);
    signal.setRange(30.0, 120.0);
    signal.setLockValueInRange(true);
    signal.addTerm(new Trapezoid("strong", 0.0, 0.0, 30.0, 65.0));
    signal.addTerm(new Triangle("decent", 25.0, 60.0, 90.0));
    signal.addTerm(new Ramp("weak", 80.0, 120.0));
    engine.addInputVariable(signal);
            
    InputVariable distance = new InputVariable();
    distance.setName("distance");
    distance.setDescription("");
    distance.setEnabled(true);
    distance.setRange(0.0, 200.0);
    distance.setLockValueInRange(true);
    distance.addTerm(new Ramp("low", 0.0, 20.0));
    distance.addTerm(new Triangle("medium", 15.0, 30.0, 70.0));
    distance.addTerm(new Ramp("high", 60.0, 200.0));
    engine.addInputVariable(distance);
        
    OutputVariable proximity = new OutputVariable();
    proximity.setName("proximity");
    proximity.setDescription("");
    proximity.setEnabled(true);
    proximity.setRange(0.0, 100.0);
    proximity.setLockValueInRange(false);
    proximity.setAggregation(new Maximum());
    proximity.setDefuzzifier(new Centroid(100));
    proximity.setDefaultValue(Double.NaN);
    proximity.setLockPreviousValue(false);
    proximity.addTerm(new Ramp("immediate", 0.0, 30.0));
    proximity.addTerm(new Triangle("near", 20.0, 40.0, 80.0));
    proximity.addTerm(new Ramp("far", 70.0, 100.0));
    engine.addOutputVariable(proximity);
            
    RuleBlock mamdani = new RuleBlock();
    mamdani.setName("mamdani");
    mamdani.setDescription("");
    mamdani.setEnabled(true);
    mamdani.setConjunction(new AlgebraicProduct());
    mamdani.setDisjunction(new AlgebraicSum());
    mamdani.setImplication(new Minimum());
    mamdani.setActivation(new General());
    mamdani.addRule(Rule.parse("if signal is strong and distance is low then proximity is immediate", engine));
    mamdani.addRule(Rule.parse("if signal is strong and distance is medium then proximity is immediate", engine));
    mamdani.addRule(Rule.parse("if signal is strong and distance is high then proximity is immediate", engine));
    mamdani.addRule(Rule.parse("if signal is decent and distance is low then proximity is immediate", engine));
    mamdani.addRule(Rule.parse("if signal is decent and distance is medium then proximity is near", engine));
    mamdani.addRule(Rule.parse("if signal is decent and distance is high then proximity is near", engine));
    mamdani.addRule(Rule.parse("if signal is weak and distance is low then proximity is immediate", engine));
    mamdani.addRule(Rule.parse("if signal is weak and distance is medium then proximity is near", engine));
    mamdani.addRule(Rule.parse("if signal is weak and distance is high then proximity is far", engine));
    engine.addRuleBlock(mamdani);
            
    signal.setValue(30.0);
    distance.setValue(40.0);
    engine.process();
    FuzzyLite.logger().info(String.format(
        "signal.input = %s, distance.input = %s -> proximity.output = %s",
        Op.str(signal.getValue()), Op.str(distance.getValue()), Op.str(proximity.getValue())));
    
    #6263
    Unknown
    Member

    Solved. The error was in Ramp values:

    
    distance.addTerm(new Ramp("low", 0.0, 20.0));
    proximity.addTerm(new Ramp("immediate", 0.0, 30.0));
    

    Should be:

    
    distance.addTerm(new Ramp("low", 20.0, 0.0));
    proximity.addTerm(new Ramp("immediate", 30.0, 0.0));
    

    But, I find another issue. I’m exporting this code to R:

    
    RScriptExporter exporter = new RScriptExporter();
    exporter.toFile(new File("plot.r"), engine);
    

    When I’m trying to execute, RStudio gives me the following error:

    
    Error: Discrete value supplied to continuous scale
    In addition: Warning message:
      Error: Discrete value supplied to continuous scale 
    
    #6264

    Hi Andrey,

    thanks for your post and for using jfuzzylite.

    Could you please post the FLL code?

    As for the previous question, glad you found the mistake. The FCL engine you posted, the equivalent in FLL is:

    Engine: proximity
    InputVariable: signal
      enabled: true
      range: 30.000 120.000
      lock-range: false
      term: strong Discrete 0.000 1.000 30.000 1.000 65.000 0.000
      term: decent Discrete 25.000 0.000 60.000 1.000 90.000 0.000
      term: weak Discrete 80.000 0.000 120.000 1.000
    InputVariable: distance
      enabled: true
      range: 0.000 200.000
      lock-range: false
      term: low Discrete 0.000 1.000 20.000 0.000
      term: medium Discrete 15.000 0.000 30.000 1.000 70.000 0.000
      term: high Discrete 60.000 0.000 200.000 1.000
    OutputVariable: proximity
      enabled: true
      range: 0.000 100.000
      lock-range: false
      aggregation: Maximum
      defuzzifier: Centroid 100
      default: 0.000
      lock-previous: false
      term: immediate Discrete 0.000 1.000 30.000 0.000
      term: near Discrete 20.000 0.000 40.000 1.000 80.000 0.000
      term: far Discrete 70.000 0.000 100.000 1.000
    RuleBlock: first
      enabled: true
      conjunction: Minimum
      disjunction: none
      implication: Minimum
      activation: General
      rule: if signal is strong and distance is low then proximity is immediate
      rule: if signal is strong and distance is medium then proximity is immediate
      rule: if signal is strong and distance is high then proximity is immediate
      rule: if signal is decent and distance is low then proximity is immediate
      rule: if signal is decent and distance is medium then proximity is near
      rule: if signal is decent and distance is high then proximity is near
      rule: if signal is weak and distance is low then proximity is immediate
      rule: if signal is weak and distance is medium then proximity is near
      rule: if signal is weak and distance is high then proximity is far
    

    Take a look at the engine:
    Screen-Shot-2018-11-18-at-09-47-44

    #6265
    Unknown
    Member

    Hi Juan,

    Here is the generated R code by jfuzzylite.

    When you run this code the following error occurs:

    Error in textConnection(engine.fld) : object 'engine.fld' not found

    So I changed from “engine.fld” to “engine.fldFile” on line 1075. But the original error still persists:

    Error: Discrete value supplied to continuous scale
    In addition: Warning message:
      Error: Discrete value supplied to continuous scale
    #6266

    Hi,

    could you please post the FLL code of your engine?

    Thanks.

    #6267

    oh, never mind. just saw it in the R code.

    #6268

    I think the problem you are having is with locales. Take notice that you export values with , as decimal separators. I think R is not handling this well.

    Please try changing the locale in java before exporting to something like Locale.setDefault(new Locale("en", "NZ"));, make sure the exported values use . for decimals, and try running the script in R.

    You do not need to change anything from the R script.

    Cheers.

    #6269
    Unknown
    Member

    It worked! Thank you Juan.

Viewing 8 posts - 1 through 8 (of 8 total)
  • You must be logged in to reply to this topic.