Skip to content

Commit 6252cdc

Browse files
authored
Fix: engine [input|output]_values (#76)
* Fix: engine [input|output]_values * Version update * Update version and history
1 parent 1128dba commit 6252cdc

File tree

8 files changed

+112
-15
lines changed

8 files changed

+112
-15
lines changed

HISTORY.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# Version 8.0.2
2+
3+
### Bug fixes
4+
5+
- Fix `engine.[input|output]_values`, which was not working correctly when manually setting variable values (issue #75).
6+
17
# Version 8.0.1
28

39
### Bug fixes
@@ -24,10 +30,10 @@
2430
- function `fl.to_float` converts any argument to a `float`, which was the behaviour of `fl.Op.scalar`.
2531
- linguistic terms `Arc` and `SemiEllipse`
2632
- indexable components:
27-
- `Engine`: get variables or rule blocks by name using square brackets, eg, `engine["light"].value`
28-
- `Variable`: get terms by name using square brackets, eg, `variable["low"].membership(value)`
29-
- `Factory`: get constructors and objects by name using square brackets,
30-
eg, `factory["Triangle"]()`, `factory["sin"](3.14)`
33+
- `Engine`: get variables or rule blocks by name using square brackets, eg, `engine["light"].value`
34+
- `Variable`: get terms by name using square brackets, eg, `variable["low"].membership(value)`
35+
- `Factory`: get constructors and objects by name using square brackets,
36+
eg, `factory["Triangle"]()`, `factory["sin"](3.14)`
3137
- class `Benchmark` to benchmark engines
3238
- `from __future__ import annotations` in every file to use better type annotations
3339
- class `library.Settings` to configure general settings in singleton `library.settings`

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# pyfuzzylite 8.0.1
1+
# pyfuzzylite 8.0.2
22

33
<img src="https://fuzzylite.github.io/pyfuzzylite/image/fuzzylite.svg" align="left" alt="fuzzylite">
44

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# pyfuzzylite 8.0.1
1+
# pyfuzzylite 8.0.2
22

33
***
44

fuzzylite/engine.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,9 @@ def input_values(self) -> ScalarArray:
323323
ValueError: when the dimensionality of values is greater than 2
324324
ValueError: when the number of columns in the values is different from the number of input variables
325325
"""
326-
return np.atleast_2d( # type:ignore
327-
np.array([v.value for v in self.input_variables])
328-
).T
326+
values = tuple(input_variable.value for input_variable in self.input_variables)
327+
result = np.column_stack(values) if values else np.array(values)
328+
return result
329329

330330
@input_values.setter
331331
def input_values(self, values: ScalarArray) -> None:
@@ -379,9 +379,9 @@ def output_values(self) -> ScalarArray:
379379
2D array of output values (rows) for each output variable (columns).
380380
"""
381381
# TODO: Maybe a property setter like input_values.
382-
return np.atleast_2d( # type:ignore
383-
np.array([v.value for v in self.output_variables])
384-
).T
382+
values = tuple(output_variable.value for output_variable in self.output_variables)
383+
result = np.column_stack(values) if values else np.array(values)
384+
return result
385385

386386
@property
387387
def values(self) -> ScalarArray:

fuzzylite/library.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ def version(self) -> str:
272272
Returns:
273273
version of the library
274274
"""
275-
__version__ = "8.0.1"
275+
__version__ = "8.0.2"
276276
return __version__
277277

278278

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
44

55
[tool.poetry]
66
name = "pyfuzzylite"
7-
version = "8.0.1"
7+
version = "8.0.2"
88
description = "a fuzzy logic control library in Python"
99
license = "Proprietary"
1010
readme = "README.md"

tests/test_engine.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,97 @@ def test_input_values_setter(self) -> None:
424424
),
425425
)
426426

427+
def test_input_values(self) -> None:
428+
"""Test the engine.input_values."""
429+
engine = fl.Engine("Test")
430+
np.testing.assert_equal(fl.array([]), engine.input_values)
431+
432+
engine = fl.Engine("Test", input_variables=[fl.InputVariable("A")])
433+
engine.input_variable(0).value = 0.6
434+
np.testing.assert_equal(fl.array([[0.6]]), engine.input_values)
435+
436+
engine.input_variable(0).value = fl.array([0.6, 0.7])
437+
np.testing.assert_equal(fl.array([[0.6], [0.7]]), engine.input_values)
438+
439+
engine = fl.Engine("Test", input_variables=[fl.InputVariable("A"), fl.InputVariable("B")])
440+
engine.input_variable(0).value = 0.6
441+
engine.input_variable(1).value = 0.2
442+
np.testing.assert_equal(fl.array([[0.6, 0.2]]), engine.input_values)
443+
444+
engine.input_variable(0).value = fl.array([0.6, 0.7])
445+
engine.input_variable(1).value = fl.array([0.2, 0.3])
446+
np.testing.assert_equal(fl.array([[0.6, 0.2], [0.7, 0.3]]), engine.input_values)
447+
448+
def test_output_values(self) -> None:
449+
"""Test the engine.output_values."""
450+
engine = fl.Engine("Test")
451+
np.testing.assert_equal(fl.array([]), engine.output_values)
452+
453+
engine = fl.Engine("Test", output_variables=[fl.OutputVariable("A")])
454+
engine.output_variable(0).value = 0.6
455+
np.testing.assert_equal(fl.array([[0.6]]), engine.output_values)
456+
457+
engine.output_variable(0).value = fl.array([0.6, 0.7])
458+
np.testing.assert_equal(fl.array([[0.6], [0.7]]), engine.output_values)
459+
460+
engine = fl.Engine(
461+
"Test", output_variables=[fl.OutputVariable("A"), fl.OutputVariable("B")]
462+
)
463+
engine.output_variable(0).value = 0.6
464+
engine.output_variable(1).value = 0.2
465+
np.testing.assert_equal(fl.array([[0.6, 0.2]]), engine.output_values)
466+
467+
engine.output_variable(0).value = fl.array([0.6, 0.7])
468+
engine.output_variable(1).value = fl.array([0.2, 0.3])
469+
np.testing.assert_equal(fl.array([[0.6, 0.2], [0.7, 0.3]]), engine.output_values)
470+
471+
def test_input_values_manual_bug(self) -> None:
472+
"""Test the bug raised in https://github.com/fuzzylite/pyfuzzylite/issues/75."""
473+
fll = """\
474+
Engine: ObstacleAvoidance
475+
InputVariable: obstacle
476+
enabled: true
477+
range: 0.000 1.000
478+
lock-range: false
479+
term: left Ramp 1.000 0.000
480+
term: right Ramp 0.000 1.000
481+
InputVariable: obstacle2
482+
enabled: true
483+
range: 0.000 1.000
484+
lock-range: false
485+
term: left Ramp 1.000 0.000
486+
term: right Ramp 0.000 1.000
487+
OutputVariable: tsSteer
488+
enabled: true
489+
range: 0.000 1.000
490+
lock-range: false
491+
aggregation: Maximum
492+
defuzzifier: WeightedAverage
493+
default: nan
494+
lock-previous: false
495+
term: right Linear 1 1 0
496+
term: left Linear 0 1 1
497+
RuleBlock: takagiSugeno
498+
enabled: true
499+
conjunction: Minimum
500+
disjunction: none
501+
implication: none
502+
activation: General
503+
rule: if obstacle is left and obstacle2 is left then tsSteer is right
504+
rule: if obstacle is left and obstacle2 is right then tsSteer is right"""
505+
engine = fl.FllImporter().from_string(fll)
506+
engine.input_variable(0).value = 0.2
507+
engine.input_variable(1).value = 0.6
508+
engine.process()
509+
np.testing.assert_allclose(0.8, engine.output_values)
510+
np.testing.assert_allclose(fl.array([[0.2, 0.6, 0.8]]), engine.values)
511+
512+
engine.input_variable(0).value = fl.array([0.2, 0.2])
513+
engine.input_variable(1).value = fl.array([0.6, 0.6])
514+
engine.process()
515+
np.testing.assert_allclose(fl.array([[0.8], [0.8]]), engine.output_values)
516+
np.testing.assert_allclose(fl.array([[0.2, 0.6, 0.8], [0.2, 0.6, 0.8]]), engine.values)
517+
427518
def test_repr(self) -> None:
428519
"""Tests repr."""
429520
code = fl.repr(SimpleDimmer().engine)

tests/test_library.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def test_library_exports_dir(self) -> None:
7676

7777
def test_library_vars(self) -> None:
7878
"""Test the library variables."""
79-
__version__ = "8.0.1"
79+
__version__ = "8.0.2"
8080
self.assertEqual(fl.__name__, "fuzzylite")
8181
self.assertEqual(fl.__version__, __version__)
8282
self.assertEqual(fl.__doc__, fl.information.description)

0 commit comments

Comments
 (0)