Example 11: Sugeno controller¶
A first-order Sugeno heater controller on error and change of error.
Source¶
examples/11_sugeno_controller.py
"""First-order Sugeno heater controller on error and change of error."""
import math
from bulanik.inference import Linear, SugenoFIS, SugenoOutput
from bulanik.sets import LinguisticVariable, triangular
error = LinguisticVariable(
"e", (-5, 5), {"neg": triangular(-5, -5, 5), "pos": triangular(-5, 5, 5)}
)
d_error = LinguisticVariable(
"de", (-5, 5), {"neg": triangular(-5, -5, 5), "pos": triangular(-5, 5, 5)}
)
u = SugenoOutput(
"u",
{
"cool": Linear({"e": 0.5, "de": 0.2}, -1.0),
"hold": Linear({"e": 1.0}, 0.0),
"heat": Linear({"e": 2.0, "de": 0.5}, 1.0),
},
)
fis = SugenoFIS(
[error, d_error],
[u],
[
"IF e IS neg AND de IS neg THEN u IS cool",
"IF e IS neg AND de IS pos THEN u IS hold",
"IF e IS pos AND de IS neg THEN u IS hold",
"IF e IS pos AND de IS pos THEN u IS heat",
],
)
result = fis.evaluate({"e": 2, "de": -1})["u"]
# e=2: neg .3, pos .7 ; de=-1: neg .6, pos .4 ; min-AND strengths: .3, .3, .6, .4
# cool = -1 + 1 - .2 = -.2 ; hold = 2 ; hold = 2 ; heat = 1 + 4 - .5 = 4.5
# u = (.3*-.2 + .3*2 + .6*2 + .4*4.5) / 1.6 = 3.54 / 1.6 = 2.2125
assert math.isclose(result, 2.2125)
print(f"u(e=2, de=-1) = {result:.4f}")
Output¶
Run when this page is built:
u(e=2, de=-1) = 2.2125
What to notice¶
- Consequents are linear functions of the inputs, not fuzzy sets, so there is no defuzzification step.
- The output is the weighted average of the rule outputs, weighted by the firing strengths.
- The result is a single number, easy to check by hand.
Go further¶
- Guide: Sugeno and Tsukamoto
- API:
bulanik.inference
Run it yourself: python examples/11_sugeno_controller.py.