home Forums # Technical Support jfuzzylite with two input values

Viewing 10 posts - 1 through 10 (of 11 total)
  • Author
    Posts
  • #1515
    Unknown
    Member

    Hi,

    I’m using jfuzzylite on an Android application, to the class below the value returned is always NaN:

    public class IndDeg { 
    	
    		public String CalcIndDeg(double jitter, double perda){
    
    		Engine engine = new Engine();
    		engine.setName("Ind-Deg");
    
    		InputVariable inputVariable1 = new InputVariable();
    		inputVariable1.setEnabled(true);
    		inputVariable1.setName("Jitter");
    		inputVariable1.setRange(0.000, 200.000);
    		//inputVariable1.addTerm(new Trapezoid("Low", 0.000, 0.000, 40.000, 60.000));
    		inputVariable1.addTerm(new Trapezoid("Low", -50.000, 0.000, 40.000, 60.000)); 
    		inputVariable1.addTerm(new Trapezoid("High", 40.000, 60.000, 200.000, 200.000));
    		inputVariable1.setInputValue(jitter);
    		engine.addInputVariable(inputVariable1);
    		
    
    		InputVariable inputVariable2 = new InputVariable();
    		inputVariable2.setEnabled(true);
    		inputVariable2.setName("Loss");
    		inputVariable2.setRange(0.000, 10.000); // inputVariable2.setRange(0.000, 5.000); //
    		inputVariable2.addTerm(new Triangle("Low", 0.000, 0.000, 1.000));
    		inputVariable2.addTerm(new Triangle("High", 0.000, 1.000, 5.000));
    		inputVariable2.addTerm(new Triangle("Limit", 1.000, 5.000, 5.000));
    		inputVariable2.setInputValue(perda);
    		engine.addInputVariable(inputVariable2);				
    
    		OutputVariable outputVariable = new OutputVariable();
    		outputVariable.setEnabled(true);
    		outputVariable.setName("IndDeg.");
    		outputVariable.setRange(-3.000, 13.000); // outputVariable.setRange(0.000, 13.000);
    		outputVariable.fuzzyOutput().setAccumulation(new Maximum());
    		outputVariable.setDefuzzifier(new Centroid(200));
    		outputVariable.setDefaultValue(Double.NaN);
    		outputVariable.setLockValidOutput(false);
    		outputVariable.setLockOutputRange(false);
    		outputVariable.addTerm(new Triangle("Worst", -3.000, 0.000, 3.000)); // outputVariable.addTerm(new Triangle("Worst", 0.000, 0.000, 3.000));
    		outputVariable.addTerm(new Triangle("Bad", 0.000, 3.000, 5.000));
    		outputVariable.addTerm(new Triangle("Average", 3.000, 5.000, 7.000));
    		outputVariable.addTerm(new Triangle("Good", 5.000, 7.000, 10.000));
    		outputVariable.addTerm(new Triangle("Best", 7.000, 10.000, 13.000));
    		engine.addOutputVariable(outputVariable);
    
    		RuleBlock ruleBlock = new RuleBlock();
    		ruleBlock.setEnabled(true);
    		ruleBlock.setName("");
    		ruleBlock.setConjunction(new Minimum());
    		ruleBlock.setDisjunction(new Maximum());
    		ruleBlock.setActivation(new Minimum());
    		ruleBlock.addRule(Rule.parse("if Jitter is Low and Loss is Low then IndDeg. is Best", engine));
    		ruleBlock.addRule(Rule.parse("if Jitter is Low and Loss is High then IndDeg. is Good", engine));
    		ruleBlock.addRule(Rule.parse("if Jitter is Low and Loss is Limit then IndDeg. is Bad", engine));
    		ruleBlock.addRule(Rule.parse("if Jitter is High and Loss is Low then IndDeg. is Good", engine));
    		ruleBlock.addRule(Rule.parse("if Jitter is High and Loss is High then IndDeg. is Average", engine));
    		ruleBlock.addRule(Rule.parse("if Jitter is High and Loss is Limit then IndDeg. is Worst", engine));
    		engine.addRuleBlock(ruleBlock);
    		
    		StringBuilder status = new StringBuilder();
    		if (!engine.isReady(status))
    			throw new RuntimeException("Nao foi possivel gerar o arquivo. "
    			+ "O seguintes erros foram encontrados:\n" + status.toString());
    				
    		engine.setInputValue("Jitter", jitter);
    		engine.setInputValue("Loss", perda);
    		engine.process();
    
    		return String.valueOf(engine.getOutputValue("IndDeg."));
    	} 
    }

    I thank any help.

    #1517
    Unknown
    Member

    Example:

    String output;
    IndDeg iDeg = new IndDeg();
    output = iDeg.CalcIndDeg(23.430952380952384, 0.0); // return NaN
    output = iDeg.CalcIndDeg(7.316666666666666, 0.0); // return NaN
    output = iDeg.CalcIndDeg(32.70238095238096, 0.0); // return NaN
    #1520

    Hi,

    Could you please post the FLL code of your controller?

    Also, I think you should avoid using the period in the name of your output variable IndDeg, that is, avoid using ‘IndDeg.’ and use instead ‘IndDeg’.

    Cheers,

    #1521

    Hi,

    I found your problem. The terms “Low” and “Limit” have been defined as Triangles, when they are actually Ramps. The following code needs to be changed:

    inputVariable2.addTerm(new Triangle("Low", 0.000, 0.000, 1.000));
    inputVariable2.addTerm(new Triangle("High", 0.000, 1.000, 5.000));
    inputVariable2.addTerm(new Triangle("Limit", 1.000, 5.000, 5.000));
    

    The new code should be:

    inputVariable2.addTerm(new Ramp("Low", 1.000, 0.000));
    inputVariable2.addTerm(new Triangle("High", 0.000, 1.000, 5.000));
    inputVariable2.addTerm(new Ramp("Limit", 1.000, 5.000));
    

    Let me know if this works for you.

    #1524
    Unknown
    Member

    Hi Juan,

    Now is correct! Thank you very much. 😀

    This code was generated from matlab code.

    Type='mamdani'
    Version=2.0
    NumInputs=2
    NumOutputs=1
    NumRules=6
    AndMethod='min'
    OrMethod='max'
    ImpMethod='min'
    AggMethod='max'
    DefuzzMethod='centroid'
    
    [Input1]
    Name='Jitter'
    Range=[0 200]
    NumMFs=2
    MF1='Low':'trapmf',[-50 0 40 60]
    MF2='High':'trapmf',[40 60 200 200]
    
    [Input2]
    Name='Loss'
    Range=[0 10]
    NumMFs=3
    MF1='Low':'trimf',[0 0 1]
    MF2='High':'trimf',[0 1 5]
    MF3='Limit':'trimf',[1 5 5]
    
    [Output1]
    Name='Ind-Deg.'
    Range=[-3 13]
    NumMFs=5
    MF1='Worst':'trimf',[-3 0 3]
    MF2='Bad':'trimf',[0 3 5]
    MF3='Average':'trimf',[3 5 7]
    MF4='Good':'trimf',[5 7 10]
    MF5='Best':'trimf',[7 10 13]
    
    [Rules]
    1 1, 5 (1) : 1
    1 2, 4 (1) : 1
    1 3, 2 (1) : 1
    2 1, 4 (1) : 1
    2 2, 3 (1) : 1
    2 3, 1 (1) : 1
    #1637
    Unknown
    Member

    Hi Juan,

    I have another class with the same problem of class above, sometimes the return value is NaN. I tried to switch to ramp, but does not work.

    import com.fuzzylite.*; 
    import com.fuzzylite.defuzzifier.*;
    import com.fuzzylite.norm.s.*; 
    import com.fuzzylite.norm.t.*; 
    import com.fuzzylite.rule.*; 
    import com.fuzzylite.term.*; 
    import com.fuzzylite.variable.*; 
    
    public class IndDisp {
    	
    	public String CalcIndDisp(double crit, double availability){
    		
    		Engine engine = new Engine();
    		engine.setName("Ind-Disp");
    
    		InputVariable inputVariable1 = new InputVariable();
    		inputVariable1.setEnabled(true);
    		inputVariable1.setName("Criticallity");
    		inputVariable1.setRange(0.000, 5.000);
    		inputVariable1.addTerm(new Triangle("Low", 0.000, 1.000, 2.000));
    		inputVariable1.addTerm(new Triangle("Average", 1.000, 2.000, 3.000));
    		inputVariable1.addTerm(new Triangle("High", 2.000, 3.000, 4.000));
    		inputVariable1.addTerm(new Triangle("Very_High", 3.000, 4.000, 5.000));
    		engine.addInputVariable(inputVariable1);
    
    		InputVariable inputVariable2 = new InputVariable();
    		inputVariable2.setEnabled(true);
    		inputVariable2.setName("Availability");
    		inputVariable2.setRange(90.000, 100.000); //inputVariable2.setRange(85.000, 100.000);
    		inputVariable2.addTerm(new Ramp("Limit", 95.000, 90.000));  //inputVariable2.addTerm(new Triangle("Limit", 90.000, 90.000, 95.000));
    		inputVariable2.addTerm(new Triangle("Very_Low", 90.000, 95.000, 98.000));
    		inputVariable2.addTerm(new Triangle("Low", 95.000, 98.000, 99.000));
    		inputVariable2.addTerm(new Triangle("Average", 98.000, 99.000, 99.900));
    		inputVariable2.addTerm(new Triangle("High", 99.000, 99.900, 100.000));
    		inputVariable2.addTerm(new Ramp("Perfect", 99.900, 100.000));  //inputVariable2.addTerm(new Triangle("Perfect", 99.900, 100.000, 100.000));
    		engine.addInputVariable(inputVariable2);
    
    		OutputVariable outputVariable = new OutputVariable();
    		outputVariable.setEnabled(true);
    		outputVariable.setName("IndDisp");
    		outputVariable.setRange(-3.000, 13.000);
    		outputVariable.fuzzyOutput().setAccumulation(new Maximum());
    		outputVariable.setDefuzzifier(new Centroid(200));
    		outputVariable.setDefaultValue(Double.NaN);
    		outputVariable.setLockValidOutput(false);
    		outputVariable.setLockOutputRange(false);
    		outputVariable.addTerm(new Triangle("Worst", -3.000, 0.000, 3.000));
    		outputVariable.addTerm(new Triangle("Bad", 0.000, 3.000, 5.000));
    		outputVariable.addTerm(new Triangle("Average", 3.000, 5.000, 7.000));
    		outputVariable.addTerm(new Triangle("Good", 5.000, 7.000, 10.000));
    		outputVariable.addTerm(new Triangle("Best", 7.000, 10.000, 13.000));
    		engine.addOutputVariable(outputVariable);
    
    		RuleBlock ruleBlock = new RuleBlock();
    		ruleBlock.setEnabled(true);
    		ruleBlock.setName("");
    		ruleBlock.setConjunction(new Minimum());
    		ruleBlock.setDisjunction(new Maximum());
    		ruleBlock.setActivation(new Minimum());
    		ruleBlock.addRule(Rule.parse("if Criticallity is Low and Availability is Limit then IndDisp is Worst", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Low and Availability is Very_Low then IndDisp is Bad", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Low and Availability is Low then IndDisp is Average", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Low and Availability is Average then IndDisp is Good", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Low and Availability is High then IndDisp is Best", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Low and Availability is Perfect then IndDisp is Best", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Average and Availability is Limit then IndDisp is Worst", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Average and Availability is Very_Low then IndDisp is Worst", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Average and Availability is Low then IndDisp is Bad", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Average and Availability is Average then IndDisp is Average", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Average and Availability is High then IndDisp is Good", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Average and Availability is Perfect then IndDisp is Best", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is High and Availability is Limit then IndDisp is Worst", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is High and Availability is Very_Low then IndDisp is Worst", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is High and Availability is Low then IndDisp is Bad", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is High and Availability is Average then IndDisp is Average", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is High and Availability is High then IndDisp is Best", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is High and Availability is Perfect then IndDisp is Best", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Very_High and Availability is Limit then IndDisp is Worst", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Very_High and Availability is Very_Low then IndDisp is Worst", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Very_High and Availability is Low then IndDisp is Bad", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Very_High and Availability is Average then IndDisp is Bad", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Very_High and Availability is High then IndDisp is Good", engine));
    		ruleBlock.addRule(Rule.parse("if Criticallity is Very_High and Availability is Perfect then IndDisp is Best", engine));
    		engine.addRuleBlock(ruleBlock);
    		
    		StringBuilder status = new StringBuilder();
    		if (!engine.isReady(status))
    		throw new RuntimeException("Nao foi possivel gerar o arquivo. "
    		+ "O seguintes erros foram encontrados:\n"
    		+ status.toString());
    				
    		engine.setInputValue("Criticallity", crit);
    		engine.setInputValue("Availability", availability);
    		engine.process();
    
    		return String.valueOf(engine.getOutputValue("IndDisp"));
    	} 
    }

    I appreciate any help.

    #1638
    Unknown
    Member

    Below, the .fis code:

    [System]
    Name='Ind-Disp'
    Type='mamdani'
    Version=2.0
    NumInputs=2
    NumOutputs=1
    NumRules=24
    AndMethod='min'
    OrMethod='max'
    ImpMethod='min'
    AggMethod='max'
    DefuzzMethod='centroid'
    
    [Input1]
    Name='Criticallity'
    Range=[0 5]
    NumMFs=4
    MF1='Low':'trimf',[0 1 2]
    MF2='Average':'trimf',[1 2 3]
    MF3='High':'trimf',[2 3 4]
    MF4='Very_High':'trimf',[3 4 5]
    
    [Input2]
    Name='Availability'
    Range=[85 100]
    NumMFs=6
    MF1='Limit':'trimf',[90 90 95]
    MF2='Very_Low':'trimf',[90 95 98]
    MF3='Low':'trimf',[95 98 99]
    MF4='Average':'trimf',[98 99 99.9]
    MF5='High':'trimf',[99 99.9 100]
    MF6='Perfect':'trimf',[99.9 100 100]
    
    [Output1]
    Name='Ind-Disp.'
    Range=[-3 13]
    NumMFs=5
    MF1='Worst':'trimf',[-3 0 3]
    MF2='Bad':'trimf',[0 3 5]
    MF3='Average':'trimf',[3 5 7]
    MF4='Good':'trimf',[5 7 10]
    MF5='Best':'trimf',[7 10 13]
    
    [Rules]
    1 1, 1 (1) : 1
    1 2, 2 (1) : 1
    1 3, 3 (1) : 1
    1 4, 4 (1) : 1
    1 5, 5 (1) : 1
    1 6, 5 (1) : 1
    2 1, 1 (1) : 1
    2 2, 1 (1) : 1
    2 3, 2 (1) : 1
    2 4, 3 (1) : 1
    2 5, 4 (1) : 1
    2 6, 5 (1) : 1
    3 1, 1 (1) : 1
    3 2, 1 (1) : 1
    3 3, 2 (1) : 1
    3 4, 3 (1) : 1
    3 5, 5 (1) : 1
    3 6, 5 (1) : 1
    4 1, 1 (1) : 1
    4 2, 1 (1) : 1
    4 3, 2 (1) : 1
    4 4, 2 (1) : 1
    4 5, 4 (1) : 1
    4 6, 5 (1) : 1
    #1643

    Hi,

    you should use QtFuzzyLite to help you with this kind of issues.

    The term Limit and Perfect are not triangles but Ramps. Check in QtFuzzyLite the difference between Triangle and Ramp. Basically, Ramp yields a membership of 1.0 after the limits it is defined, whereas a Triangle does not.

    InputVariable: Availability
      enabled: true
      range: 85.000 100.000
      term: Limit Ramp 95.000 90.000
      term: Very_Low Triangle 90.000 95.000 98.000
      term: Low Triangle 95.000 98.000 99.000
      term: Average Triangle 98.000 99.000 99.900
      term: High Triangle 99.000 99.900 100.000
      term: Perfect Ramp 99.900 100.000
    
    #1660
    Unknown
    Member

    Hi,

    I’m very sorry to bother you. But your suggestion made me very close to the correct value.

    InputVariable inputVariable1 = new InputVariable();
    inputVariable1.setEnabled(true);
    inputVariable1.setName("Criticallity");
    inputVariable1.setRange(0.000, 5.000);
    inputVariable1.addTerm(new Triangle("Low", 0.000, 1.000, 2.000));
    inputVariable1.addTerm(new Triangle("Average", 1.000, 2.000, 3.000));
    inputVariable1.addTerm(new Triangle("High", 2.000, 3.000, 4.000));
    inputVariable1.addTerm(new Triangle("Very_High", 3.000, 4.000, 5.000));
    engine.addInputVariable(inputVariable1);
    
    InputVariable inputVariable2 = new InputVariable();
    inputVariable2.setEnabled(true);
    inputVariable2.setName("Availability");
    inputVariable2.setRange(85.000, 100.000);
    inputVariable2.addTerm(new Ramp("Limit", 95.000, 90.000));  
    inputVariable2.addTerm(new Triangle("Very_Low", 90.000, 95.000, 98.000));
    inputVariable2.addTerm(new Triangle("Low", 95.000, 98.000, 99.000));
    inputVariable2.addTerm(new Triangle("Average", 98.000, 99.000, 99.900));
    inputVariable2.addTerm(new Triangle("High", 99.000, 99.900, 100.000));
    inputVariable2.addTerm(new Ramp("Perfect", 99.900, 100.000));  
    engine.addInputVariable(inputVariable2);

    With this code, I enter 3.8 and 100 –> iDisp.CalcIndDisp(3.8, 100);
    and I get 9.999999999999995, but the result should be: 9.74 What other changes should I do?

    IndDisp Block
    indicator block Availability (IndDisp)

    Sorry again and thanks for help!

    #1668

    Hi vinimac,

    thank you for your post.

    The approximation issue you are experiencing may be due to a small bug in Triangle.java.

    Could you please try the following fix and compile jfuzzylite again?

    In Triangle.java, substitute line 75:

    if (Op.isLE(x, a) || Op.isGE(x, c))

    with

    if (Op.isLt(x, a) || Op.isGt(x, c))

    Instead of a <= or >=, the change is for < or >.

    Please let me know if this fixes your issue.

    Cheers.

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