Skip to content

Commit c710894

Browse files
author
Леонид Елкин
committed
refactor: strategies now is one per distribution
1 parent 5417c30 commit c710894

4 files changed

Lines changed: 190 additions & 69 deletions

File tree

src/pysatl_core/families/distribution.py

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

14-
15-
from dataclasses import dataclass
1614
from typing import TYPE_CHECKING, cast
1715

1816
from pysatl_core.distributions.distribution import Distribution
17+
from pysatl_core.distributions.strategies import (
18+
DefaultComputationStrategy,
19+
DefaultSamplingUnivariateStrategy,
20+
)
1921
from pysatl_core.families.registry import ParametricFamilyRegister
2022
from pysatl_core.types import NumericArray
2123

@@ -40,8 +42,9 @@
4042
ParametrizationName,
4143
)
4244

45+
_KEEP: object = object()
46+
4347

44-
@dataclass(slots=True)
4548
class ParametricFamilyDistribution(Distribution):
4649
"""
4750
A specific distribution instance from a parametric family.
@@ -53,18 +56,44 @@ class ParametricFamilyDistribution(Distribution):
5356
----------
5457
family_name : str
5558
Name of the distribution family.
56-
_distribution_type : DistributionType
59+
distribution_type : DistributionType
5760
Type of this distribution.
58-
_parametrization : Parametrization
61+
parametrization : Parametrization
5962
Parameter values for this distribution.
60-
_support : Support or None
63+
support : Support or None
6164
Support of this distribution.
65+
sampling_strategy : SamplingStrategy
66+
Strategy for generating random samples.
67+
computation_strategy : ComputationStrategy
68+
Strategy for computing characteristics and conversions.
6269
"""
6370

64-
family_name: str
65-
_distribution_type: DistributionType
66-
_parametrization: Parametrization
67-
_support: Support | None
71+
def __init__(
72+
self,
73+
family_name: str,
74+
distribution_type: DistributionType,
75+
parametrization: Parametrization,
76+
support: Support | None,
77+
sampling_strategy: SamplingStrategy | None = None,
78+
computation_strategy: ComputationStrategy[Any, Any] | None = None,
79+
):
80+
self._distribution_type = distribution_type
81+
self._family_name = family_name
82+
self._parametrization = parametrization
83+
self._support = support
84+
85+
self._computation_strategy = computation_strategy or DefaultComputationStrategy()
86+
self._sampling_strategy = sampling_strategy or DefaultSamplingUnivariateStrategy()
87+
88+
self._analytical_cache_key: tuple[int, GenericCharacteristicName] | None = None
89+
self._analytical_cache_val: (
90+
Mapping[GenericCharacteristicName, AnalyticalComputation[Any, Any]] | None
91+
) = None
92+
93+
@property
94+
def family_name(self) -> str:
95+
"Get the name of the family this distribution belongs to."
96+
return self._family_name
6897

6998
@property
7099
def distribution_type(self) -> DistributionType:
@@ -142,25 +171,110 @@ def analytical_computations(
142171
parametrization object or name changes.
143172
"""
144173
key = (id(self.parametrization), self.parametrization_name)
145-
cache_key = getattr(self, "_analytical_cache_key", None)
146-
cache_val = getattr(self, "_analytical_cache_val", None)
147174

148-
if cache_key != key or cache_val is None:
149-
cache_val = self.family._build_analytical_computations(self.parametrization)
175+
if self._analytical_cache_key != key or self._analytical_cache_val is None:
176+
self._analytical_cache_val = self.family.build_analytical_computations(
177+
self.parametrization
178+
)
150179
self._analytical_cache_key = key
151-
self._analytical_cache_val = cache_val
152180

153-
return cache_val
181+
return self._analytical_cache_val
154182

155183
@property
156184
def sampling_strategy(self) -> SamplingStrategy:
157185
"""Get the sampling strategy for this distribution."""
158-
return self.family.sampling_strategy
186+
return self._sampling_strategy
159187

160188
@property
161189
def computation_strategy(self) -> ComputationStrategy[Any, Any]:
162190
"""Get the computation strategy for this distribution."""
163-
return self.family.computation_strategy
191+
return self._computation_strategy
192+
193+
def with_sampling_strategy(
194+
self, sampling_strategy: SamplingStrategy | None
195+
) -> ParametricFamilyDistribution:
196+
"""
197+
Return a copy of this distribution with an updated sampling strategy.
198+
199+
Parameters
200+
----------
201+
sampling_strategy : SamplingStrategy | None
202+
New sampling strategy. If ``None``, the default sampling strategy is used.
203+
204+
Returns
205+
-------
206+
ParametricFamilyDistribution
207+
New distribution instance with the same parameters and updated strategy.
208+
"""
209+
return ParametricFamilyDistribution(
210+
family_name=self._family_name,
211+
distribution_type=self._distribution_type,
212+
parametrization=self._parametrization,
213+
support=self._support,
214+
sampling_strategy=sampling_strategy,
215+
computation_strategy=self._computation_strategy,
216+
)
217+
218+
def with_computation_strategy(
219+
self, computation_strategy: ComputationStrategy[Any, Any] | None
220+
) -> ParametricFamilyDistribution:
221+
"""
222+
Return a copy of this distribution with an updated computation strategy.
223+
224+
Parameters
225+
----------
226+
computation_strategy : ComputationStrategy[Any, Any] | None
227+
New computation strategy. If ``None``, the default computation strategy is used.
228+
229+
Returns
230+
-------
231+
ParametricFamilyDistribution
232+
New distribution instance with the same parameters and updated strategy.
233+
"""
234+
return ParametricFamilyDistribution(
235+
family_name=self._family_name,
236+
distribution_type=self._distribution_type,
237+
parametrization=self._parametrization,
238+
support=self._support,
239+
sampling_strategy=self._sampling_strategy,
240+
computation_strategy=computation_strategy,
241+
)
242+
243+
def with_strategies(
244+
self,
245+
*,
246+
sampling_strategy: SamplingStrategy | None = None,
247+
computation_strategy: ComputationStrategy[Any, Any] | None = None,
248+
) -> ParametricFamilyDistribution:
249+
"""
250+
Return a copy of this distribution with updated strategies.
251+
252+
Parameters
253+
----------
254+
sampling_strategy : SamplingStrategy | None | object, optional
255+
New sampling strategy. If not provided, the current strategy is preserved.
256+
If explicitly set to ``None``, the default sampling strategy is used.
257+
computation_strategy : ComputationStrategy[Any, Any] | None | object, optional
258+
New computation strategy. If not provided, the current strategy is preserved.
259+
If explicitly set to ``None``, the default computation strategy is used.
260+
261+
Returns
262+
-------
263+
ParametricFamilyDistribution
264+
New distribution instance with the same parameters and updated strategies.
265+
"""
266+
new_sampling = self._sampling_strategy if sampling_strategy is _KEEP else sampling_strategy
267+
new_computation = (
268+
self._computation_strategy if computation_strategy is _KEEP else computation_strategy
269+
)
270+
return ParametricFamilyDistribution(
271+
family_name=self._family_name,
272+
distribution_type=self._distribution_type,
273+
parametrization=self._parametrization,
274+
support=self._support,
275+
sampling_strategy=new_sampling,
276+
computation_strategy=new_computation,
277+
)
164278

165279
@property
166280
def support(self) -> Support | None:

0 commit comments

Comments
 (0)