Skip to content

Mamdani inference

Mamdani consequents are fuzzy sets (output is term). For each call:

  1. Evaluate every rule's antecedent → a firing strength.
  2. Shape the consequent set over the output universe via the implication operator (min clips, prod scales).
  3. Aggregate shaped sets per output variable (s-norm, default max).
  4. Defuzzify to a crisp value.
import fuzzytool as fz

sys = fz.Mamdani(
    tnorm="min", snorm="max",     # antecedent connectives
    implication="min",            # "min" (clip) or "prod" (scale)
    aggregation="max",            # combine shaped output sets
    defuzz="centroid",            # see the defuzzification guide
)

Multiple outputs

Add rules whose consequents reference different output variables; calling the system returns a dict keyed by output name (a single output returns a float).

sys.rule(x["hi"], y1["a"])
sys.rule(x["lo"], y2["b"])
sys(x=0.7)   # -> {"y1": ..., "y2": ...}

When no rule fires

If an input activates no rule, the aggregated output set is empty and there is nothing to defuzzify. The on_no_rule policy decides what happens, and it is applied identically by __call__ and predict:

on_no_rule Result for an unfired output
"mid" (default) midpoint of the output universe
"nan" float("nan")
"raise" raises ValueError
sys = fz.Mamdani(on_no_rule="nan")   # unfired samples come back as NaN

The same option exists on TSK and Tsukamoto (with "nan" — not "mid" — as their default, since they have no output universe).