Source code for pyifdm.IFS.ifs

# Copyright (c) 2023 Jakub Więckowski

import numpy as np

[docs] class IFS: """ Represents an Intuitionistic Fuzzy Set (IFS) with membership, non-membership, and uncertainty values. Parameters: - membership (float): The degree to which an element belongs to the set. - non_membership (float): The degree to which an element does not belong to the set. - uncertainty (float, optional): The degree of uncertainty in the membership assignment. If not provided, it is calculated as 1 - membership - non_membership. Methods: - __and__(self, other): Intersection operator for IFS. - __or__(self, other): Union operator for IFS. - __invert__(self): Complement operator for IFS. - owa_aggregation(self, weights): Ordered Weighted Averaging (OWA) aggregation operator for IFS. Example: ``` # Example Usage: ifs1 = IFS(0.6, 0.2) ifs2 = IFS(0.8, 0.1) intersection_result = ifs1 & ifs2 union_result = ifs1 | ifs2 complement_result = ~ifs1 owa_weights = [0.3, 0.4, 0.3] owa_result = ifs1.owa_aggregation(owa_weights) ``` The IFS class supports standard set operations and aggregation, providing a versatile representation for handling uncertainty and imprecision in decision-making. """
[docs] def __init__(self, membership, non_membership, uncertainty=None): """ Initialize an Intuitionistic Fuzzy Set (IFS). Parameters: - membership (float): The degree to which an element belongs to the set. - non_membership (float): The degree to which an element does not belong to the set. - uncertainty (float, optional): The degree of uncertainty in the membership assignment. If not provided, it is calculated as 1 - membership - non_membership. """ self.membership = membership self.non_membership = non_membership if uncertainty is not None: self.uncertainty = uncertainty else: self.uncertainty = 1 - membership - non_membership
[docs] def __repr__(self): """ Return a string representation of the IFS. Returns: str: A string representation of the IFS. """ return f"IFS({self.membership}, {self.non_membership}, {self.uncertainty})"
[docs] def __str__(self): """ Return a human-readable string representation of the IFS. Returns: str: A string representation of the IFS. """ return f"Membership: {self.membership}, Non-membership: {self.non_membership}, Uncertainty: {self.uncertainty}"
[docs] def __eq__(self, other): """ Check if two IFS are equal. Parameters: - other (IFS): The IFS to compare with. Returns: bool: True if the IFS are equal, False otherwise. """ return ( self.membership == other.membership and self.non_membership == other.non_membership and self.uncertainty == other.uncertainty )
[docs] def __add__(self, other): """ Compute the addition of two IFS. Parameters: - other (IFS): The IFS to add. Returns: IFS: The resulting IFS after addition. """ membership = self.membership + other.membership - self.membership * other.membership non_membership = self.non_membership - other.non_membership uncertainty = np.max([1 - (membership + non_membership), 0]) return IFS(membership, non_membership, uncertainty)
[docs] def __sub__(self, other): """ Compute the subtraction of two IFS. Parameters: - other (IFS): The IFS to subtract. Returns: IFS: The resulting IFS after subtraction. """ if self.non_membership / other.non_membership <= ((1 - self.membership) / (1 - other.membership)): membership = (self.membership - other.membership) / (1 - other.membership) non_membership = self.non_membership / other.non_membership uncertainty = np.max([1 - (membership + non_membership), 0]) return IFS(membership, non_membership, uncertainty) else: return IFS(0, 1, 0)
[docs] def __mul__(self, other): """ Compute the multiplication of two IFS. Parameters: - other (IFS): The IFS to multiply. Returns: IFS: The resulting IFS after multiplication. """ membership = self.membership * other.membership non_membership = self.non_membership + other.non_membership - self.non_membership * other.non_membership uncertainty = np.max([1 - (membership + non_membership), 0]) return IFS(membership, non_membership, uncertainty)
[docs] def __truediv__(self, other): """ Compute the division of two IFS. Parameters: - other (IFS): The IFS to divide. Returns: IFS: The resulting IFS after division. """ if self.membership / other.membership <= ((1 - self.non_membership) / (1 - other.non_membership)): membership = self.membership / other.membership non_membership = (self.non_membership - other.non_membership) / (1 - other.non_membership) uncertainty = np.max([1 - (membership + non_membership), 0]) return IFS(membership, non_membership, uncertainty) else: return IFS(1, 0, 0)
[docs] def __pow__(self, y): """ Compute the division of two IFS. Parameters: - other (IFS): The IFS to divide. Returns: IFS: The resulting IFS after division. """ if y <= 0: raise ValueError('Power should be greater than 0') membership = self.membership ** y non_membership = 1 - (1 - self.non_membership) ** y uncertainty = np.max([1 - (membership + non_membership), 0]) return IFS(membership, non_membership, uncertainty)
[docs] def __and__(self, other): """ Compute the intersection of two IFS. Parameters: - other (IFS): The IFS to intersect with. Returns: IFS: The resulting IFS after intersection. """ membership = min(self.membership, other.membership) non_membership = max(self.non_membership, other.non_membership) uncertainty = np.max([1 - (membership + non_membership), 0]) return IFS(membership, non_membership, uncertainty)
[docs] def __or__(self, other): """ Compute the union of two IFS. Parameters: - other (IFS): The IFS to union with. Returns: IFS: The resulting IFS after union. """ membership = max(self.membership, other.membership) non_membership = min(self.non_membership, other.non_membership) uncertainty = np.max([1 - (membership + non_membership), 0]) return IFS(membership, non_membership, uncertainty)
[docs] def __invert__(self): """ Compute the complement of the IFS. Returns: IFS: The resulting complemented IFS. """ return IFS(self.non_membership, self.membership, self.uncertainty)
[docs] def dominance(self, other): """ Check if one IFS dominates another. Parameters: - other (IFS): The IFS to compare with. Returns: bool: True if the current IFS dominates the other, False otherwise. """ return ( self.membership >= other.membership and self.non_membership <= other.non_membership and self.uncertainty <= other.uncertainty )
[docs] def owa_aggregation(self, weights): """ Compute the Ordered Weighted Averaging (OWA) aggregation of the IFS. Parameters: - weights (list): A list of weights for each component (non-membership, uncertainty, membership). Returns: float: The result of the OWA aggregation. """ values = [self.non_membership, self.uncertainty, self.membership] return np.sum(np.multiply(weights, values))
[docs] def similarity_jaccard(self, other): """ Compute the Jaccard similarity coefficient between two IFS. Parameters: - other (IFS): The IFS to compare with. Returns: float: Jaccard similarity coefficient. """ intersection = min(self.membership, other.membership) + min(self.non_membership, other.non_membership) + min(self.uncertainty, other.uncertainty) union = max(self.membership, other.membership) + max(self.non_membership, other.non_membership) + max(self.uncertainty, other.uncertainty) similarity = intersection / union return similarity
[docs] def fuzzy_relation(self, other): """ Compute the fuzzy relation matrix between two IFS. Parameters: - other (IFS): The IFS to form a relation with. Returns: np.ndarray: Fuzzy relation matrix. """ relation_matrix = np.zeros((3, 3)) for i, component_i in enumerate([self.membership, self.non_membership, self.uncertainty]): for j, component_j in enumerate([other.membership, other.non_membership, other.uncertainty]): relation_matrix[i, j] = min(component_i, component_j) return relation_matrix