home › Forums › # Technical Support › jfuzzylite with two input values
- This topic has 10 replies, 2 voices, and was last updated 8 years, 7 months ago by
Unknown.
-
AuthorPosts
-
November 23, 2014 at 11:21 #1515
Unknown
MemberHi,
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.
November 23, 2014 at 11:40 #1517Unknown
MemberExample:
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
November 24, 2014 at 11:11 #1520Juan Rada-Vilela (admin)
KeymasterHi,
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,
November 24, 2014 at 12:06 #1521Juan Rada-Vilela (admin)
KeymasterHi,
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.
November 25, 2014 at 12:49 #1524Unknown
MemberHi 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
January 23, 2015 at 11:43 #1637Unknown
MemberHi 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.
January 23, 2015 at 11:47 #1638Unknown
MemberBelow, 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
January 26, 2015 at 14:25 #1643Juan Rada-Vilela (admin)
KeymasterHi,
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
February 10, 2015 at 11:22 #1660Unknown
MemberHi,
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?
indicator block Availability (IndDisp)Sorry again and thanks for help!
February 15, 2015 at 07:38 #1668Juan Rada-Vilela (admin)
KeymasterHi 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.
-
AuthorPosts
- You must be logged in to reply to this topic.