99class Sampler :
1010 property : str
1111
12- def __init__ (self , property : str ):
12+ def __init__ (
13+ self ,
14+ property : str ,
15+ min : float | None = None ,
16+ max : float | None = None ,
17+ scale : float = 1.0 ,
18+ ):
1319 self .property = property
20+ self .min = min
21+ self .max = max
22+ self .scale = scale
23+ self .first = True
1424
1525 @staticmethod
1626 def _from_yaml (property : str , params : Dict ) -> "Sampler" :
@@ -23,6 +33,9 @@ def _from_yaml(property: str, params: Dict) -> "Sampler":
2333 params ["value" ],
2434 params .get ("sample" , "independent" ) == "accumulate" ,
2535 params .get ("start" , None ),
36+ params .get ("min" , None ),
37+ params .get ("max" , None ),
38+ params .get ("scale" , 1.0 ),
2639 )
2740
2841 if "distribution" in params :
@@ -31,6 +44,10 @@ def _from_yaml(property: str, params: Dict) -> "Sampler":
3144 params ["distribution" ],
3245 params .get ("parameters" , {}),
3346 params .get ("sample" , "independent" ),
47+ params .get ("start" , None ),
48+ params .get ("min" , None ),
49+ params .get ("max" , None ),
50+ params .get ("scale" , 1.0 ),
3451 )
3552
3653 return StaticSampler (property , None )
@@ -45,21 +62,33 @@ class StaticSampler(Sampler):
4562 step : Value
4663
4764 def __init__ (
48- self , property : str , value : Value , accumulate : bool = False , start : Value = None
65+ self ,
66+ property : str ,
67+ value : Value ,
68+ accumulate : bool = False ,
69+ start : Value = None ,
70+ min : float | None = None ,
71+ max : float | None = None ,
72+ scale : float = 1.0 ,
4973 ):
50- super ().__init__ (property )
74+ super ().__init__ (property , min , max , scale )
5175 self .accumulate = accumulate
5276 self .value = start if start else 0.0 if isinstance (value , float ) else 0
5377 self .step = value
5478
5579 def next (self ) -> Value :
56- if (
57- self .accumulate
58- and isinstance (self .value , int | float )
59- and isinstance (self .step , int | float )
60- ):
61- self .value += self .step
62- return self .value
80+ if self .first :
81+ self .first = False
82+ else :
83+ if (
84+ self .accumulate
85+ and isinstance (self .value , int | float )
86+ and isinstance (self .step , int | float )
87+ ):
88+ self .value += self .step
89+ return (
90+ self .value if not isinstance (self .value , float ) else self .scale * self .value
91+ )
6392
6493
6594class DistributionSampler (Sampler ):
@@ -76,20 +105,34 @@ def __init__(
76105 parameters : Dict ,
77106 accumulation : Literal ["independent" , "accumulate" ],
78107 start : Optional [float ] = None ,
108+ min : float | None = None ,
109+ max : float | None = None ,
110+ scale = 1.0 ,
79111 ):
80- super ().__init__ (property )
81- self .value = start if start else 0.0
112+ super ().__init__ (property , min , max , scale )
82113 self .accumulate = accumulation == "accumulate"
83114 self .rng = np .random .default_rng ()
84115 self .np_function = getattr (self .rng , np_generator )
85116 self .parameters = parameters
117+ self .value = start if start else self .sample ()
86118
87- def next (self ) -> Value :
88- sample = self .np_function (** self .parameters )
89- if not self .accumulate :
90- return sample
119+ def sample (self ) -> float :
120+ value = self .np_function (** self .parameters )
121+ if self .min and value < self .min :
122+ return self .min
123+ if self .max and value > self .max :
124+ return self .max
125+ return self .scale * value
91126
92- self .value += sample
127+ def next (self ) -> Value :
128+ if self .first :
129+ self .first = False
130+ else :
131+ sample = self .sample ()
132+ if not self .accumulate :
133+ return sample
134+
135+ self .value += sample
93136 return self .value
94137
95138
0 commit comments