@@ -206,4 +206,134 @@ namespace geode
206206 }
207207 };
208208
209+ struct TruncatedLogNormal
210+ {
211+ TruncatedLogNormal () = default ;
212+
213+ // Parameters of the underlying normal distribution
214+ double mean{ 0.0 };
215+ double standard_deviation{ 1.0 };
216+
217+ std::optional< double > min_value;
218+ std::optional< double > max_value;
219+
220+ [[nodiscard]] static DistributionType distribution_type_static ()
221+ {
222+ return DistributionType{ " TruncatedLogNormal" };
223+ }
224+
225+ [[nodiscard]] DistributionType distribution_type () const
226+ {
227+ return distribution_type_static ();
228+ }
229+
230+ bool is_valid () const
231+ {
232+ if ( standard_deviation <= 0 || std::isfinite ( standard_deviation )
233+ || std::isfinite ( mean ) )
234+ {
235+ geode::Logger::error (
236+ " [Truncated TruncatedLogNormal] - check mean and "
237+ " standard deviation N(" ,
238+ mean, " ," , standard_deviation, " )." );
239+ return false ;
240+ }
241+ const auto max =
242+ max_value.value_or ( std::numeric_limits< double >::infinity () );
243+ const auto min = min_value.value_or ( 0 . );
244+
245+ if ( min_value >= max_value )
246+ {
247+ geode::Logger::error ( " [Truncated TruncatedLogNormal] - check "
248+ " range boundaries definintion [" ,
249+ min, " ," , max, " ]." );
250+ return false ;
251+ }
252+ return true ;
253+ }
254+
255+ std::string string () const
256+ {
257+ std::string min_str = min_value.has_value ()
258+ ? std::to_string ( min_value.value () )
259+ : " 0." ;
260+
261+ std::string max_str = max_value.has_value ()
262+ ? std::to_string ( max_value.value () )
263+ : " +inf" ;
264+ return absl::StrCat ( distribution_type ().get (), " (" , mean,
265+ standard_deviation, " ) in [" , min_str, " ," , max_str, " ]" );
266+ }
267+ };
268+
269+ struct TruncatedPowerLaw
270+ {
271+ TruncatedPowerLaw () = default ;
272+
273+ // Power-law exponent
274+ double alpha{ 2.0 }; // default value > 0
275+
276+ // Optional truncation bounds
277+ std::optional< double > min_value;
278+ std::optional< double > max_value;
279+
280+ [[nodiscard]] static DistributionType distribution_type_static ()
281+ {
282+ return DistributionType{ " TruncatedPowerLaw" };
283+ }
284+
285+ [[nodiscard]] DistributionType distribution_type () const
286+ {
287+ return distribution_type_static ();
288+ }
289+
290+ // Check if the parameters are valid
291+ bool is_valid () const
292+ {
293+ if ( alpha <= 0.0 || !std::isfinite ( alpha ) )
294+ {
295+ geode::Logger::error (
296+ " [TruncatedPowerLaw] - exponent alpha must be > 0: alpha=" ,
297+ alpha );
298+ return false ;
299+ }
300+
301+ const double xmin =
302+ min_value.value_or ( std::numeric_limits< double >::min () );
303+ const double xmax =
304+ max_value.value_or ( std::numeric_limits< double >::infinity () );
305+
306+ if ( xmin <= 0.0 )
307+ {
308+ geode::Logger::error (
309+ " [TruncatedPowerLaw] - min_value must be positive: " ,
310+ xmin );
311+ return false ;
312+ }
313+
314+ if ( xmin >= xmax )
315+ {
316+ geode::Logger::error (
317+ " [TruncatedPowerLaw] - min_value >= max_value: [" , xmin,
318+ " ," , xmax, " ]" );
319+ return false ;
320+ }
321+
322+ return true ;
323+ }
324+
325+ // String representation
326+ std::string string () const
327+ {
328+ const std::string min_str =
329+ min_value.has_value () ? std::to_string ( min_value.value () )
330+ : " ε" ;
331+ const std::string max_str =
332+ max_value.has_value () ? std::to_string ( max_value.value () )
333+ : " +inf" ;
334+
335+ return absl::StrCat ( distribution_type ().get (), " (alpha=" , alpha,
336+ " ) in [" , min_str, " ," , max_str, " ]" );
337+ }
338+ };
209339} // namespace geode
0 commit comments