Source code for fuzzy_set.triangular_fuzzy_number

# © 2025 Nokia
# Licensed under the BSD 3-Clause License
# SPDX-License-Identifier: BSD-3-Clause

from fuzzy_set import TrapezoidalFuzzyNumber


[docs] class TriangularFuzzyNumber(TrapezoidalFuzzyNumber): """ A *Triangular Fuzzy Number* is a Trapezoidal Fuzzy Number whose core is reduced to a single value. Therefore, it is piecewise linear and continuous and has a triangular shape. As a consequence, it is fully characterized by a triple of real numbers, denoted by :math:`[x_1, x_2, x_3]`, where: - :math:`a_1 \\le a_2 \\le a_3`; - :math:`[a_1, a_3]` is its support; - :math:`\\{a_2\\}` is its core. **Example:** >>> from fuzzy_set import TriangularFuzzyNumber >>> t1 = TriangularFuzzyNumber(1, 3, 10) >>> t2 = TriangularFuzzyNumber(2, 5, 8) >>> t1 + t2 TriangularFuzzyNumber<(3, 8, 18)> >>> t1 - t2 TriangularFuzzyNumber<(-7, -2, 8)> >>> t1 * t2 TriangularFuzzyNumber<(2, 15, 80)> >>> t1 / t2 TriangularFuzzyNumber<(0.125, 0.6, 5.0)> **Example:** .. code-block:: python import matplotlib.pyplot as plt from operator import __add__, __sub__, __mul__, __truediv__ (fig, axs) = plt.subplots(2, 2) for (ij, (op, opname)) in { (0, 0): (__add__, "+"), (0, 1): (__sub__, "-"), (1, 0): (__mul__, "\\cdot"), (1, 1): (__truediv__, "/"), }.items(): ax = axs[ij] title = f"$a_1 {opname} a_2$" ax.set_title(title) t1.plot(ax=ax, label="$a_1$") t2.plot(ax=ax, label="$a_2$") op(t1, t2).plot(ax=axs[ij], label=title) ax.grid() ax.legend() ax.legend(bbox_to_anchor=(1, 0.5), loc="center left") plt.tight_layout() """ def __init__(self, a1: float, a2: float, a3: float): super().__init__(x1=a1, x2=a2, x3=a2, x4=a3) @property def a1(self) -> float: return self.x1 @property def a2(self) -> float: return self.x2 @property def a3(self) -> float: return self.x4 @a1.setter def a1(self, value: float): self.x1 = value @a2.setter def a2(self, value: float): self.x2 = self.x3 = value @a3.setter def a3(self, value: float): self.x4 = value def __add__( self, other: "TriangularFuzzyNumber" ) -> "TriangularFuzzyNumber": """ Adds this :math:`[a_1, a_2, a_3]` TFN and another :math:`[b_1, b_2, b_3]` TFN. Args: other (TriangularFuzzyNumber): The other TFN. Returns: The resulting :math:`[a_1 + b_1, a_2 + b_2, a_3 + b_3]` TFN. """ return self.__class__( self.a1 + other.a1, self.a2 + other.a2, self.a3 + other.a3, ) def __sub__( self, other: "TriangularFuzzyNumber" ) -> "TriangularFuzzyNumber": """ Subtracts this :math:`[a_1, a_2, a_3]` TFN and another :math:`[b_1, b_2, b_3]` TFN. Args: other (TriangularFuzzyNumber): The other TFN. Returns: The resulting :math:`[a_1 - b_3, a_2 - b_2, a_3 - b_1]` TFN. """ return self.__class__( self.a1 - other.a3, self.a2 - other.a2, self.a3 - other.a1, ) def __mul__( self, other: "TriangularFuzzyNumber" ) -> "TriangularFuzzyNumber": """ Approximates the multiplication of this :math:`[a_1, a_2, a_3]` TFN and another :math:`[b_1, b_2, b_3]` TFN. Args: other (TriangularFuzzyNumber): The other TFN. Returns: The resulting approximated :math:`[a_1 \\cdot b_1, a_2 \\cdot b_2, a_3 \\cdot b_3]` TFN. """ return self.__class__( self.a1 * other.a1, self.a2 * other.a2, self.a3 * other.a3, ) def __truediv__( self, other: "TriangularFuzzyNumber" ) -> "TriangularFuzzyNumber": """ Approximates the division of this :math:`[a_1, a_2, a_3]` TFN and another :math:`[b_1, b_2, b_3]` TFN. Args: other (TriangularFuzzyNumber): The other TFN. Returns: The resulting approximated :math:`[a_1 / b_3 , a_2 / b_2 , a_3 / b_1]` TFN. """ return self.__class__( self.a1 / other.a3, self.a2 / other.a2, self.a3 / other.a1 ) def __repr__(self) -> str: return ( f"{self.__class__.__name__}" f"<{self.a1, self.a2, self.a3}>" )