membership.function

Standard membership function implementations for AxisFuzzy.

This module provides a comprehensive collection of commonly used membership functions that form the building blocks of fuzzy sets and fuzzy logic systems. Each function implements the MembershipFunction interface and provides mathematically sound, numerically stable, and computationally efficient implementations.

The functions are designed to work seamlessly with the AxisFuzzy fuzzification system and support both scalar and vectorized array operations for high-performance batch processing.

Available Functions

This module implements the following standard membership functions:

Basic Shape Functions:
  • TriangularMF: Triangular-shaped membership function with three parameters (a, b, c)

  • TrapezoidalMF: Trapezoidal-shaped function with four parameters (a, b, c, d)

  • GaussianMF: Bell-shaped Gaussian function with center and spread parameters

S-Curve and Z-Curve Functions:
  • SigmoidMF: Sigmoid (S-shaped) function with slope and center parameters

  • SMF: S-shaped membership function with smooth transitions

  • ZMF: Z-shaped membership function (inverse of S-shaped)

  • PiMF: Pi-shaped function combining S and Z curves

Advanced Functions:

Design Principles

All membership functions in this module follow consistent design principles:

Mathematical Correctness:
  • All functions guarantee output values in the range [0, 1]

  • Smooth transitions and mathematical continuity where appropriate

  • Proper handling of boundary conditions and edge cases

Numerical Stability:
  • Robust handling of extreme values and potential division by zero

  • Use of NumPy’s error handling for floating-point operations

  • Clipping and sanitization of results to ensure valid outputs

Performance Optimization:
  • Vectorized operations using NumPy for efficient array processing

  • Minimal object creation and memory allocation

  • Optimized algorithms for common parameter configurations

User Experience:
  • Flexible parameter specification (positional or keyword arguments)

  • Comprehensive parameter validation with clear error messages

  • Consistent naming conventions following MATLAB Fuzzy Logic Toolbox

Parameter Conventions

Most functions support dual parameter specification modes:

  1. Positional Arguments: MembershipFunction(param1, param2, ...) - Traditional mathematical notation - Compact specification for known parameter orders

  2. Keyword Arguments: MembershipFunction(param1=value1, param2=value2) - Self-documenting parameter specification - Partial parameter specification with defaults - Better for programmatic generation

Parameter Validation: All functions validate their parameters during construction and when updated via set_parameters(). Common validation includes: - Range checks (e.g., positive values for standard deviations) - Ordering constraints (e.g., a ≤ b ≤ c for triangular functions) - Mathematical feasibility (e.g., non-zero denominators)

Vectorization Support

All functions are designed for efficient vectorized operation:

import numpy as np

# Single value computation
mf = TriangularMF(0, 0.5, 1)
single_result = mf.compute(0.3)  # Returns scalar

# Vectorized computation
x_array = np.linspace(0, 1, 1000)
array_result = mf.compute(x_array)  # Returns array of same shape

Performance Characteristics

The functions are optimized for different usage patterns:

  • TriangularMF, TrapezoidalMF: Extremely fast, piecewise linear computation

  • GaussianMF, DoubleGaussianMF: Moderate speed, smooth curves

  • SMF, ZMF, PiMF: Moderate speed, complex curve shapes

  • GeneralizedBellMF: Slower due to power operations, high flexibility

  • SigmoidMF: Fast, good for neural network-style applications

Integration with AxisFuzzy

These functions integrate seamlessly with the broader AxisFuzzy ecosystem:

  • Factory System: All functions are automatically discovered and available through axisfuzzy.membership.factory.create_mf()

  • Fuzzification: Used by axisfuzzy.fuzzify for crisp-to-fuzzy conversion

  • Visualization: Built-in plotting support for function analysis

  • Serialization: Parameter dictionaries support easy save/load operations

Notes

  • All functions are thread-safe for read operations after construction

  • Parameter updates via set_parameters() are not guaranteed to be thread-safe

  • Functions maintain internal parameter dictionaries for introspection

  • Plotting requires matplotlib and is optional for core functionality

See also

axisfuzzy.membership.base

Base class defining the membership function interface

axisfuzzy.membership.factory

Factory functions for creating instances

axisfuzzy.fuzzify

Fuzzification system using these functions

Examples

Basic usage of different membership functions:

import numpy as np
from axisfuzzy.membership.function import TriangularMF, GaussianMF, SigmoidMF

# Create different function types
tri = TriangularMF(a=0, b=0.5, c=1)
gauss = GaussianMF(sigma=0.2, c=0.5)
sigmoid = SigmoidMF(k=5, c=0.5)

# Evaluate at single points
x = 0.3
tri_val = tri.compute(x)     # ≈ 0.6
gauss_val = gauss.compute(x) # ≈ 0.135
sig_val = sigmoid.compute(x) # ≈ 0.119

# Vectorized evaluation
x_array = np.linspace(0, 1, 100)
tri_array = tri.compute(x_array)
gauss_array = gauss.compute(x_array)
sig_array = sigmoid.compute(x_array)

Parameter flexibility and validation:

# Multiple ways to create triangular function
tri1 = TriangularMF(0, 0.5, 1)              # Positional
tri2 = TriangularMF(a=0, b=0.5, c=1)        # Keyword
tri3 = TriangularMF(a=0, c=1, b=0.5)        # Mixed order

# Parameter validation
try:
    invalid = TriangularMF(1, 0.5, 0)  # Invalid order
except ValueError as e:
    print(f"Validation error: {e}")

# Dynamic parameter updates
tri = TriangularMF(0, 0.5, 1)
tri.set_parameters(b=0.7)  # Update peak position
print(tri.get_parameters()) # {'a': 0, 'b': 0.7, 'c': 1}

Advanced function combinations:

# Create complex membership functions
double_gauss = DoubleGaussianMF(sigma1=0.1, c1=0.3, sigma2=0.15, c2=0.7)
pi_function = PiMF(a=0.2, b=0.4, c=0.6, d=0.8)

# Evaluate and compare
x = np.linspace(0, 1, 200)
dg_values = double_gauss.compute(x)
pi_values = pi_function.compute(x)

# Plot for comparison
import matplotlib.pyplot as plt
plt.plot(x, dg_values, label='Double Gaussian')
plt.plot(x, pi_values, label='Pi Function')
plt.legend()
plt.show()

Integration with fuzzification:

from axisfuzzy.membership.factory import create_mf
from axisfuzzy.fuzzify import fuzzify

# Create membership function via factory
mf, _ = create_mf('trimf', a=0, b=0.5, c=1)

# Use in fuzzification
crisp_values = [0.2, 0.5, 0.8]
fuzzy_result = fuzzify(crisp_values, membership_function=mf, mtype='qrofn')

References

  • Zadeh, L.A. (1965). “Fuzzy sets”. Information and Control, 8(3), 338-353.

  • MATLAB Fuzzy Logic Toolbox documentation for function definitions

class axisfuzzy.membership.function.DoubleGaussianMF(*params, sigma1=None, c1=None, sigma2=None, c2=None)[source]

Bases: MembershipFunction

Double Gaussian membership function.

A combination of two Gaussian curves that takes the maximum value at each point. This creates a function with two peaks or a broader, flatter top than a single Gaussian. Useful for representing bimodal distributions or wide acceptance regions.

Parameters:
  • sigma1 (float) – Standard deviations of the two Gaussian curves. Must be positive.

  • sigma2 (float) – Standard deviations of the two Gaussian curves. Must be positive.

  • c1 (float) – Centers of the two Gaussian curves.

  • c2 (float) – Centers of the two Gaussian curves.

Examples

# Two separate peaks
mf = DoubleGaussianMF(sigma1=0.1, c1=0.3, sigma2=0.1, c2=0.7)

# Overlapping peaks (broader curve)
mf = DoubleGaussianMF(sigma1=0.2, c1=0.4, sigma2=0.2, c2=0.6)

# Asymmetric double curve
mf = DoubleGaussianMF(sigma1=0.1, c1=0.2, sigma2=0.3, c2=0.8)
compute(x)[source]

Compute membership degrees for input values.

This is the core method that all membership functions must implement. It transforms input values into membership degrees in the range [0, 1].

Parameters:

x (float or numpy.ndarray) – Input value(s) for which to compute membership degrees. Can be a scalar or array of any shape.

Returns:

Membership degree(s) corresponding to the input values. Output has the same shape as input and values are in [0, 1].

Return type:

float or numpy.ndarray

Notes

Implementations must ensure that: - All output values are in the range [0, 1] - The function handles both scalar and array inputs correctly - Numerical stability is maintained for edge cases - The function is vectorized for efficient array processing

Examples

Implementation example for a simple linear membership function:

def compute(self, x):
    x = np.asarray(x, dtype=float)
    result = (x - self.min_val) / (self.max_val - self.min_val)
    return np.clip(result, 0.0, 1.0)
get_parameters()

Retrieve the current parameters of the membership function.

Returns a dictionary containing all parameters that define the shape and behavior of the membership function. This is useful for introspection, serialization, and debugging.

Returns:

Dictionary mapping parameter names to their current values. The exact keys depend on the specific membership function type.

Return type:

dict

Examples

# For a triangular membership function
mf = TriangularMF(a=0, b=0.5, c=1)
params = mf.get_parameters()
print(params)  # {'a': 0, 'b': 0.5, 'c': 1}

# For a Gaussian membership function
mf = GaussianMF(sigma=1.0, c=0.0)
params = mf.get_parameters()
print(params)  # {'sigma': 1.0, 'c': 0.0}
plot(x_range=(0, 1), num_points=1000)

Generate a matplotlib plot of the membership function.

Creates a visual representation of the membership function over the specified input range. This is useful for function validation, parameter tuning, and educational purposes.

Parameters:
  • x_range (tuple of float, default (0, 1)) – The (min, max) range of input values to plot.

  • num_points (int, default 1000) – Number of points to use for plotting. Higher values create smoother curves but require more computation.

Notes

This method requires matplotlib to be installed. If matplotlib is not available, the method will raise an ImportError.

The plot shows: - X-axis: Input values over the specified range - Y-axis: Membership degrees from 0 to 1 - Title: Function name and type - Grid: Enabled for easier reading

Examples

# Plot with default settings
mf = TriangularMF(a=0, b=0.5, c=1)
mf.plot()

# Plot over custom range with high resolution
mf.plot(x_range=(-2, 3), num_points=2000)

# Plot multiple functions for comparison
mf1 = TriangularMF(a=0, b=0.3, c=0.6)
mf2 = TriangularMF(a=0.4, b=0.7, c=1.0)

import matplotlib.pyplot as plt
mf1.plot()
mf2.plot()
plt.legend(['Function 1', 'Function 2'])
# For users who want to display the plot immediately.

# plt.show() should be called outside the function # to allow for multiple plots to be drawn on the same figure. # plt.show()

Raises:
  • ImportError – If matplotlib is not installed.

  • ValueError – If x_range is invalid or num_points is not positive.

set_parameters(**kwargs)[source]

Update the parameters of the membership function.

This method allows dynamic modification of function parameters after instantiation. Implementations must validate parameters and update both the internal state and the parameters dictionary.

Parameters:

**kwargs – Parameter names and values to update. Only parameters recognized by the specific membership function are processed.

Raises:

ValueError – If invalid parameter values are provided or if parameter combinations violate mathematical constraints.

Notes

Implementations should: - Validate all parameter values before updating - Maintain mathematical constraints (e.g., ordering requirements) - Update both internal attributes and the parameters dict - Provide clear error messages for invalid parameters

Examples

# Update triangular function parameters
mf = TriangularMF(a=0, b=0.5, c=1)
mf.set_parameters(b=0.6, c=1.2)

# Update Gaussian function parameters
mf = GaussianMF(sigma=1.0, c=0.0)
mf.set_parameters(sigma=1.5)  # Only update sigma

# Invalid parameter raises ValueError
try:
    mf.set_parameters(sigma=-1.0)  # Negative sigma
except ValueError as e:
    print(f"Error: {e}")
class axisfuzzy.membership.function.GaussianMF(*params, sigma=None, c=None)[source]

Bases: MembershipFunction

Gaussian membership function.

A bell-shaped curve based on the normal distribution. It provides smooth transitions and is commonly used when gradual membership changes are desired. The function is symmetric around its center point.

Parameters:
  • sigma (float) – Standard deviation controlling the width of the bell curve. Must be positive. Smaller values create narrower curves.

  • c (float) – Center of the bell curve (mean of the distribution).

Examples

# Standard Gaussian
mf = GaussianMF(sigma=0.2, c=0.5)
result = mf.compute([0.3, 0.5, 0.7])  # Peak at c=0.5

# Wide Gaussian
mf = GaussianMF(sigma=0.5, c=0.5)  # Broader curve

# Narrow Gaussian
mf = GaussianMF(sigma=0.1, c=0.5)  # Sharper peak
compute(x)[source]

Compute membership degrees for input values.

This is the core method that all membership functions must implement. It transforms input values into membership degrees in the range [0, 1].

Parameters:

x (float or numpy.ndarray) – Input value(s) for which to compute membership degrees. Can be a scalar or array of any shape.

Returns:

Membership degree(s) corresponding to the input values. Output has the same shape as input and values are in [0, 1].

Return type:

float or numpy.ndarray

Notes

Implementations must ensure that: - All output values are in the range [0, 1] - The function handles both scalar and array inputs correctly - Numerical stability is maintained for edge cases - The function is vectorized for efficient array processing

Examples

Implementation example for a simple linear membership function:

def compute(self, x):
    x = np.asarray(x, dtype=float)
    result = (x - self.min_val) / (self.max_val - self.min_val)
    return np.clip(result, 0.0, 1.0)
get_parameters()

Retrieve the current parameters of the membership function.

Returns a dictionary containing all parameters that define the shape and behavior of the membership function. This is useful for introspection, serialization, and debugging.

Returns:

Dictionary mapping parameter names to their current values. The exact keys depend on the specific membership function type.

Return type:

dict

Examples

# For a triangular membership function
mf = TriangularMF(a=0, b=0.5, c=1)
params = mf.get_parameters()
print(params)  # {'a': 0, 'b': 0.5, 'c': 1}

# For a Gaussian membership function
mf = GaussianMF(sigma=1.0, c=0.0)
params = mf.get_parameters()
print(params)  # {'sigma': 1.0, 'c': 0.0}
plot(x_range=(0, 1), num_points=1000)

Generate a matplotlib plot of the membership function.

Creates a visual representation of the membership function over the specified input range. This is useful for function validation, parameter tuning, and educational purposes.

Parameters:
  • x_range (tuple of float, default (0, 1)) – The (min, max) range of input values to plot.

  • num_points (int, default 1000) – Number of points to use for plotting. Higher values create smoother curves but require more computation.

Notes

This method requires matplotlib to be installed. If matplotlib is not available, the method will raise an ImportError.

The plot shows: - X-axis: Input values over the specified range - Y-axis: Membership degrees from 0 to 1 - Title: Function name and type - Grid: Enabled for easier reading

Examples

# Plot with default settings
mf = TriangularMF(a=0, b=0.5, c=1)
mf.plot()

# Plot over custom range with high resolution
mf.plot(x_range=(-2, 3), num_points=2000)

# Plot multiple functions for comparison
mf1 = TriangularMF(a=0, b=0.3, c=0.6)
mf2 = TriangularMF(a=0.4, b=0.7, c=1.0)

import matplotlib.pyplot as plt
mf1.plot()
mf2.plot()
plt.legend(['Function 1', 'Function 2'])
# For users who want to display the plot immediately.

# plt.show() should be called outside the function # to allow for multiple plots to be drawn on the same figure. # plt.show()

Raises:
  • ImportError – If matplotlib is not installed.

  • ValueError – If x_range is invalid or num_points is not positive.

set_parameters(**kwargs)[source]

Update the parameters of the membership function.

This method allows dynamic modification of function parameters after instantiation. Implementations must validate parameters and update both the internal state and the parameters dictionary.

Parameters:

**kwargs – Parameter names and values to update. Only parameters recognized by the specific membership function are processed.

Raises:

ValueError – If invalid parameter values are provided or if parameter combinations violate mathematical constraints.

Notes

Implementations should: - Validate all parameter values before updating - Maintain mathematical constraints (e.g., ordering requirements) - Update both internal attributes and the parameters dict - Provide clear error messages for invalid parameters

Examples

# Update triangular function parameters
mf = TriangularMF(a=0, b=0.5, c=1)
mf.set_parameters(b=0.6, c=1.2)

# Update Gaussian function parameters
mf = GaussianMF(sigma=1.0, c=0.0)
mf.set_parameters(sigma=1.5)  # Only update sigma

# Invalid parameter raises ValueError
try:
    mf.set_parameters(sigma=-1.0)  # Negative sigma
except ValueError as e:
    print(f"Error: {e}")
class axisfuzzy.membership.function.GeneralizedBellMF(*params, a=None, b=None, c=None)[source]

Bases: MembershipFunction

Generalized Bell membership function.

A bell-shaped curve with adjustable steepness and width. It provides more flexibility than the Gaussian function by allowing independent control of the curve’s width and steepness around the center point.

Parameters:
  • a (float) – Width parameter controlling the curve width. Must be positive. Larger values create wider curves.

  • b (float) – Slope parameter controlling steepness at the crossover points. Must be positive. Larger values create steeper transitions.

  • c (float) – Center of the bell curve.

Examples

# Standard generalized bell
mf = GeneralizedBellMF(a=0.2, b=2, c=0.5)

# Wide, gentle curve
mf = GeneralizedBellMF(a=0.5, b=1, c=0.5)

# Narrow, steep curve
mf = GeneralizedBellMF(a=0.1, b=5, c=0.5)
compute(x)[source]

Compute membership degrees for input values.

This is the core method that all membership functions must implement. It transforms input values into membership degrees in the range [0, 1].

Parameters:

x (float or numpy.ndarray) – Input value(s) for which to compute membership degrees. Can be a scalar or array of any shape.

Returns:

Membership degree(s) corresponding to the input values. Output has the same shape as input and values are in [0, 1].

Return type:

float or numpy.ndarray

Notes

Implementations must ensure that: - All output values are in the range [0, 1] - The function handles both scalar and array inputs correctly - Numerical stability is maintained for edge cases - The function is vectorized for efficient array processing

Examples

Implementation example for a simple linear membership function:

def compute(self, x):
    x = np.asarray(x, dtype=float)
    result = (x - self.min_val) / (self.max_val - self.min_val)
    return np.clip(result, 0.0, 1.0)
get_parameters()

Retrieve the current parameters of the membership function.

Returns a dictionary containing all parameters that define the shape and behavior of the membership function. This is useful for introspection, serialization, and debugging.

Returns:

Dictionary mapping parameter names to their current values. The exact keys depend on the specific membership function type.

Return type:

dict

Examples

# For a triangular membership function
mf = TriangularMF(a=0, b=0.5, c=1)
params = mf.get_parameters()
print(params)  # {'a': 0, 'b': 0.5, 'c': 1}

# For a Gaussian membership function
mf = GaussianMF(sigma=1.0, c=0.0)
params = mf.get_parameters()
print(params)  # {'sigma': 1.0, 'c': 0.0}
plot(x_range=(0, 1), num_points=1000)

Generate a matplotlib plot of the membership function.

Creates a visual representation of the membership function over the specified input range. This is useful for function validation, parameter tuning, and educational purposes.

Parameters:
  • x_range (tuple of float, default (0, 1)) – The (min, max) range of input values to plot.

  • num_points (int, default 1000) – Number of points to use for plotting. Higher values create smoother curves but require more computation.

Notes

This method requires matplotlib to be installed. If matplotlib is not available, the method will raise an ImportError.

The plot shows: - X-axis: Input values over the specified range - Y-axis: Membership degrees from 0 to 1 - Title: Function name and type - Grid: Enabled for easier reading

Examples

# Plot with default settings
mf = TriangularMF(a=0, b=0.5, c=1)
mf.plot()

# Plot over custom range with high resolution
mf.plot(x_range=(-2, 3), num_points=2000)

# Plot multiple functions for comparison
mf1 = TriangularMF(a=0, b=0.3, c=0.6)
mf2 = TriangularMF(a=0.4, b=0.7, c=1.0)

import matplotlib.pyplot as plt
mf1.plot()
mf2.plot()
plt.legend(['Function 1', 'Function 2'])
# For users who want to display the plot immediately.

# plt.show() should be called outside the function # to allow for multiple plots to be drawn on the same figure. # plt.show()

Raises:
  • ImportError – If matplotlib is not installed.

  • ValueError – If x_range is invalid or num_points is not positive.

set_parameters(**kwargs)[source]

Update the parameters of the membership function.

This method allows dynamic modification of function parameters after instantiation. Implementations must validate parameters and update both the internal state and the parameters dictionary.

Parameters:

**kwargs – Parameter names and values to update. Only parameters recognized by the specific membership function are processed.

Raises:

ValueError – If invalid parameter values are provided or if parameter combinations violate mathematical constraints.

Notes

Implementations should: - Validate all parameter values before updating - Maintain mathematical constraints (e.g., ordering requirements) - Update both internal attributes and the parameters dict - Provide clear error messages for invalid parameters

Examples

# Update triangular function parameters
mf = TriangularMF(a=0, b=0.5, c=1)
mf.set_parameters(b=0.6, c=1.2)

# Update Gaussian function parameters
mf = GaussianMF(sigma=1.0, c=0.0)
mf.set_parameters(sigma=1.5)  # Only update sigma

# Invalid parameter raises ValueError
try:
    mf.set_parameters(sigma=-1.0)  # Negative sigma
except ValueError as e:
    print(f"Error: {e}")
class axisfuzzy.membership.function.PiMF(*params, a=None, b=None, c=None, d=None)[source]

Bases: MembershipFunction

Pi-shaped membership function.

A combination of S-shaped and Z-shaped curves creating a bell-like function with smooth transitions. It rises smoothly, maintains a flat top, then falls smoothly. This function is useful when you need smooth transitions with a plateau region of maximum membership.

Parameters:
  • a (float) – Left foot where function starts rising.

  • b (float) – Left shoulder where function reaches maximum.

  • c (float) – Right shoulder where function starts falling.

  • d (float) – Right foot where function reaches zero.

  • Constraints (a ≤ b ≤ c ≤ d)

Examples

# Standard Pi function
mf = PiMF(a=0, b=0.2, c=0.8, d=1)

# Narrow plateau
mf = PiMF(a=0, b=0.4, c=0.6, d=1)

# Wide plateau
mf = PiMF(a=0, b=0.1, c=0.9, d=1)
compute(x)[source]

Compute membership degrees for input values.

This is the core method that all membership functions must implement. It transforms input values into membership degrees in the range [0, 1].

Parameters:

x (float or numpy.ndarray) – Input value(s) for which to compute membership degrees. Can be a scalar or array of any shape.

Returns:

Membership degree(s) corresponding to the input values. Output has the same shape as input and values are in [0, 1].

Return type:

float or numpy.ndarray

Notes

Implementations must ensure that: - All output values are in the range [0, 1] - The function handles both scalar and array inputs correctly - Numerical stability is maintained for edge cases - The function is vectorized for efficient array processing

Examples

Implementation example for a simple linear membership function:

def compute(self, x):
    x = np.asarray(x, dtype=float)
    result = (x - self.min_val) / (self.max_val - self.min_val)
    return np.clip(result, 0.0, 1.0)
get_parameters()

Retrieve the current parameters of the membership function.

Returns a dictionary containing all parameters that define the shape and behavior of the membership function. This is useful for introspection, serialization, and debugging.

Returns:

Dictionary mapping parameter names to their current values. The exact keys depend on the specific membership function type.

Return type:

dict

Examples

# For a triangular membership function
mf = TriangularMF(a=0, b=0.5, c=1)
params = mf.get_parameters()
print(params)  # {'a': 0, 'b': 0.5, 'c': 1}

# For a Gaussian membership function
mf = GaussianMF(sigma=1.0, c=0.0)
params = mf.get_parameters()
print(params)  # {'sigma': 1.0, 'c': 0.0}
plot(x_range=(0, 1), num_points=1000)

Generate a matplotlib plot of the membership function.

Creates a visual representation of the membership function over the specified input range. This is useful for function validation, parameter tuning, and educational purposes.

Parameters:
  • x_range (tuple of float, default (0, 1)) – The (min, max) range of input values to plot.

  • num_points (int, default 1000) – Number of points to use for plotting. Higher values create smoother curves but require more computation.

Notes

This method requires matplotlib to be installed. If matplotlib is not available, the method will raise an ImportError.

The plot shows: - X-axis: Input values over the specified range - Y-axis: Membership degrees from 0 to 1 - Title: Function name and type - Grid: Enabled for easier reading

Examples

# Plot with default settings
mf = TriangularMF(a=0, b=0.5, c=1)
mf.plot()

# Plot over custom range with high resolution
mf.plot(x_range=(-2, 3), num_points=2000)

# Plot multiple functions for comparison
mf1 = TriangularMF(a=0, b=0.3, c=0.6)
mf2 = TriangularMF(a=0.4, b=0.7, c=1.0)

import matplotlib.pyplot as plt
mf1.plot()
mf2.plot()
plt.legend(['Function 1', 'Function 2'])
# For users who want to display the plot immediately.

# plt.show() should be called outside the function # to allow for multiple plots to be drawn on the same figure. # plt.show()

Raises:
  • ImportError – If matplotlib is not installed.

  • ValueError – If x_range is invalid or num_points is not positive.

set_parameters(**kwargs)[source]

Update the parameters of the membership function.

This method allows dynamic modification of function parameters after instantiation. Implementations must validate parameters and update both the internal state and the parameters dictionary.

Parameters:

**kwargs – Parameter names and values to update. Only parameters recognized by the specific membership function are processed.

Raises:

ValueError – If invalid parameter values are provided or if parameter combinations violate mathematical constraints.

Notes

Implementations should: - Validate all parameter values before updating - Maintain mathematical constraints (e.g., ordering requirements) - Update both internal attributes and the parameters dict - Provide clear error messages for invalid parameters

Examples

# Update triangular function parameters
mf = TriangularMF(a=0, b=0.5, c=1)
mf.set_parameters(b=0.6, c=1.2)

# Update Gaussian function parameters
mf = GaussianMF(sigma=1.0, c=0.0)
mf.set_parameters(sigma=1.5)  # Only update sigma

# Invalid parameter raises ValueError
try:
    mf.set_parameters(sigma=-1.0)  # Negative sigma
except ValueError as e:
    print(f"Error: {e}")
class axisfuzzy.membership.function.SMF(*params, a=None, b=None)[source]

Bases: MembershipFunction

S-shaped membership function.

A smooth S-curve that transitions from 0 to 1. The function has an inflection point at the midpoint between parameters a and b. It’s useful for representing gradual increase in membership with smooth acceleration and deceleration.

Parameters:
  • a (float) – Lower bound where function starts transitioning from 0.

  • b (float) – Upper bound where function reaches 1.

  • Constraints (a < b)

Examples

# Standard S-curve
mf = SMF(a=0, b=1)
result = mf.compute([0, 0.25, 0.5, 0.75, 1])  # [0, 0.125, 0.5, 0.875, 1]

# Shifted S-curve
mf = SMF(a=0.2, b=0.8)  # Transition between 0.2 and 0.8
compute(x)[source]

Compute membership degrees for input values.

This is the core method that all membership functions must implement. It transforms input values into membership degrees in the range [0, 1].

Parameters:

x (float or numpy.ndarray) – Input value(s) for which to compute membership degrees. Can be a scalar or array of any shape.

Returns:

Membership degree(s) corresponding to the input values. Output has the same shape as input and values are in [0, 1].

Return type:

float or numpy.ndarray

Notes

Implementations must ensure that: - All output values are in the range [0, 1] - The function handles both scalar and array inputs correctly - Numerical stability is maintained for edge cases - The function is vectorized for efficient array processing

Examples

Implementation example for a simple linear membership function:

def compute(self, x):
    x = np.asarray(x, dtype=float)
    result = (x - self.min_val) / (self.max_val - self.min_val)
    return np.clip(result, 0.0, 1.0)
get_parameters()

Retrieve the current parameters of the membership function.

Returns a dictionary containing all parameters that define the shape and behavior of the membership function. This is useful for introspection, serialization, and debugging.

Returns:

Dictionary mapping parameter names to their current values. The exact keys depend on the specific membership function type.

Return type:

dict

Examples

# For a triangular membership function
mf = TriangularMF(a=0, b=0.5, c=1)
params = mf.get_parameters()
print(params)  # {'a': 0, 'b': 0.5, 'c': 1}

# For a Gaussian membership function
mf = GaussianMF(sigma=1.0, c=0.0)
params = mf.get_parameters()
print(params)  # {'sigma': 1.0, 'c': 0.0}
plot(x_range=(0, 1), num_points=1000)

Generate a matplotlib plot of the membership function.

Creates a visual representation of the membership function over the specified input range. This is useful for function validation, parameter tuning, and educational purposes.

Parameters:
  • x_range (tuple of float, default (0, 1)) – The (min, max) range of input values to plot.

  • num_points (int, default 1000) – Number of points to use for plotting. Higher values create smoother curves but require more computation.

Notes

This method requires matplotlib to be installed. If matplotlib is not available, the method will raise an ImportError.

The plot shows: - X-axis: Input values over the specified range - Y-axis: Membership degrees from 0 to 1 - Title: Function name and type - Grid: Enabled for easier reading

Examples

# Plot with default settings
mf = TriangularMF(a=0, b=0.5, c=1)
mf.plot()

# Plot over custom range with high resolution
mf.plot(x_range=(-2, 3), num_points=2000)

# Plot multiple functions for comparison
mf1 = TriangularMF(a=0, b=0.3, c=0.6)
mf2 = TriangularMF(a=0.4, b=0.7, c=1.0)

import matplotlib.pyplot as plt
mf1.plot()
mf2.plot()
plt.legend(['Function 1', 'Function 2'])
# For users who want to display the plot immediately.

# plt.show() should be called outside the function # to allow for multiple plots to be drawn on the same figure. # plt.show()

Raises:
  • ImportError – If matplotlib is not installed.

  • ValueError – If x_range is invalid or num_points is not positive.

set_parameters(**kwargs)[source]

Update the parameters of the membership function.

This method allows dynamic modification of function parameters after instantiation. Implementations must validate parameters and update both the internal state and the parameters dictionary.

Parameters:

**kwargs – Parameter names and values to update. Only parameters recognized by the specific membership function are processed.

Raises:

ValueError – If invalid parameter values are provided or if parameter combinations violate mathematical constraints.

Notes

Implementations should: - Validate all parameter values before updating - Maintain mathematical constraints (e.g., ordering requirements) - Update both internal attributes and the parameters dict - Provide clear error messages for invalid parameters

Examples

# Update triangular function parameters
mf = TriangularMF(a=0, b=0.5, c=1)
mf.set_parameters(b=0.6, c=1.2)

# Update Gaussian function parameters
mf = GaussianMF(sigma=1.0, c=0.0)
mf.set_parameters(sigma=1.5)  # Only update sigma

# Invalid parameter raises ValueError
try:
    mf.set_parameters(sigma=-1.0)  # Negative sigma
except ValueError as e:
    print(f"Error: {e}")
class axisfuzzy.membership.function.SigmoidMF(*params, k=None, c=None)[source]

Bases: MembershipFunction

Sigmoid membership function.

A smooth S-shaped function commonly used in neural networks and fuzzy logic. The function transitions from 0 to 1 with adjustable steepness and center point.

Parameters:
  • k (float) – Slope (steepness) of the sigmoid function. Positive values create ascending curves, negative values create descending curves.

  • c (float) – Center (midpoint) of the sigmoid function where output equals 0.5.

Examples

# Create ascending sigmoid
mf = SigmoidMF(k=2.0, c=0.5)
result = mf.compute([0, 0.5, 1])  # [0.12, 0.5, 0.88]

# Create descending sigmoid
mf = SigmoidMF(k=-2.0, c=0.5)
result = mf.compute([0, 0.5, 1])  # [0.88, 0.5, 0.12]
compute(x)[source]

Compute sigmoid membership values.

Return type:

ndarray

get_parameters()

Retrieve the current parameters of the membership function.

Returns a dictionary containing all parameters that define the shape and behavior of the membership function. This is useful for introspection, serialization, and debugging.

Returns:

Dictionary mapping parameter names to their current values. The exact keys depend on the specific membership function type.

Return type:

dict

Examples

# For a triangular membership function
mf = TriangularMF(a=0, b=0.5, c=1)
params = mf.get_parameters()
print(params)  # {'a': 0, 'b': 0.5, 'c': 1}

# For a Gaussian membership function
mf = GaussianMF(sigma=1.0, c=0.0)
params = mf.get_parameters()
print(params)  # {'sigma': 1.0, 'c': 0.0}
plot(x_range=(0, 1), num_points=1000)

Generate a matplotlib plot of the membership function.

Creates a visual representation of the membership function over the specified input range. This is useful for function validation, parameter tuning, and educational purposes.

Parameters:
  • x_range (tuple of float, default (0, 1)) – The (min, max) range of input values to plot.

  • num_points (int, default 1000) – Number of points to use for plotting. Higher values create smoother curves but require more computation.

Notes

This method requires matplotlib to be installed. If matplotlib is not available, the method will raise an ImportError.

The plot shows: - X-axis: Input values over the specified range - Y-axis: Membership degrees from 0 to 1 - Title: Function name and type - Grid: Enabled for easier reading

Examples

# Plot with default settings
mf = TriangularMF(a=0, b=0.5, c=1)
mf.plot()

# Plot over custom range with high resolution
mf.plot(x_range=(-2, 3), num_points=2000)

# Plot multiple functions for comparison
mf1 = TriangularMF(a=0, b=0.3, c=0.6)
mf2 = TriangularMF(a=0.4, b=0.7, c=1.0)

import matplotlib.pyplot as plt
mf1.plot()
mf2.plot()
plt.legend(['Function 1', 'Function 2'])
# For users who want to display the plot immediately.

# plt.show() should be called outside the function # to allow for multiple plots to be drawn on the same figure. # plt.show()

Raises:
  • ImportError – If matplotlib is not installed.

  • ValueError – If x_range is invalid or num_points is not positive.

set_parameters(**kwargs)[source]

Update the parameters of the membership function.

This method allows dynamic modification of function parameters after instantiation. Implementations must validate parameters and update both the internal state and the parameters dictionary.

Parameters:

**kwargs – Parameter names and values to update. Only parameters recognized by the specific membership function are processed.

Raises:

ValueError – If invalid parameter values are provided or if parameter combinations violate mathematical constraints.

Notes

Implementations should: - Validate all parameter values before updating - Maintain mathematical constraints (e.g., ordering requirements) - Update both internal attributes and the parameters dict - Provide clear error messages for invalid parameters

Examples

# Update triangular function parameters
mf = TriangularMF(a=0, b=0.5, c=1)
mf.set_parameters(b=0.6, c=1.2)

# Update Gaussian function parameters
mf = GaussianMF(sigma=1.0, c=0.0)
mf.set_parameters(sigma=1.5)  # Only update sigma

# Invalid parameter raises ValueError
try:
    mf.set_parameters(sigma=-1.0)  # Negative sigma
except ValueError as e:
    print(f"Error: {e}")
class axisfuzzy.membership.function.TrapezoidalMF(*params, a=None, b=None, c=None, d=None)[source]

Bases: MembershipFunction

Trapezoidal membership function.

A piecewise linear function forming a trapezoid shape. It has a flat top region between two linear transition regions. This function is useful when there’s a range of values that should have maximum membership.

Parameters:
  • a (float) – Left foot (start of ascending region).

  • b (float) – Left shoulder (start of flat top).

  • c (float) – Right shoulder (end of flat top).

  • d (float) – Right foot (end of descending region).

  • Constraints (a ≤ b ≤ c ≤ d)

Examples

# Standard trapezoidal function
mf = TrapezoidalMF(a=0, b=0.2, c=0.8, d=1)
result = mf.compute([0, 0.1, 0.5, 0.9, 1])  # [0, 0.5, 1, 0.5, 0]

# Degenerate to triangle when b=c
mf = TrapezoidalMF(a=0, b=0.5, c=0.5, d=1)  # Acts like triangle
compute(x)[source]

Compute membership degrees for input values.

This is the core method that all membership functions must implement. It transforms input values into membership degrees in the range [0, 1].

Parameters:

x (float or numpy.ndarray) – Input value(s) for which to compute membership degrees. Can be a scalar or array of any shape.

Returns:

Membership degree(s) corresponding to the input values. Output has the same shape as input and values are in [0, 1].

Return type:

float or numpy.ndarray

Notes

Implementations must ensure that: - All output values are in the range [0, 1] - The function handles both scalar and array inputs correctly - Numerical stability is maintained for edge cases - The function is vectorized for efficient array processing

Examples

Implementation example for a simple linear membership function:

def compute(self, x):
    x = np.asarray(x, dtype=float)
    result = (x - self.min_val) / (self.max_val - self.min_val)
    return np.clip(result, 0.0, 1.0)
get_parameters()

Retrieve the current parameters of the membership function.

Returns a dictionary containing all parameters that define the shape and behavior of the membership function. This is useful for introspection, serialization, and debugging.

Returns:

Dictionary mapping parameter names to their current values. The exact keys depend on the specific membership function type.

Return type:

dict

Examples

# For a triangular membership function
mf = TriangularMF(a=0, b=0.5, c=1)
params = mf.get_parameters()
print(params)  # {'a': 0, 'b': 0.5, 'c': 1}

# For a Gaussian membership function
mf = GaussianMF(sigma=1.0, c=0.0)
params = mf.get_parameters()
print(params)  # {'sigma': 1.0, 'c': 0.0}
plot(x_range=(0, 1), num_points=1000)

Generate a matplotlib plot of the membership function.

Creates a visual representation of the membership function over the specified input range. This is useful for function validation, parameter tuning, and educational purposes.

Parameters:
  • x_range (tuple of float, default (0, 1)) – The (min, max) range of input values to plot.

  • num_points (int, default 1000) – Number of points to use for plotting. Higher values create smoother curves but require more computation.

Notes

This method requires matplotlib to be installed. If matplotlib is not available, the method will raise an ImportError.

The plot shows: - X-axis: Input values over the specified range - Y-axis: Membership degrees from 0 to 1 - Title: Function name and type - Grid: Enabled for easier reading

Examples

# Plot with default settings
mf = TriangularMF(a=0, b=0.5, c=1)
mf.plot()

# Plot over custom range with high resolution
mf.plot(x_range=(-2, 3), num_points=2000)

# Plot multiple functions for comparison
mf1 = TriangularMF(a=0, b=0.3, c=0.6)
mf2 = TriangularMF(a=0.4, b=0.7, c=1.0)

import matplotlib.pyplot as plt
mf1.plot()
mf2.plot()
plt.legend(['Function 1', 'Function 2'])
# For users who want to display the plot immediately.

# plt.show() should be called outside the function # to allow for multiple plots to be drawn on the same figure. # plt.show()

Raises:
  • ImportError – If matplotlib is not installed.

  • ValueError – If x_range is invalid or num_points is not positive.

set_parameters(**kwargs)[source]

Update the parameters of the membership function.

This method allows dynamic modification of function parameters after instantiation. Implementations must validate parameters and update both the internal state and the parameters dictionary.

Parameters:

**kwargs – Parameter names and values to update. Only parameters recognized by the specific membership function are processed.

Raises:

ValueError – If invalid parameter values are provided or if parameter combinations violate mathematical constraints.

Notes

Implementations should: - Validate all parameter values before updating - Maintain mathematical constraints (e.g., ordering requirements) - Update both internal attributes and the parameters dict - Provide clear error messages for invalid parameters

Examples

# Update triangular function parameters
mf = TriangularMF(a=0, b=0.5, c=1)
mf.set_parameters(b=0.6, c=1.2)

# Update Gaussian function parameters
mf = GaussianMF(sigma=1.0, c=0.0)
mf.set_parameters(sigma=1.5)  # Only update sigma

# Invalid parameter raises ValueError
try:
    mf.set_parameters(sigma=-1.0)  # Negative sigma
except ValueError as e:
    print(f"Error: {e}")
class axisfuzzy.membership.function.TriangularMF(*params, a=None, b=None, c=None)[source]

Bases: MembershipFunction

Triangular membership function.

A piecewise linear function forming a triangle shape. It rises linearly from 0 to 1 and then falls linearly back to 0. This is one of the most commonly used membership functions due to its simplicity and computational efficiency.

Parameters:
  • a (float) – Left foot of the triangle (where function starts rising from 0).

  • b (float) – Peak of the triangle (where function equals 1).

  • c (float) – Right foot of the triangle (where function falls back to 0).

  • Constraints (a ≤ b ≤ c)

Examples

# Standard triangular function
mf = TriangularMF(a=0, b=0.5, c=1)
result = mf.compute([0, 0.25, 0.5, 0.75, 1])  # [0, 0.5, 1, 0.5, 0]

# Asymmetric triangle
mf = TriangularMF(a=0, b=0.2, c=1)  # Peak closer to left
compute(x)[source]

Compute membership degrees for input values.

This is the core method that all membership functions must implement. It transforms input values into membership degrees in the range [0, 1].

Parameters:

x (float or numpy.ndarray) – Input value(s) for which to compute membership degrees. Can be a scalar or array of any shape.

Returns:

Membership degree(s) corresponding to the input values. Output has the same shape as input and values are in [0, 1].

Return type:

float or numpy.ndarray

Notes

Implementations must ensure that: - All output values are in the range [0, 1] - The function handles both scalar and array inputs correctly - Numerical stability is maintained for edge cases - The function is vectorized for efficient array processing

Examples

Implementation example for a simple linear membership function:

def compute(self, x):
    x = np.asarray(x, dtype=float)
    result = (x - self.min_val) / (self.max_val - self.min_val)
    return np.clip(result, 0.0, 1.0)
get_parameters()

Retrieve the current parameters of the membership function.

Returns a dictionary containing all parameters that define the shape and behavior of the membership function. This is useful for introspection, serialization, and debugging.

Returns:

Dictionary mapping parameter names to their current values. The exact keys depend on the specific membership function type.

Return type:

dict

Examples

# For a triangular membership function
mf = TriangularMF(a=0, b=0.5, c=1)
params = mf.get_parameters()
print(params)  # {'a': 0, 'b': 0.5, 'c': 1}

# For a Gaussian membership function
mf = GaussianMF(sigma=1.0, c=0.0)
params = mf.get_parameters()
print(params)  # {'sigma': 1.0, 'c': 0.0}
plot(x_range=(0, 1), num_points=1000)

Generate a matplotlib plot of the membership function.

Creates a visual representation of the membership function over the specified input range. This is useful for function validation, parameter tuning, and educational purposes.

Parameters:
  • x_range (tuple of float, default (0, 1)) – The (min, max) range of input values to plot.

  • num_points (int, default 1000) – Number of points to use for plotting. Higher values create smoother curves but require more computation.

Notes

This method requires matplotlib to be installed. If matplotlib is not available, the method will raise an ImportError.

The plot shows: - X-axis: Input values over the specified range - Y-axis: Membership degrees from 0 to 1 - Title: Function name and type - Grid: Enabled for easier reading

Examples

# Plot with default settings
mf = TriangularMF(a=0, b=0.5, c=1)
mf.plot()

# Plot over custom range with high resolution
mf.plot(x_range=(-2, 3), num_points=2000)

# Plot multiple functions for comparison
mf1 = TriangularMF(a=0, b=0.3, c=0.6)
mf2 = TriangularMF(a=0.4, b=0.7, c=1.0)

import matplotlib.pyplot as plt
mf1.plot()
mf2.plot()
plt.legend(['Function 1', 'Function 2'])
# For users who want to display the plot immediately.

# plt.show() should be called outside the function # to allow for multiple plots to be drawn on the same figure. # plt.show()

Raises:
  • ImportError – If matplotlib is not installed.

  • ValueError – If x_range is invalid or num_points is not positive.

set_parameters(**kwargs)[source]

Update the parameters of the membership function.

This method allows dynamic modification of function parameters after instantiation. Implementations must validate parameters and update both the internal state and the parameters dictionary.

Parameters:

**kwargs – Parameter names and values to update. Only parameters recognized by the specific membership function are processed.

Raises:

ValueError – If invalid parameter values are provided or if parameter combinations violate mathematical constraints.

Notes

Implementations should: - Validate all parameter values before updating - Maintain mathematical constraints (e.g., ordering requirements) - Update both internal attributes and the parameters dict - Provide clear error messages for invalid parameters

Examples

# Update triangular function parameters
mf = TriangularMF(a=0, b=0.5, c=1)
mf.set_parameters(b=0.6, c=1.2)

# Update Gaussian function parameters
mf = GaussianMF(sigma=1.0, c=0.0)
mf.set_parameters(sigma=1.5)  # Only update sigma

# Invalid parameter raises ValueError
try:
    mf.set_parameters(sigma=-1.0)  # Negative sigma
except ValueError as e:
    print(f"Error: {e}")
class axisfuzzy.membership.function.ZMF(*params, a=None, b=None)[source]

Bases: MembershipFunction

Z-shaped membership function.

A smooth Z-curve that transitions from 1 to 0. It’s the inverse of the S-curve and is useful for representing gradual decrease in membership. The function has an inflection point at the midpoint between parameters a and b.

Parameters:
  • a (float) – Lower bound where function starts transitioning from 1.

  • b (float) – Upper bound where function reaches 0.

  • Constraints (a < b)

Examples

# Standard Z-curve
mf = ZMF(a=0, b=1)
result = mf.compute([0, 0.25, 0.5, 0.75, 1])  # [1, 0.875, 0.5, 0.125, 0]

# Shifted Z-curve
mf = ZMF(a=0.3, b=0.7)  # Transition between 0.3 and 0.7
compute(x)[source]

Compute membership degrees for input values.

This is the core method that all membership functions must implement. It transforms input values into membership degrees in the range [0, 1].

Parameters:

x (float or numpy.ndarray) – Input value(s) for which to compute membership degrees. Can be a scalar or array of any shape.

Returns:

Membership degree(s) corresponding to the input values. Output has the same shape as input and values are in [0, 1].

Return type:

float or numpy.ndarray

Notes

Implementations must ensure that: - All output values are in the range [0, 1] - The function handles both scalar and array inputs correctly - Numerical stability is maintained for edge cases - The function is vectorized for efficient array processing

Examples

Implementation example for a simple linear membership function:

def compute(self, x):
    x = np.asarray(x, dtype=float)
    result = (x - self.min_val) / (self.max_val - self.min_val)
    return np.clip(result, 0.0, 1.0)
get_parameters()

Retrieve the current parameters of the membership function.

Returns a dictionary containing all parameters that define the shape and behavior of the membership function. This is useful for introspection, serialization, and debugging.

Returns:

Dictionary mapping parameter names to their current values. The exact keys depend on the specific membership function type.

Return type:

dict

Examples

# For a triangular membership function
mf = TriangularMF(a=0, b=0.5, c=1)
params = mf.get_parameters()
print(params)  # {'a': 0, 'b': 0.5, 'c': 1}

# For a Gaussian membership function
mf = GaussianMF(sigma=1.0, c=0.0)
params = mf.get_parameters()
print(params)  # {'sigma': 1.0, 'c': 0.0}
plot(x_range=(0, 1), num_points=1000)

Generate a matplotlib plot of the membership function.

Creates a visual representation of the membership function over the specified input range. This is useful for function validation, parameter tuning, and educational purposes.

Parameters:
  • x_range (tuple of float, default (0, 1)) – The (min, max) range of input values to plot.

  • num_points (int, default 1000) – Number of points to use for plotting. Higher values create smoother curves but require more computation.

Notes

This method requires matplotlib to be installed. If matplotlib is not available, the method will raise an ImportError.

The plot shows: - X-axis: Input values over the specified range - Y-axis: Membership degrees from 0 to 1 - Title: Function name and type - Grid: Enabled for easier reading

Examples

# Plot with default settings
mf = TriangularMF(a=0, b=0.5, c=1)
mf.plot()

# Plot over custom range with high resolution
mf.plot(x_range=(-2, 3), num_points=2000)

# Plot multiple functions for comparison
mf1 = TriangularMF(a=0, b=0.3, c=0.6)
mf2 = TriangularMF(a=0.4, b=0.7, c=1.0)

import matplotlib.pyplot as plt
mf1.plot()
mf2.plot()
plt.legend(['Function 1', 'Function 2'])
# For users who want to display the plot immediately.

# plt.show() should be called outside the function # to allow for multiple plots to be drawn on the same figure. # plt.show()

Raises:
  • ImportError – If matplotlib is not installed.

  • ValueError – If x_range is invalid or num_points is not positive.

set_parameters(**kwargs)[source]

Update the parameters of the membership function.

This method allows dynamic modification of function parameters after instantiation. Implementations must validate parameters and update both the internal state and the parameters dictionary.

Parameters:

**kwargs – Parameter names and values to update. Only parameters recognized by the specific membership function are processed.

Raises:

ValueError – If invalid parameter values are provided or if parameter combinations violate mathematical constraints.

Notes

Implementations should: - Validate all parameter values before updating - Maintain mathematical constraints (e.g., ordering requirements) - Update both internal attributes and the parameters dict - Provide clear error messages for invalid parameters

Examples

# Update triangular function parameters
mf = TriangularMF(a=0, b=0.5, c=1)
mf.set_parameters(b=0.6, c=1.2)

# Update Gaussian function parameters
mf = GaussianMF(sigma=1.0, c=0.0)
mf.set_parameters(sigma=1.5)  # Only update sigma

# Invalid parameter raises ValueError
try:
    mf.set_parameters(sigma=-1.0)  # Negative sigma
except ValueError as e:
    print(f"Error: {e}")