2525
2626#include < geode/stochastic/common.hpp>
2727#include < geode/stochastic/sampling/random_engine.hpp>
28+ namespace
29+ {
30+ struct DistributionParams
31+ {
32+ double min;
33+ double max;
34+ double mean;
35+ double std;
36+ };
2837
38+ DistributionParams complete_distribution_params (
39+ const geode::DoubleSampler::DistributionDescription& d )
40+ {
41+ DistributionParams p{};
42+
43+ if ( d.min_value && d.max_value )
44+ {
45+ p.min = *d.min_value ;
46+ p.max = *d.max_value ;
47+ p.mean = ( p.min + p.max ) / 2.0 ;
48+ p.std = ( p.max - p.min ) / std::sqrt ( 12.0 );
49+ return p;
50+ }
51+
52+ if ( d.mean && d.standard_deviation )
53+ {
54+ p.mean = *d.mean ;
55+ p.std = *d.standard_deviation ;
56+ p.min = p.mean - std::sqrt ( 3.0 ) * p.std ;
57+ p.max = p.mean + std::sqrt ( 3.0 ) * p.std ;
58+ return p;
59+ }
60+
61+ throw geode::OpenGeodeException (
62+ " [DistributionDescripption] Incomplete distribution description: "
63+ " need at least (min,max) or (mean,std)." );
64+ return p;
65+ }
66+ } // namespace
2967namespace geode
3068{
3169 struct DistributionTypeHasher
@@ -38,47 +76,47 @@ namespace geode
3876 };
3977
4078 using DistributionFactory = std::function< DoubleSampler::Distribution(
41- const DistributionDescription& ) >;
79+ const DoubleSampler:: DistributionDescription& ) >;
4280
4381 static absl::flat_hash_map< DistributionType, // key type
4482 DistributionFactory, // value type
4583 DistributionTypeHasher // custom hasher
4684 >
4785 distribution_registry = {
4886 { UniformClosed< double >::distribution_type_static (),
49- []( const DistributionDescription& d ) {
87+ []( const DoubleSampler::DistributionDescription& d ) {
88+ auto p = complete_distribution_params ( d );
5089 UniformClosed< double > dist;
51- dist.min_value = d. min_value ;
52- dist.max_value = d. max_value ;
90+ dist.min_value = p. min ;
91+ dist.max_value = p. max ;
5392 return dist;
5493 } },
5594 { UniformClosedOpen< double >::distribution_type_static (),
56- []( const DistributionDescription& d ) {
95+ []( const DoubleSampler::DistributionDescription& d ) {
96+ auto p = complete_distribution_params ( d );
5797 UniformClosedOpen< double > dist;
58- dist.min_value = d. min_value ;
59- dist.max_value = d. max_value ;
98+ dist.min_value = p. min ;
99+ dist.max_value = p. max ;
60100 return dist;
61101 } },
62102 { Gaussian::distribution_type_static (),
63- []( const DistributionDescription& d ) {
103+ []( const DoubleSampler::DistributionDescription& d ) {
104+ auto p = complete_distribution_params ( d );
64105 Gaussian dist;
65- dist.mean =
66- d.mean .value_or ( ( d.max_value - d.min_value ) / 2.0 );
67- dist.standard_deviation = d.standard_deviation .value_or (
68- ( d.max_value - d.min_value ) / 6.0 );
106+ dist.mean = p.mean ;
107+ dist.standard_deviation = p.std ;
69108 return dist;
70109 } },
71110 { TruncatedGaussian::distribution_type_static (),
72- []( const DistributionDescription& d ) {
111+ []( const DoubleSampler::DistributionDescription& d ) {
112+ auto p = complete_distribution_params ( d );
73113 TruncatedGaussian dist;
74- dist.mean =
75- d.mean .value_or ( ( d.max_value - d.min_value ) / 2.0 );
76- dist.standard_deviation = d.standard_deviation .value_or (
77- ( d.max_value - d.min_value ) / 6.0 );
78- dist.min_value = d.min_value ;
79- dist.max_value = d.max_value ;
114+ dist.mean = p.mean ;
115+ dist.standard_deviation = p.std ;
116+ dist.min_value = p.min ;
117+ dist.max_value = p.max ;
80118 return dist;
81- } }
119+ } },
82120 };
83121
84122 DoubleSampler::Distribution DoubleSampler::create_distribution (
0 commit comments