Python/fuzzy_logic/fuzzy_operations.py
Shreya123714 f2436318ce
Add FuzzySet Class for Triangular Fuzzy Sets (#11036)
* Added Opertation for triangular fuzzy sets

* Added Sources

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix the bug , for which test were failing

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add type hints and improve parameter names

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add Test For fuzzy_operations.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix the bug in fuzzy_operations.py

* Add test_fuzzy_logic.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix the bug in fuzzy_operations.py & deleted test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fixed the typo error

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Again done

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* corrected wrong intendation due to which test fail

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* bug fixed

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add test_fuzzy_logic

* Modified fuzzy_operations.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fixed the bug, made a FuzzySet dataclass

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Replaced assertEqual of unittest to assert python

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* lets see

* Changed test

* orderd the import statements

* Add docstring and dataclass the FuzzySet

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update fuzzy_operations.py

* Delete fuzzy_logic/test_fuzzy_logic.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* https://en.wikipedia.org/wiki/Fuzzy_set

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
2023-10-28 20:32:12 +02:00

196 lines
5.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
By @Shreya123714
https://en.wikipedia.org/wiki/Fuzzy_set
"""
from __future__ import annotations
from dataclasses import dataclass
import matplotlib.pyplot as plt
import numpy as np
@dataclass
class FuzzySet:
"""
A class for representing and manipulating triangular fuzzy sets.
Attributes:
name: The name or label of the fuzzy set.
left_boundary: The left boundary of the fuzzy set.
peak: The peak (central) value of the fuzzy set.
right_boundary: The right boundary of the fuzzy set.
Methods:
membership(x): Calculate the membership value of an input 'x' in the fuzzy set.
union(other): Calculate the union of this fuzzy set with another fuzzy set.
intersection(other): Calculate the intersection of this fuzzy set with another.
complement(): Calculate the complement (negation) of this fuzzy set.
plot(): Plot the membership function of the fuzzy set.
>>> sheru = FuzzySet("Sheru", 0.4, 1, 0.6)
>>> sheru
FuzzySet(name='Sheru', left_boundary=0.4, peak=1, right_boundary=0.6)
>>> str(sheru)
'Sheru: [0.4, 1, 0.6]'
>>> siya = FuzzySet("Siya", 0.5, 1, 0.7)
>>> siya
FuzzySet(name='Siya', left_boundary=0.5, peak=1, right_boundary=0.7)
# Complement Operation
>>> sheru.complement()
FuzzySet(name='¬Sheru', left_boundary=0.4, peak=0.6, right_boundary=0)
>>> siya.complement() # doctest: +NORMALIZE_WHITESPACE
FuzzySet(name='¬Siya', left_boundary=0.30000000000000004, peak=0.5,
right_boundary=0)
# Intersection Operation
>>> siya.intersection(sheru)
FuzzySet(name='Siya ∩ Sheru', left_boundary=0.5, peak=0.6, right_boundary=1.0)
# Membership Operation
>>> sheru.membership(0.5)
0.16666666666666663
>>> sheru.membership(0.6)
0.0
# Union Operations
>>> siya.union(sheru)
FuzzySet(name='Siya Sheru', left_boundary=0.4, peak=0.7, right_boundary=1.0)
"""
name: str
left_boundary: float
peak: float
right_boundary: float
def __str__(self) -> str:
"""
>>> FuzzySet("fuzzy_set", 0.1, 0.2, 0.3)
FuzzySet(name='fuzzy_set', left_boundary=0.1, peak=0.2, right_boundary=0.3)
"""
return (
f"{self.name}: [{self.left_boundary}, {self.peak}, {self.right_boundary}]"
)
def complement(self) -> FuzzySet:
"""
Calculate the complement (negation) of this fuzzy set.
Returns:
FuzzySet: A new fuzzy set representing the complement.
>>> FuzzySet("fuzzy_set", 0.1, 0.2, 0.3).complement()
FuzzySet(name='¬fuzzy_set', left_boundary=0.7, peak=0.9, right_boundary=0.8)
"""
return FuzzySet(
f"¬{self.name}",
1 - self.right_boundary,
1 - self.left_boundary,
1 - self.peak,
)
def intersection(self, other) -> FuzzySet:
"""
Calculate the intersection of this fuzzy set
with another fuzzy set.
Args:
other: Another fuzzy set to intersect with.
Returns:
A new fuzzy set representing the intersection.
>>> FuzzySet("a", 0.1, 0.2, 0.3).intersection(FuzzySet("b", 0.4, 0.5, 0.6))
FuzzySet(name='a ∩ b', left_boundary=0.4, peak=0.3, right_boundary=0.35)
"""
return FuzzySet(
f"{self.name}{other.name}",
max(self.left_boundary, other.left_boundary),
min(self.right_boundary, other.right_boundary),
(self.peak + other.peak) / 2,
)
def membership(self, x: float) -> float:
"""
Calculate the membership value of an input 'x' in the fuzzy set.
Returns:
The membership value of 'x' in the fuzzy set.
>>> a = FuzzySet("a", 0.1, 0.2, 0.3)
>>> a.membership(0.09)
0.0
>>> a.membership(0.1)
0.0
>>> a.membership(0.11)
0.09999999999999995
>>> a.membership(0.4)
0.0
>>> FuzzySet("A", 0, 0.5, 1).membership(0.1)
0.2
>>> FuzzySet("B", 0.2, 0.7, 1).membership(0.6)
0.8
"""
if x <= self.left_boundary or x >= self.right_boundary:
return 0.0
elif self.left_boundary < x <= self.peak:
return (x - self.left_boundary) / (self.peak - self.left_boundary)
elif self.peak < x < self.right_boundary:
return (self.right_boundary - x) / (self.right_boundary - self.peak)
msg = f"Invalid value {x} for fuzzy set {self}"
raise ValueError(msg)
def union(self, other) -> FuzzySet:
"""
Calculate the union of this fuzzy set with another fuzzy set.
Args:
other (FuzzySet): Another fuzzy set to union with.
Returns:
FuzzySet: A new fuzzy set representing the union.
>>> FuzzySet("a", 0.1, 0.2, 0.3).union(FuzzySet("b", 0.4, 0.5, 0.6))
FuzzySet(name='a b', left_boundary=0.1, peak=0.6, right_boundary=0.35)
"""
return FuzzySet(
f"{self.name} {other.name}",
min(self.left_boundary, other.left_boundary),
max(self.right_boundary, other.right_boundary),
(self.peak + other.peak) / 2,
)
def plot(self):
"""
Plot the membership function of the fuzzy set.
"""
x = np.linspace(0, 1, 1000)
y = [self.membership(xi) for xi in x]
plt.plot(x, y, label=self.name)
if __name__ == "__main__":
from doctest import testmod
testmod()
a = FuzzySet("A", 0, 0.5, 1)
b = FuzzySet("B", 0.2, 0.7, 1)
a.plot()
b.plot()
plt.xlabel("x")
plt.ylabel("Membership")
plt.legend()
plt.show()
union_ab = a.union(b)
intersection_ab = a.intersection(b)
complement_a = a.complement()
union_ab.plot()
intersection_ab.plot()
complement_a.plot()
plt.xlabel("x")
plt.ylabel("Membership")
plt.legend()
plt.show()