Fuzzy Logic

Fuzzy logic, introduced by Lotfi Zadeh in 1965, replaces the crisp true/false of classical logic with degrees of truth in [0, 1]. It is designed for vague, graded concepts that people use naturally — "warm", "fast", "high risk" — and lets you build controllers and decision rules directly from linguistic statements such as IF temperature is hot AND humidity is high THEN fan speed is fast. It is widely used in embedded control (appliances, HVAC, automotive subsystems, cameras), in scoring systems, and in fuzzy matching of records.

Part of Knowledge & Reasoning. It extends Rule-based Systems with graded conditions and contrasts with Bayesian Networks, which model uncertainty rather than vagueness.


1. Fuzzy Sets and Membership Functions

Temperature: Cold, Warm, Hot (Overlapping Membership) 0 1 Cold Warm Hot 27 °C: warm 0.3, hot 0.5 010203040 °C A single reading belongs partly to two sets at once; there is no sharp boundary.

A classical set has a characteristic function that returns 0 or 1. A fuzzy set A on a universe X has a membership function μA: X → [0, 1]. Common shapes are triangular, trapezoidal, Gaussian and sigmoid. A linguistic variable such as temperature is partitioned into overlapping terms (cold, warm, hot); overlap is what makes the controller's output change smoothly as input changes. Converting a crisp input into memberships is called fuzzification. The figure uses the same membership functions as the code in section 5.

2. Fuzzy Operators

Logical connectives generalize to functions on [0, 1]. AND uses a t-norm, OR a t-conorm, NOT a complement:

ConnectiveZadeh (min/max)Product familyŁukasiewicz
A AND Bmin(a, b)a · bmax(0, a + b − 1)
A OR Bmax(a, b)a + b − a·bmin(1, a + b)
NOT A1 − a1 − a1 − a

All reduce to Boolean logic on 0/1 inputs. Note that the law of the excluded middle fails: with min/max, A OR NOT A for a = 0.5 is only 0.5. Hedges modify terms: "very A" is commonly μ2, "somewhat A" is √μ.

3. Fuzzy Inference: Mamdani and Sugeno

Fuzzy Inference System Pipeline Crisp input 27 °C, 70 % Fuzzify μ for each term Rule evaluation AND/OR → strength Aggregate clip and max Defuzzify crisp fan % Mamdani: rule outputs are fuzzy sets, defuzzified by centroid (interpretable). Sugeno: rule outputs are crisp functions, combined by weighted average (fast).

A fuzzy inference system (FIS) runs every rule in parallel. Each rule's firing strength is its antecedent evaluated with the chosen t-norm. In a Mamdani system the consequent is a fuzzy set, clipped (min) or scaled (product) by the firing strength; all clipped sets are aggregated with max into one output fuzzy set. In a Takagi-Sugeno-Kang (Sugeno) system each consequent is a crisp function such as z = p·x + q·y + r, and the output is the strength-weighted average of the rule outputs, with no separate defuzzification step. Sugeno systems are cheaper, easier to tune from data, and are the basis of ANFIS (adaptive neuro-fuzzy inference), which learns membership parameters by gradient descent.

4. Defuzzification

Centroid of the Aggregated Output Set centroid z* "slow" clipped at 0.4 "fast" clipped at 0.6 0 % 100 % fan speed z* = ∫ μ(z) · z dz / ∫ μ(z) dz

Defuzzification turns the aggregated output set into one actionable number. The centroid (center of gravity) is the most common and gives smooth behavior. Alternatives are the bisector, mean of maxima, and smallest or largest of maxima; maxima-based methods are cheaper but can jump abruptly when rule strengths change.

5. Python: A Fan-Speed Controller

import numpy as np

def tri(x, a, b, c):
    """Triangular membership; a == b or b == c gives a shoulder."""
    x = np.asarray(x, dtype=float)
    left  = np.ones_like(x) if b == a else (x - a) / (b - a)
    right = np.ones_like(x) if c == b else (c - x) / (c - b)
    return np.clip(np.minimum(left, right), 0, 1)

# Input terms
temp = {"cold": (0, 0, 17), "warm": (10, 20, 30), "hot": (22, 32, 32)}
hum  = {"dry":  (0, 0, 60), "humid": (40, 100, 100)}
# Output universe and terms (fan speed %)
z = np.linspace(0, 100, 501)
fan = {"slow": tri(z, 0, 0, 50), "medium": tri(z, 20, 50, 80), "fast": tri(z, 50, 100, 100)}

rules = [  # (temp term, humidity term or None, output term)
    ("cold", None,    "slow"),
    ("warm", "dry",   "medium"),
    ("warm", "humid", "fast"),
    ("hot",  None,    "fast"),
]

def control(t, h):
    mt = {k: float(tri(t, *v)) for k, v in temp.items()}
    mh = {k: float(tri(h, *v)) for k, v in hum.items()}
    agg = np.zeros_like(z)
    for tt, ht, out in rules:
        strength = mt[tt] if ht is None else min(mt[tt], mh[ht])   # AND = min
        agg = np.maximum(agg, np.minimum(strength, fan[out]))       # clip, then max
    if agg.sum() == 0:
        return 0.0
    return float((agg * z).sum() / agg.sum())                       # centroid

for t, h in [(12, 30), (21, 30), (21, 85), (35, 50)]:
    print(f"temp={t:>2} C  humidity={h:>2}%  ->  fan={control(t, h):5.1f}%")

For larger systems, scikit-fuzzy provides membership functions, rule objects and a control-system simulator; simpful supports both Mamdani and Sugeno.

6. Fuzzy vs Probability

Both use numbers in [0, 1], but they answer different questions. Probability measures uncertainty about a crisp fact: "there is a 0.7 chance it will be above 25 °C tomorrow". Membership measures the degree to which a known fact fits a vague concept: "25 °C is 0.7 hot". Observing the outcome resolves probability; it does not resolve vagueness. The two can be combined (fuzzy random variables, possibility theory), but mixing them casually leads to incoherent models.

7. When to Use, and Pitfalls

8. Worked Example: Tracing One Input

Take the fan controller above with temp = 21 °C and humidity = 30%. Fuzzification: the triangle warm = (10, 20, 30) gives 21 °C a membership of 0.9, while cold and hot are both 0. For humidity, dry = (0, 0, 60) gives 0.5 and humid gives 0. Rule evaluation: only "warm AND dry → medium" fires, with strength min(0.9, 0.5) = 0.5. Implication: the medium output triangle is clipped at height 0.5, producing a trapezoid. Aggregation: with one active rule, the aggregate is that trapezoid. Defuzzification: the trapezoid is symmetric around 50, so its centroid, the fan speed, is 50%.

Raise humidity to 85% and the picture changes. Now humid is 0.75 and dry is 0, so "warm AND humid → fast" fires with strength min(0.9, 0.75) = 0.75. The fast shoulder clipped at 0.75 has a centroid near 82.6%, so the fan speeds up smoothly rather than jumping between fixed settings. Between those two humidity values, both rules fire partially and the output slides continuously, which is exactly the property that makes fuzzy controllers pleasant to tune.

9. Designing the Rule Base

Rule Base as a Grid (Fuzzy Associative Memory) coldwarmhot dryhumid slow medium fast slow fast fast temperature increases each cell = one rule 3 x 2 = 6 rules The four rules in the code cover these six cells; "cold" and "hot" ignore humidity.

Writing the rules as a grid, one axis per input and one cell per combination of terms, makes gaps and contradictions visible at a glance. Each cell holds the consequent term. Neighbouring cells should usually differ by at most one output term; a jump from "slow" to "fast" between adjacent cells produces a steep, twitchy control surface. Practical guidance:

10. Further Reading