1111__copyright__ = "Copyright (c) 2025 PySATL project"
1212__license__ = "SPDX-License-Identifier: MIT"
1313
14-
15- from dataclasses import dataclass
1614from typing import TYPE_CHECKING , cast
1715
1816from pysatl_core .distributions .distribution import Distribution
17+ from pysatl_core .distributions .strategies import (
18+ DefaultComputationStrategy ,
19+ DefaultSamplingUnivariateStrategy ,
20+ )
1921from pysatl_core .families .registry import ParametricFamilyRegister
2022from pysatl_core .types import NumericArray
2123
4042 ParametrizationName ,
4143 )
4244
45+ _KEEP : object = object ()
46+
4347
44- @dataclass (slots = True )
4548class 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