Skip to content

Commit 7b3e4a9

Browse files
authored
Fix: output variable can set default values when the output is a single scalar (#92)
1 parent 57ff18e commit 7b3e4a9

File tree

2 files changed

+88
-1
lines changed

2 files changed

+88
-1
lines changed

fuzzylite/variable.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,8 @@ def defuzzify(self) -> None:
532532

533533
# Applying default values
534534
if not np.isnan(self.default_value):
535-
value[np.isnan(value)] = self.default_value # type: ignore
535+
value = np.atleast_1d(value)
536+
value[np.isnan(value)] = self.default_value
536537

537538
# Committing the value
538539
self.value = value

tests/test_issues.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import fuzzylite as fl
2+
import unittest
3+
import numpy as np
4+
5+
6+
class TestIssue91(unittest.TestCase):
7+
"""
8+
Test case for https://github.com/fuzzylite/pyfuzzylite/issues/91
9+
"""
10+
11+
def engine(self) -> fl.Engine:
12+
fll = """
13+
Engine: tipper
14+
description: (service and food) -> (tip)
15+
InputVariable: service
16+
description: quality of service
17+
enabled: true
18+
range: 0.000 10.000
19+
lock-range: true
20+
term: poor Discrete 0.000 1.000 2.500 1.000 5.000 0.000 10.000 0.000
21+
term: good Discrete 0.000 0.000 2.500 0.000 5.000 1.000 7.500 0.000 10.000 0.000
22+
term: excellent Discrete 0.000 0.000 5.000 0.000 7.500 1.000 10.000 1.000
23+
InputVariable: food
24+
description: quality of food
25+
enabled: true
26+
range: 0.000 10.000
27+
lock-range: true
28+
term: rancid Discrete 0.000 1.000 2.500 1.000 7.500 0.000 10.000 0.000
29+
term: delicious Discrete 0.000 0.000 2.500 0.000 7.500 1.000 10.000 1.000
30+
OutputVariable: mTip
31+
description: tip based on Mamdani inference
32+
enabled: true
33+
range: 0.000 30.000
34+
lock-range: false
35+
aggregation: Maximum
36+
defuzzifier: Centroid 100
37+
default: 0.0
38+
lock-previous: false
39+
term: cheap Discrete 0.000 0.000 5.000 1.000 10.000 0.000 30.000 0.000
40+
term: average Discrete 0.000 0.000 10.000 0.000 15.000 1.000 20.000 0.000 30.000 0.000
41+
term: generous Discrete 0.000 0.000 20.000 0.000 25.000 1.000 30.000 0.000
42+
OutputVariable: tsTip
43+
description: tip based on Takagi-Sugeno inference
44+
enabled: true
45+
range: 0.000 30.000
46+
lock-range: false
47+
aggregation: none
48+
defuzzifier: WeightedAverage TakagiSugeno
49+
default: 0.0
50+
lock-previous: false
51+
term: cheap Constant 5.000
52+
term: average Constant 15.000
53+
term: generous Constant 25.000
54+
RuleBlock: mamdani
55+
description: Mamdani inference
56+
enabled: true
57+
conjunction: AlgebraicProduct
58+
disjunction: AlgebraicSum
59+
implication: Minimum
60+
activation: General
61+
rule: if service is poor or food is rancid then mTip is cheap
62+
rule: if service is good then mTip is average
63+
rule: if service is excellent or food is delicious then mTip is generous with 0.5
64+
rule: if service is excellent and food is delicious then mTip is generous with 1.0
65+
RuleBlock: takagiSugeno
66+
description: Takagi-Sugeno inference
67+
enabled: true
68+
conjunction: AlgebraicProduct
69+
disjunction: AlgebraicSum
70+
implication: none
71+
activation: General
72+
rule: if service is poor or food is rancid then tsTip is cheap
73+
rule: if service is good then tsTip is average
74+
rule: if service is excellent or food is delicious then tsTip is generous with 0.5
75+
rule: if service is excellent and food is delicious then tsTip is generous with 1.0
76+
"""
77+
return fl.FllImporter().from_string(fll)
78+
79+
def test_issue_91(self) -> None:
80+
# "'numpy.float64' object does not support item assignment"
81+
engine = self.engine()
82+
engine.variable("food").value = 10
83+
engine.variable("service").value = 10
84+
engine.process()
85+
np.testing.assert_almost_equal(engine.variable("mTip").value, 25.00104979)
86+
np.testing.assert_almost_equal(engine.variable("tsTip").value, 25)

0 commit comments

Comments
 (0)