Skip to content

Commit f45d60b

Browse files
committed
example: example updated to use it in docs
1 parent a96d0e5 commit f45d60b

15 files changed

Lines changed: 789 additions & 338 deletions

File tree

examples/example-parametric.ipynb

Lines changed: 0 additions & 279 deletions
This file was deleted.

examples/overview.ipynb

Lines changed: 676 additions & 0 deletions
Large diffs are not rendered by default.

src/pysatl_core/distributions/distribution.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111
__copyright__ = "Copyright (c) 2025 PySATL project"
1212
__license__ = "SPDX-License-Identifier: MIT"
1313

14-
from typing import TYPE_CHECKING, Protocol, runtime_checkable
14+
from typing import TYPE_CHECKING, Protocol, cast, runtime_checkable
15+
16+
from pysatl_core.types import NumericArray
1517

1618
if TYPE_CHECKING:
1719
from collections.abc import Mapping
1820
from typing import Any
1921

2022
from pysatl_core.distributions.computation import AnalyticalComputation
21-
from pysatl_core.distributions.sampling import Sample
2223
from pysatl_core.distributions.strategies import (
2324
ComputationStrategy,
2425
Method,
@@ -113,7 +114,7 @@ def calculate_characteristic(
113114
"""
114115
return self.query_method(characteristic_name, **options)(value)
115116

116-
def sample(self, n: int, **options: Any) -> Sample:
117+
def sample(self, n: int, **options: Any) -> NumericArray:
117118
"""
118119
Generate random samples from the distribution.
119120
@@ -122,11 +123,14 @@ def sample(self, n: int, **options: Any) -> Sample:
122123
n : int
123124
Number of samples to generate.
124125
**options : Any
125-
Additional sampling options.
126+
Additional sampling options forwarded to the underlying
127+
sampling strategy.
126128
127129
Returns
128130
-------
129-
Sample
130-
Container with the generated samples.
131+
NumericArray
132+
NumPy array containing ``n`` generated samples.
133+
The exact array shape depends on the distribution and
134+
the sampling strategy.
131135
"""
132-
return self.sampling_strategy.sample(n, distr=self, **options)
136+
return cast(NumericArray, self.sampling_strategy.sample(n, distr=self, **options))

src/pysatl_core/distributions/sampling.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import numpy.typing as npt
2323

2424

25+
# TODO: This is probably a stillborn idea, it's better to just use NumPy arrays.
2526
class Sample(Protocol):
2627
"""
2728
Protocol for sample containers.
@@ -41,6 +42,7 @@ def array(self) -> npt.NDArray[np.floating[Any]]: ...
4142
def shape(self) -> tuple[int, ...]: ...
4243

4344

45+
# TODO: This is probably a stillborn idea, it's better to just use NumPy arrays.
4446
class ArraySample:
4547
"""
4648
Array-backed sample container.

src/pysatl_core/distributions/strategies.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,18 @@
1111
__copyright__ = "Copyright (c) 2025 PySATL project"
1212
__license__ = "SPDX-License-Identifier: MIT"
1313

14-
from typing import TYPE_CHECKING, Protocol
14+
from typing import TYPE_CHECKING, Protocol, cast
1515

1616
import numpy as np
1717

1818
from pysatl_core.distributions.registry import characteristic_registry
19-
from pysatl_core.distributions.sampling import ArraySample
19+
from pysatl_core.types import CharacteristicName, NumericArray
2020

2121
if TYPE_CHECKING:
2222
from typing import Any
2323

2424
from pysatl_core.distributions.computation import AnalyticalComputation, FittedComputationMethod
2525
from pysatl_core.distributions.distribution import Distribution
26-
from pysatl_core.distributions.sampling import Sample
2726
from pysatl_core.types import GenericCharacteristicName
2827

2928
type Method[In, Out] = AnalyticalComputation[In, Out] | FittedComputationMethod[In, Out]
@@ -186,25 +185,27 @@ def query_method(
186185
class SamplingStrategy(Protocol):
187186
"""Protocol for strategies that generate samples from distributions."""
188187

189-
def sample(self, n: int, distr: Distribution, **options: Any) -> Sample: ...
188+
def sample(self, n: int, distr: Distribution, **options: Any) -> NumericArray: ...
190189

191190

192191
class DefaultSamplingUnivariateStrategy(SamplingStrategy):
193192
"""
194-
Default univariate sampler using inverse transform sampling.
193+
Default univariate sampler based on inverse transform sampling.
195194
196195
This strategy generates samples by applying the PPF (inverse CDF)
197-
to uniform random variables.
196+
to uniformly distributed random variables.
198197
199198
Notes
200199
-----
201200
- Requires the distribution to provide a PPF computation method.
202-
- Returns samples as a 2D array of shape (n, 1).
201+
- Assumes that the PPF follows NumPy semantics (vectorized evaluation).
202+
- Graph-derived PPFs (scalar-only) are currently not supported.
203+
- Returns a NumPy array containing the generated samples.
203204
"""
204205

205-
def sample(self, n: int, distr: Distribution, **options: Any) -> ArraySample:
206+
def sample(self, n: int, distr: Distribution, **options: Any) -> NumericArray:
206207
"""
207-
Generate n samples from the distribution.
208+
Generate samples from the distribution.
208209
209210
Parameters
210211
----------
@@ -213,15 +214,19 @@ def sample(self, n: int, distr: Distribution, **options: Any) -> ArraySample:
213214
distr : Distribution
214215
Distribution to sample from.
215216
**options : Any
216-
Additional options passed to the PPF computation.
217+
Additional options forwarded to the PPF computation.
217218
218219
Returns
219220
-------
220-
ArraySample
221-
Samples as a 2D array of shape (n, 1).
221+
NumericArray
222+
NumPy array containing ``n`` generated samples.
223+
The exact array shape depends on the distribution and sampling strategy.
222224
"""
223-
ppf = distr.query_method("ppf", **options)
225+
ppf = distr.query_method(CharacteristicName.PPF, **options)
224226
rng = np.random.default_rng()
225227
U = rng.random(n)
226-
vals = np.array([ppf(Ui) for Ui in U], dtype=np.float64).reshape(n, 1)
227-
return ArraySample(vals)
228+
# TODO: Now it will be based on the fact that the characteristic
229+
# has NumPy semantics (It is much more faster), that is,
230+
# it will not work with the graph computed characteristics currently.
231+
samples = ppf(U)
232+
return cast(NumericArray, samples)

src/pysatl_core/families/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
__license__ = "SPDX-License-Identifier: MIT"
1111

1212

13+
from .builtins import * # noqa: UP029
14+
from .builtins import __all__ as _builtins_all
1315
from .configuration import configure_families_register
1416
from .distribution import ParametricFamilyDistribution
1517
from .parametric_family import ParametricFamily
@@ -30,4 +32,8 @@
3032
"constraint",
3133
"parametrization",
3234
"configure_families_register",
35+
# builtins
36+
*_builtins_all,
3337
]
38+
39+
del _builtins_all

src/pysatl_core/families/builtins/__init__.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,11 @@
1010
__license__ = "SPDX-License-Identifier: MIT"
1111

1212

13-
from pysatl_core.families.builtins.continuous import (
14-
configure_exponential_family,
15-
configure_normal_family,
16-
configure_uniform_family,
17-
)
13+
from .continuous import *
14+
from .continuous import __all__ as _continuous_all
1815

1916
__all__ = [
20-
"configure_normal_family",
21-
"configure_uniform_family",
22-
"configure_exponential_family",
17+
*_continuous_all,
2318
]
19+
20+
del _continuous_all

src/pysatl_core/families/builtins/continuous/exponential.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
import numpy as np
1616

17-
from pysatl_core.distributions.strategies import DefaultSamplingUnivariateStrategy
1817
from pysatl_core.distributions.support import ContinuousSupport
1918
from pysatl_core.families.parametric_family import ParametricFamily
2019
from pysatl_core.families.parametrizations import (
@@ -39,6 +38,10 @@ def configure_exponential_family() -> None:
3938
"""
4039
Configure and register the Exponential distribution family.
4140
"""
41+
42+
if ParametricFamilyRegister.contains(FamilyName.EXPONENTIAL):
43+
return
44+
4245
EXPONENTIAL_DOC = """
4346
Exponential distribution.
4447
@@ -215,7 +218,6 @@ def _support(_: Parametrization) -> ContinuousSupport:
215218
CharacteristicName.SKEW: skew_func,
216219
CharacteristicName.KURT: kurt_func,
217220
},
218-
sampling_strategy=DefaultSamplingUnivariateStrategy(),
219221
support_by_parametrization=_support,
220222
)
221223
Exponential.__doc__ = EXPONENTIAL_DOC

src/pysatl_core/families/builtins/continuous/normal.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import numpy as np
1717
from scipy.special import erf, erfinv
1818

19-
from pysatl_core.distributions.strategies import DefaultSamplingUnivariateStrategy
2019
from pysatl_core.distributions.support import ContinuousSupport
2120
from pysatl_core.families.parametric_family import ParametricFamily
2221
from pysatl_core.families.parametrizations import (
@@ -41,6 +40,10 @@ def configure_normal_family() -> None:
4140
"""
4241
Configure and register the Normal distribution family.
4342
"""
43+
44+
if ParametricFamilyRegister.contains(FamilyName.NORMAL):
45+
return
46+
4447
NORMAL_DOC = """
4548
Normal (Gaussian) distribution.
4649
@@ -218,7 +221,6 @@ def _support(_: Parametrization) -> ContinuousSupport:
218221
CharacteristicName.SKEW: skew_func,
219222
CharacteristicName.KURT: kurt_func,
220223
},
221-
sampling_strategy=DefaultSamplingUnivariateStrategy(),
222224
support_by_parametrization=_support,
223225
)
224226
Normal.__doc__ = NORMAL_DOC

src/pysatl_core/families/builtins/continuous/uniform.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
import numpy as np
1616

17-
from pysatl_core.distributions.strategies import DefaultSamplingUnivariateStrategy
1817
from pysatl_core.distributions.support import ContinuousSupport
1918
from pysatl_core.families.parametric_family import ParametricFamily
2019
from pysatl_core.families.parametrizations import (
@@ -39,6 +38,10 @@ def configure_uniform_family() -> None:
3938
"""
4039
Configure and register the Uniform distribution family.
4140
"""
41+
42+
if ParametricFamilyRegister.contains(FamilyName.CONTINUOUS_UNIFORM):
43+
return
44+
4245
UNIFORM_DOC = """
4346
Uniform (continuous) distribution.
4447
@@ -250,7 +253,6 @@ def _support(parameters: Parametrization) -> ContinuousSupport:
250253
CharacteristicName.SKEW: skew_func,
251254
CharacteristicName.KURT: kurt_func,
252255
},
253-
sampling_strategy=DefaultSamplingUnivariateStrategy(),
254256
support_by_parametrization=_support,
255257
)
256258
Uniform.__doc__ = UNIFORM_DOC

0 commit comments

Comments
 (0)