Source code for axisfuzzy.fuzzifier.fuzzifier

#  Copyright (c) yibocat 2025 All Rights Reserved
#  Python: 3.12.7
#  Date: 2025/8/19 12:17
#  Author: yibow
#  Email: yibocat@yeah.net
#  Software: AxisFuzzy

# fuzzifier.py
from typing import Union, Optional, Any, List, Dict, Type
import numpy as np
import inspect

from .registry import get_registry_fuzzify
from ..config import get_config
from ..membership import MembershipFunction, get_mf_class
from ..core import Fuzznum, Fuzzarray


[docs] class Fuzzifier: """ 模糊化引擎 - 强制参数格式: mf_params: List[Dict] - 分离策略参数与隶属函数参数 - 调用策略决策生成结果 """ def __init__(self, mf: Union[MembershipFunction, Type[MembershipFunction], str], mtype: Optional[str] = None, method: Optional[str] = None, **kwargs: Any): """ Parameters ---------- mf : 隶属函数类名或实例 mtype : 模糊数类型 (e.g. qrofn, qrohfn) method : 策略方法名 kwargs : 包含 'mf_params' 与策略参数 """ # --- 保存原始构造参数,这对于序列化至关重要 --- self._init_mf = mf self._init_mtype = mtype self._init_method = method self._init_kwargs = kwargs.copy() # 必须复制 # --- 序列化所需信息结束 --- # 1. 确定策略类 self.mtype = mtype or get_config().DEFAULT_MTYPE registry = get_registry_fuzzify() self.method = method or registry.get_default_method(self.mtype) if self.method is None: raise ValueError(f"No default method for mtype '{self.mtype}'") strategy_cls = registry.get_strategy(self.mtype, self.method) if strategy_cls is None: raise ValueError(f"No strategy found for mtype {self.mtype}, method {self.method}") # 2. 确定隶属函数类 if isinstance(mf, MembershipFunction): # 传入的是隶属函数实例 self.mf_cls = mf.__class__ self.provided_mf_instance = mf elif inspect.isclass(mf) and issubclass(mf, MembershipFunction): # 传入的是隶属函数类 self.mf_cls = mf self.provided_mf_instance = None else: # 传入的是字符串名称或别名 self.mf_cls = get_mf_class(mf) self.provided_mf_instance = None # 3. 提取并标准化 mf_params if "mf_params" not in kwargs: # 如果传入的是隶属函数实例且未提供 mf_params,则自动从实例中提取参数 if isinstance(mf, MembershipFunction): mf_params = mf.get_parameters() else: raise ValueError("Fuzzifier requires 'mf_params' argument (dict or list of dicts) when not using a MembershipFunction instance.") else: mf_params = kwargs.pop("mf_params") if isinstance(mf_params, dict): mf_params_list = [mf_params] elif isinstance(mf_params, list) and all(isinstance(d, dict) for d in mf_params): mf_params_list = mf_params else: raise TypeError("mf_params must be either a dict, or a list of dicts.") self.mf_params_list: List[Dict] = mf_params_list # 4. 实例化策略(其余 kwargs 转给策略) self.strategy = strategy_cls(**kwargs) def __call__(self, x: Union[float, int, list, np.ndarray]) -> Fuzznum | Fuzzarray: """调用策略进行模糊化""" return self.strategy.fuzzify(x, self.mf_cls, self.mf_params_list) def __repr__(self): return (f"Fuzzifier(method='{self.method}', " f"mtype='{self.mtype}', " f"mf='{self.mf_cls.__name__}', " f"params={self.mf_params_list})")
[docs] def get_config(self) -> Dict[str, Any]: """ 返回一个可序列化的配置字典,用于重建 Fuzzifier。 此方法返回重建实例所需的所有构造参数。 """ # 隶属函数总是以字符串形式保存,以确保可移植性 if isinstance(self._init_mf, str): mf_name = self._init_mf else: mf_name = self._init_mf.__class__.__name__ config = { 'mf': mf_name, 'mtype': self._init_mtype, 'method': self._init_method, } # 将 mf_params 和其他策略参数合并 config.update(self._init_kwargs) return config
[docs] @classmethod def from_config(cls, config: Dict[str, Any]) -> 'Fuzzifier': """ 从配置字典重建 Fuzzifier 实例。 Args: config (dict): 由 get_config 方法生成的配置字典。 Returns: Fuzzifier: 重建的 Fuzzifier 实例。 """ return cls(**config)
[docs] def plot(self, x_range: tuple = (0, 1), num_points: int = 100, show: bool = True): """ 绘制此 Fuzzifier 对应的隶属函数集合曲线. Args: x_range (tuple): 横坐标区间 (min, max) num_points (int): 采样点个数 show (bool): 是否立即显示图像 """ try: from matplotlib import pyplot as plt except ImportError: raise ImportError( "matplotlib is required for plotting. " "Install it with: pip install matplotlib or uv add --optional analysis matplotlib" ) x = np.linspace(x_range[0], x_range[1], num_points) plt.figure(figsize=(8, 5)) for idx, params in enumerate(self.mf_params_list): # 创建对应的隶属函数实例 mf = self.mf_cls(**params) y = mf.compute(x) label = f"{self.mf_cls.__name__} {params}" plt.plot(x, y, label=label) plt.xlabel("x") plt.ylabel("Membership Degree") plt.title(f"Fuzzifier: {self.mf_cls.__name__} [{self.mtype}:{self.method}]") plt.legend() plt.grid(True) if show: plt.show()