fuzzy_logic.fuzzy_set_operations ================================ .. py:module:: fuzzy_logic.fuzzy_set_operations .. autoapi-nested-parse:: 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: - https://en.wikipedia.org/wiki/Fuzzy_set#Fuzzy_set_operations - https://en.wikipedia.org/wiki/Fuzzy_logic - https://en.wikipedia.org/wiki/T-norm 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 ---------- .. autoapisummary:: fuzzy_logic.fuzzy_set_operations.universe Functions --------- .. autoapisummary:: fuzzy_logic.fuzzy_set_operations.algebraic_product fuzzy_logic.fuzzy_set_operations.algebraic_sum fuzzy_logic.fuzzy_set_operations.bounded_difference fuzzy_logic.fuzzy_set_operations.bounded_sum fuzzy_logic.fuzzy_set_operations.fuzzy_complement fuzzy_logic.fuzzy_set_operations.fuzzy_difference fuzzy_logic.fuzzy_set_operations.fuzzy_intersection fuzzy_logic.fuzzy_set_operations.fuzzy_union fuzzy_logic.fuzzy_set_operations.triangular_membership Module Contents --------------- .. py:function:: 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 ]) .. py:function:: 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. ]) .. py:function:: 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]) .. py:function:: 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. ]) .. py:function:: 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. ]) .. py:function:: 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]) .. py:function:: 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]) .. py:function:: 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]) .. py:function:: 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]) .. py:data:: universe