Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions src/pysatl_core/distributions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@
from .distribution import Distribution
from .registry import *
from .registry import __all__ as _registry_all
from .sampling import ArraySample, Sample
from .strategies import (
ComputationStrategy,
DefaultComputationStrategy,
DefaultSamplingUnivariateStrategy,
SamplingStrategy,
)
from .support import *
Expand All @@ -38,14 +36,10 @@
"FittedComputationMethod",
# distribution
"Distribution",
# sampling
"Sample",
"ArraySample",
# strategies
"ComputationStrategy",
"DefaultComputationStrategy",
"SamplingStrategy",
"DefaultSamplingUnivariateStrategy",
# registry
*_registry_all,
# support
Expand Down
6 changes: 2 additions & 4 deletions src/pysatl_core/distributions/distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,8 @@ def __init__(
computation_strategy : ComputationStrategy or None, default=None
Computation strategy instance. If omitted, default strategy is used.
"""
from pysatl_core.distributions.strategies import (
DefaultComputationStrategy,
DefaultSamplingUnivariateStrategy,
)
from pysatl_core.distributions.strategies import DefaultComputationStrategy
from pysatl_core.sampling.default import DefaultSamplingUnivariateStrategy

self._distribution_type = distribution_type
normalized_analytical: dict[
Expand Down
102 changes: 0 additions & 102 deletions src/pysatl_core/distributions/sampling.py

This file was deleted.

48 changes: 1 addition & 47 deletions src/pysatl_core/distributions/strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@

from typing import TYPE_CHECKING, Any, Protocol, cast

import numpy as np

from pysatl_core.distributions.registry import characteristic_registry
from pysatl_core.types import CharacteristicName, Method, NumericArray
from pysatl_core.types import Method, NumericArray

if TYPE_CHECKING:
from collections.abc import Mapping
Expand Down Expand Up @@ -236,47 +234,3 @@ class SamplingStrategy(Protocol):
"""Protocol for strategies that generate samples from distributions."""

def sample(self, n: int, distr: Distribution, **options: Any) -> NumericArray: ...


class DefaultSamplingUnivariateStrategy(SamplingStrategy):
"""
Default univariate sampler based on inverse transform sampling.

This strategy generates samples by applying the PPF (inverse CDF)
to uniformly distributed random variables.

Notes
-----
- Requires the distribution to provide a PPF computation method.
- Assumes that the PPF follows NumPy semantics (vectorized evaluation).
- Graph-derived PPFs (scalar-only) are currently not supported.
- Returns a NumPy array containing the generated samples.
"""

def sample(self, n: int, distr: Distribution, **options: Any) -> NumericArray:
"""
Generate samples from the distribution.

Parameters
----------
n : int
Number of samples to generate.
distr : Distribution
Distribution to sample from.
**options : Any
Additional options forwarded to the PPF computation.

Returns
-------
NumericArray
NumPy array containing ``n`` generated samples.
The exact array shape depends on the distribution and sampling strategy.
"""
ppf = distr.query_method(CharacteristicName.PPF, **options)
rng = np.random.default_rng()
U = rng.random(n)
# TODO: Now it will be based on the fact that the characteristic
# has NumPy semantics (It is much more faster), that is,
# it will not work with the graph computed characteristics currently.
samples = ppf(U)
return cast(NumericArray, samples)
2 changes: 2 additions & 0 deletions src/pysatl_core/sampling/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
__copyright__ = "Copyright (c) 2025 PySATL project"
__license__ = "SPDX-License-Identifier: MIT"

from .default import DefaultSamplingUnivariateStrategy
from .unuran import (
DefaultUnuranSampler,
DefaultUnuranSamplingStrategy,
Expand All @@ -19,6 +20,7 @@
DefaultSamplingStrategy = DefaultUnuranSamplingStrategy

__all__ = [
"DefaultSamplingUnivariateStrategy",
"SamplingMethod",
"SamplingMethodConfig",
"DefaultSampler",
Expand Down
68 changes: 68 additions & 0 deletions src/pysatl_core/sampling/default.py
Comment thread
wrdxwrdxwrdx marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""
Simple Inverse-Transform Sampling Strategy
==========================================

This module provides a basic univariate sampler based on inverse transform
sampling (also known as the quantile/PPF method). It is used as a fallback
when advanced sampling methods (e.g. UNU.RAN) are not available.
"""

from __future__ import annotations

__author__ = "Leonid Elkin, Mikhail Mikhailov"
__copyright__ = "Copyright (c) 2025 PySATL project"
__license__ = "SPDX-License-Identifier: MIT"

from typing import TYPE_CHECKING, Any, cast

import numpy as np

from pysatl_core.distributions.strategies import SamplingStrategy
from pysatl_core.types import CharacteristicName, NumericArray

if TYPE_CHECKING:
from pysatl_core.distributions.distribution import Distribution


class DefaultSamplingUnivariateStrategy(SamplingStrategy):
"""
Default univariate sampler based on inverse transform sampling.

This strategy generates samples by applying the PPF (inverse CDF)
to uniformly distributed random variables.

Notes
-----
- Requires the distribution to provide a PPF computation method.
- Assumes that the PPF follows NumPy semantics (vectorized evaluation).
- Graph-derived PPFs (scalar-only) are currently not supported.
- Returns a NumPy array containing the generated samples.
"""

def sample(self, n: int, distr: Distribution, **options: Any) -> NumericArray:
"""
Generate samples from the distribution.

Parameters
----------
n : int
Number of samples to generate.
distr : Distribution
Distribution to sample from.
**options : Any
Additional options forwarded to the PPF computation.

Returns
-------
NumericArray
NumPy array containing ``n`` generated samples.
The exact array shape depends on the distribution and sampling strategy.
"""
ppf = distr.query_method(CharacteristicName.PPF, **options)
rng = np.random.default_rng()
U = rng.random(n)
# TODO: Now it will be based on the fact that the characteristic
# has NumPy semantics (It is much more faster), that is,
# it will not work with the graph computed characteristics currently.
samples = ppf(U)
return cast(NumericArray, samples)
2 changes: 1 addition & 1 deletion src/pysatl_core/sampling/unuran/core/unuran_sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
import numpy as np
import numpy.typing as npt

from pysatl_core.distributions.strategies import DefaultSamplingUnivariateStrategy
from pysatl_core.distributions.support import ExplicitTableDiscreteSupport
from pysatl_core.sampling.default import DefaultSamplingUnivariateStrategy
from pysatl_core.sampling.unuran.core._unuran_sampler import (
UnuranSamplerInitializer,
ensure_default_urng,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

from typing import TYPE_CHECKING, Any, Final

from pysatl_core.distributions.strategies import DefaultSamplingUnivariateStrategy
from pysatl_core.sampling.default import DefaultSamplingUnivariateStrategy
from pysatl_core.sampling.unuran.core.unuran_sampler import DefaultUnuranSampler
from pysatl_core.sampling.unuran.method_config import (
UnuranMethodConfig,
Expand Down
Loading