fuzzy_logic.fuzzy_set_operations

Zadeh’s fuzzy-set operators on membership vectors.

A fuzzy set over a universe of discourse X is described by a membership function mu: X -> [0, 1]. Once the universe is sampled on a grid, that function becomes a NumPy vector of membership degrees and the classic set operations reduce to element-wise arithmetic.

This module implements the standard (Zadeh) operators plus a few common alternatives. Unlike fuzzy_operations.FuzzySet – which stores a triangular fuzzy number by its three defining points – the functions here work on the sampled membership vectors directly, so they apply to any membership shape (triangular, trapezoidal, Gaussian, …).

References:
Requirements:
  • numpy

Originally contributed as a scikit-fuzzy demo by Jigyasa Gandhi; rewritten here to be dependency-free (NumPy only) and covered by doctests.

Attributes

universe

Functions

algebraic_product(→ numpy.typing.NDArray[numpy.float64])

Algebraic product: mu_A * mu_B.

algebraic_sum(→ numpy.typing.NDArray[numpy.float64])

Algebraic (probabilistic) sum: mu_A + mu_B - mu_A * mu_B.

bounded_difference(→ numpy.typing.NDArray[numpy.float64])

Bounded difference (Lukasiewicz t-norm): max(0, mu_A + mu_B - 1).

bounded_sum(→ numpy.typing.NDArray[numpy.float64])

Bounded sum (Lukasiewicz t-conorm): min(1, mu_A + mu_B).

fuzzy_complement(→ numpy.typing.NDArray[numpy.float64])

Complement (logical NOT): 1 - mu_A(x).

fuzzy_difference(→ numpy.typing.NDArray[numpy.float64])

Difference A / B: min(mu_A(x), 1 - mu_B(x)).

fuzzy_intersection(→ numpy.typing.NDArray[numpy.float64])

Intersection (logical AND): min(mu_A(x), mu_B(x)).

fuzzy_union(→ numpy.typing.NDArray[numpy.float64])

Union (logical OR): max(mu_A(x), mu_B(x)).

triangular_membership(...)

Sample a triangular membership function on the grid.

Module Contents

fuzzy_logic.fuzzy_set_operations.algebraic_product(membership_a: numpy.typing.NDArray[numpy.float64], membership_b: numpy.typing.NDArray[numpy.float64]) numpy.typing.NDArray[numpy.float64]

Algebraic product: mu_A * mu_B.

>>> algebraic_product(np.array([0.5, 1.0]), np.array([0.5, 0.2]))
array([0.25, 0.2 ])
fuzzy_logic.fuzzy_set_operations.algebraic_sum(membership_a: numpy.typing.NDArray[numpy.float64], membership_b: numpy.typing.NDArray[numpy.float64]) numpy.typing.NDArray[numpy.float64]

Algebraic (probabilistic) sum: mu_A + mu_B - mu_A * mu_B.

>>> algebraic_sum(np.array([0.5, 1.0]), np.array([0.5, 0.2]))
array([0.75, 1.  ])
fuzzy_logic.fuzzy_set_operations.bounded_difference(membership_a: numpy.typing.NDArray[numpy.float64], membership_b: numpy.typing.NDArray[numpy.float64]) numpy.typing.NDArray[numpy.float64]

Bounded difference (Lukasiewicz t-norm): max(0, mu_A + mu_B - 1).

>>> bounded_difference(np.array([0.5, 0.8]), np.array([0.2, 0.7]))
array([0. , 0.5])
fuzzy_logic.fuzzy_set_operations.bounded_sum(membership_a: numpy.typing.NDArray[numpy.float64], membership_b: numpy.typing.NDArray[numpy.float64]) numpy.typing.NDArray[numpy.float64]

Bounded sum (Lukasiewicz t-conorm): min(1, mu_A + mu_B).

>>> bounded_sum(np.array([0.5, 0.8]), np.array([0.2, 0.7]))
array([0.7, 1. ])
fuzzy_logic.fuzzy_set_operations.fuzzy_complement(membership: numpy.typing.NDArray[numpy.float64]) numpy.typing.NDArray[numpy.float64]

Complement (logical NOT): 1 - mu_A(x).

>>> fuzzy_complement(np.array([0.0, 0.3, 1.0]))
array([1. , 0.7, 0. ])
fuzzy_logic.fuzzy_set_operations.fuzzy_difference(membership_a: numpy.typing.NDArray[numpy.float64], membership_b: numpy.typing.NDArray[numpy.float64]) numpy.typing.NDArray[numpy.float64]

Difference A / B: min(mu_A(x), 1 - mu_B(x)).

>>> fuzzy_difference(np.array([0.6, 0.4]), np.array([0.2, 0.9]))
array([0.6, 0.1])
fuzzy_logic.fuzzy_set_operations.fuzzy_intersection(membership_a: numpy.typing.NDArray[numpy.float64], membership_b: numpy.typing.NDArray[numpy.float64]) numpy.typing.NDArray[numpy.float64]

Intersection (logical AND): min(mu_A(x), mu_B(x)).

>>> fuzzy_intersection(np.array([0.2, 0.7]), np.array([0.5, 0.1]))
array([0.2, 0.1])
fuzzy_logic.fuzzy_set_operations.fuzzy_union(membership_a: numpy.typing.NDArray[numpy.float64], membership_b: numpy.typing.NDArray[numpy.float64]) numpy.typing.NDArray[numpy.float64]

Union (logical OR): max(mu_A(x), mu_B(x)).

>>> fuzzy_union(np.array([0.2, 0.7]), np.array([0.5, 0.1]))
array([0.5, 0.7])
fuzzy_logic.fuzzy_set_operations.triangular_membership(grid: numpy.typing.NDArray[numpy.float64], left: float, peak: float, right: float) numpy.typing.NDArray[numpy.float64]

Sample a triangular membership function on the grid.

The membership rises linearly from 0 at left to 1 at peak and falls back to 0 at right.

>>> grid = np.array([0.0, 25.0, 50.0])
>>> triangular_membership(grid, 0, 25, 50)
array([0., 1., 0.])
>>> triangular_membership(np.array([10.0, 12.5]), 0, 25, 50)
array([0.4, 0.5])
fuzzy_logic.fuzzy_set_operations.universe