random.base

Abstract base classes for random fuzzy number generation.

This module provides the foundational interfaces and utilities for implementing random generators for different fuzzy number types (mtypes). The system follows a plugin architecture where each fuzzy number type can register its own specialized random generator.

The module defines two main abstract base classes:

  1. BaseRandomGenerator - Core interface that all generators must implement

  2. ParameterizedRandomGenerator - Helper class with distribution sampling utilities

Architecture

The random generation system is designed around the following principles:

  • Type Specialization: Each fuzzy number type (mtype) has its own generator

  • High Performance: Vectorized batch generation for Fuzzarray creation

  • Flexibility: Parameterized control over distributions and generation modes

  • Reproducibility: Integration with NumPy’s random number generation system

Random generators are registered globally and can be accessed through the registry system. Each generator is responsible for creating both individual Fuzznum instances and batch Fuzzarray instances with optimal performance.

Classes

BaseRandomGenerator

Abstract interface for all random generators.

ParameterizedRandomGenerator

Helper base class with distribution sampling utilities.

See also

axisfuzzy.random.registry

Registration system for random generators

axisfuzzy.random.api

High-level API for random generation

axisfuzzy.fuzztype.qrofn.random

Example implementation for QROFN type

Examples

Implementing a custom random generator:

from axisfuzzy.random.base import ParameterizedRandomGenerator
from axisfuzzy.random import register_random

@register_random
class CustomRandomGenerator(ParameterizedRandomGenerator):
    mtype = "custom"

    def get_default_parameters(self):
        return {
            'param1': 1.0,
            'param2': 0.5,
            'distribution': 'uniform'
        }

    def validate_parameters(self, **params):
        if 'param1' in params and params['param1'] <= 0:
            raise ValueError("param1 must be positive")

    def fuzznum(self, rng, **params):
        # Implementation for single fuzzy number generation
        merged = self._merge_parameters(**params)
        value = self._sample_from_distribution(
            rng, dist=merged['distribution'],
            low=0, high=merged['param1']
        )
        return Fuzznum(mtype='custom').create(value=value)

    def fuzzarray(self, rng, shape, **params):
        # Implementation for batch generation
        merged = self._merge_parameters(**params)
        # ... batch generation logic
        return Fuzzarray(...)

Using the registered generator:

import axisfuzzy.random as fr

# Generate single instance
num = fr.rand('custom', param1=2.0)

# Generate batch
arr = fr.rand('custom', shape=(100,), param2=0.8)
class axisfuzzy.random.base.BaseRandomGenerator[source]

Bases: ABC

Abstract base class for fuzzy number random generators.

This class defines the interface that all random generators must implement to be compatible with the AxisFuzzy random generation system. Each fuzzy number type (mtype) should have a corresponding generator that inherits from this class.

The generator is responsible for creating both individual Fuzznum instances and batch Fuzzarray instances with high performance vectorized operations.

mtype

The fuzzy number type identifier that this generator handles. Must be set by concrete implementations.

Type:

str

Notes

Concrete implementations must set the mtype class attribute and implement all abstract methods. The generator should be stateless to ensure thread safety and consistent behavior.

For high-performance batch generation, implementations should avoid creating intermediate Fuzznum objects and instead populate backend arrays directly.

See also

ParameterizedRandomGenerator

Helper base class with distribution utilities

axisfuzzy.random.registry.register_random

Decorator for automatic registration

Examples

Basic generator structure:

class MyGenerator(BaseRandomGenerator):
    mtype = "mytype"

    def get_default_parameters(self):
        return {'param1': 1.0, 'param2': 0.5}

    def validate_parameters(self, **params):
        # Validate parameter values
        pass

    def fuzznum(self, rng, **params):
        # Generate single fuzzy number
        return Fuzznum(mtype=self.mtype).create(...)

    def fuzzarray(self, rng, shape, **params):
        # Generate batch array
        return Fuzzarray(...)
abstractmethod fuzzarray(rng, shape, **params)[source]

Generate a Fuzzarray of random fuzzy numbers.

Creates a multi-dimensional array of fuzzy numbers with the specified shape and parameters. This method is designed for high-performance batch generation using vectorized operations.

Parameters:
  • rng (numpy.random.Generator) – NumPy random number generator instance for sampling.

  • shape (tuple of int) – The desired shape of the output Fuzzarray.

  • **params (dict) – Generation parameters including structural parameters (like ‘q’) and procedural parameters (like distribution settings).

Returns:

Multi-dimensional array of fuzzy numbers with the specified shape.

Return type:

Fuzzarray

Notes

This method should be highly optimized for performance:

  • Use vectorized NumPy operations for sampling

  • Avoid creating intermediate Fuzznum objects

  • Populate backend arrays directly when possible

  • Handle constraints efficiently using array operations

For large arrays, consider memory-efficient generation strategies and avoid operations that scale quadratically with array size.

Examples

def fuzzarray(self, rng, shape, **params):
    merged = self._merge_parameters(**params)
    self.validate_parameters(**merged)

    size = int(np.prod(shape))

    # Vectorized generation
    mds = rng.uniform(
        merged['md_low'], merged['md_high'], size=size
    )

    # Constraint handling
    max_nmds = (1 - mds**merged['q']) ** (1/merged['q'])
    nmds = rng.uniform(0, max_nmds)

    # Create backend directly
    backend = MyBackend.from_arrays(
        mds=mds.reshape(shape),
        nmds=nmds.reshape(shape),
        q=merged['q']
    )

    return Fuzzarray(backend=backend)
abstractmethod fuzznum(rng, **params)[source]

Generate a single random Fuzznum instance.

Creates one fuzzy number with the specified parameters using the provided random number generator for reproducible results.

Parameters:
  • rng (numpy.random.Generator) – NumPy random number generator instance for sampling.

  • **params (dict) – Generation parameters including structural parameters (like ‘q’) and procedural parameters (like distribution settings). Parameters not provided will use default values.

Returns:

A single fuzzy number instance of the appropriate mtype.

Return type:

Fuzznum

Notes

This method should be implemented efficiently but the primary performance focus should be on the fuzzarray() method for batch generation scenarios.

Examples

def fuzznum(self, rng, **params):
    merged = self._merge_parameters(**params)
    self.validate_parameters(**merged)

    # Generate membership degree
    md = rng.uniform(merged['md_low'], merged['md_high'])

    # Generate non-membership degree with constraints
    max_nmd = (1 - md**merged['q']) ** (1/merged['q'])
    nmd = rng.uniform(0, max_nmd)

    return Fuzznum(mtype=self.mtype, q=merged['q']).create(
        md=md, nmd=nmd
    )
abstractmethod get_default_parameters()[source]

Get the default parameters for random generation.

Returns the default configuration for all parameters that control the random generation process. These defaults can be overridden when calling the generation methods.

Returns:

Dictionary mapping parameter names to their default values. The exact parameters depend on the specific fuzzy number type and generation strategy.

Return type:

dict

Notes

Default parameters should include all necessary configuration for the generator to function properly. Structural parameters like ‘q’ (q-rung) are typically not included in defaults as they are usually provided explicitly.

Examples

def get_default_parameters(self):
    return {
        'md_dist': 'uniform',
        'md_low': 0.0,
        'md_high': 1.0,
        'nu_mode': 'orthopair',
        'distribution_params': {'a': 2.0, 'b': 2.0}
    }
mtype: str = 'unknown'

The fuzzy number type identifier handled by this generator.

Type:

str

abstractmethod validate_parameters(**params)[source]

Validate parameters for random generation.

Checks that all provided parameters have valid values and that parameter combinations are mathematically consistent. This method should raise appropriate exceptions for invalid configurations.

Parameters:

**params (dict) – Parameter values to validate, including both structural parameters (like ‘q’) and procedural parameters (like distribution settings).

Raises:
  • ValueError – If any parameter value is invalid or if parameter combinations violate mathematical constraints.

  • TypeError – If parameters have incorrect types.

Notes

Return type:

None

Validation should be comprehensive but efficient, as it may be called frequently during batch generation. Consider caching validation results for repeated parameter sets.

Examples

def validate_parameters(self, **params):
    if 'q' in params:
        q = params['q']
        if not isinstance(q, int) or q <= 0:
            raise ValueError(f"q must be positive integer, got {q}")

    if 'md_low' in params and 'md_high' in params:
        if params['md_low'] > params['md_high']:
            raise ValueError("md_low cannot exceed md_high")
class axisfuzzy.random.base.ParameterizedRandomGenerator[source]

Bases: BaseRandomGenerator, ABC

Helper base class for generators using parameterized distributions.

This class extends BaseRandomGenerator with common utilities for parameter management and statistical distribution sampling. It simplifies the implementation of concrete generators by providing ready-to-use methods for common operations.

The class provides: - Parameter merging and default handling - Vectorized sampling from standard distributions - Parameter validation utilities - Efficient distribution parameter management

Notes

This class is designed for generators that use standard statistical distributions (uniform, beta, normal) for sampling fuzzy number components. Generators with highly specialized sampling logic may inherit directly from BaseRandomGenerator.

The class maintains cached default parameters for efficiency during repeated generation calls.

See also

BaseRandomGenerator

Core interface for all generators

Examples

Using the parameterized base class:

@register_random
class MyGenerator(ParameterizedRandomGenerator):
    mtype = "mytype"

    def get_default_parameters(self):
        return {
            'md_dist': 'uniform',
            'md_low': 0.0,
            'md_high': 1.0,
            'a': 2.0,  # Beta parameter
            'b': 2.0   # Beta parameter
        }

    def fuzznum(self, rng, **params):
        merged = self._merge_parameters(**params)

        # Use built-in distribution sampling
        md = self._sample_from_distribution(
            rng,
            dist=merged['md_dist'],
            low=merged['md_low'],
            high=merged['md_high'],
            a=merged['a'],
            b=merged['b']
        )

        return Fuzznum(mtype=self.mtype).create(md=md)
abstractmethod fuzzarray(rng, shape, **params)

Generate a Fuzzarray of random fuzzy numbers.

Creates a multi-dimensional array of fuzzy numbers with the specified shape and parameters. This method is designed for high-performance batch generation using vectorized operations.

Parameters:
  • rng (numpy.random.Generator) – NumPy random number generator instance for sampling.

  • shape (tuple of int) – The desired shape of the output Fuzzarray.

  • **params (dict) – Generation parameters including structural parameters (like ‘q’) and procedural parameters (like distribution settings).

Returns:

Multi-dimensional array of fuzzy numbers with the specified shape.

Return type:

Fuzzarray

Notes

This method should be highly optimized for performance:

  • Use vectorized NumPy operations for sampling

  • Avoid creating intermediate Fuzznum objects

  • Populate backend arrays directly when possible

  • Handle constraints efficiently using array operations

For large arrays, consider memory-efficient generation strategies and avoid operations that scale quadratically with array size.

Examples

def fuzzarray(self, rng, shape, **params):
    merged = self._merge_parameters(**params)
    self.validate_parameters(**merged)

    size = int(np.prod(shape))

    # Vectorized generation
    mds = rng.uniform(
        merged['md_low'], merged['md_high'], size=size
    )

    # Constraint handling
    max_nmds = (1 - mds**merged['q']) ** (1/merged['q'])
    nmds = rng.uniform(0, max_nmds)

    # Create backend directly
    backend = MyBackend.from_arrays(
        mds=mds.reshape(shape),
        nmds=nmds.reshape(shape),
        q=merged['q']
    )

    return Fuzzarray(backend=backend)
abstractmethod fuzznum(rng, **params)

Generate a single random Fuzznum instance.

Creates one fuzzy number with the specified parameters using the provided random number generator for reproducible results.

Parameters:
  • rng (numpy.random.Generator) – NumPy random number generator instance for sampling.

  • **params (dict) – Generation parameters including structural parameters (like ‘q’) and procedural parameters (like distribution settings). Parameters not provided will use default values.

Returns:

A single fuzzy number instance of the appropriate mtype.

Return type:

Fuzznum

Notes

This method should be implemented efficiently but the primary performance focus should be on the fuzzarray() method for batch generation scenarios.

Examples

def fuzznum(self, rng, **params):
    merged = self._merge_parameters(**params)
    self.validate_parameters(**merged)

    # Generate membership degree
    md = rng.uniform(merged['md_low'], merged['md_high'])

    # Generate non-membership degree with constraints
    max_nmd = (1 - md**merged['q']) ** (1/merged['q'])
    nmd = rng.uniform(0, max_nmd)

    return Fuzznum(mtype=self.mtype, q=merged['q']).create(
        md=md, nmd=nmd
    )
abstractmethod get_default_parameters()

Get the default parameters for random generation.

Returns the default configuration for all parameters that control the random generation process. These defaults can be overridden when calling the generation methods.

Returns:

Dictionary mapping parameter names to their default values. The exact parameters depend on the specific fuzzy number type and generation strategy.

Return type:

dict

Notes

Default parameters should include all necessary configuration for the generator to function properly. Structural parameters like ‘q’ (q-rung) are typically not included in defaults as they are usually provided explicitly.

Examples

def get_default_parameters(self):
    return {
        'md_dist': 'uniform',
        'md_low': 0.0,
        'md_high': 1.0,
        'nu_mode': 'orthopair',
        'distribution_params': {'a': 2.0, 'b': 2.0}
    }
mtype: str = 'unknown'

The fuzzy number type identifier handled by this generator.

Type:

str

abstractmethod validate_parameters(**params)

Validate parameters for random generation.

Checks that all provided parameters have valid values and that parameter combinations are mathematically consistent. This method should raise appropriate exceptions for invalid configurations.

Parameters:

**params (dict) – Parameter values to validate, including both structural parameters (like ‘q’) and procedural parameters (like distribution settings).

Raises:
  • ValueError – If any parameter value is invalid or if parameter combinations violate mathematical constraints.

  • TypeError – If parameters have incorrect types.

Notes

Return type:

None

Validation should be comprehensive but efficient, as it may be called frequently during batch generation. Consider caching validation results for repeated parameter sets.

Examples

def validate_parameters(self, **params):
    if 'q' in params:
        q = params['q']
        if not isinstance(q, int) or q <= 0:
            raise ValueError(f"q must be positive integer, got {q}")

    if 'md_low' in params and 'md_high' in params:
        if params['md_low'] > params['md_high']:
            raise ValueError("md_low cannot exceed md_high")