Skip to content

Commit 9b52d61

Browse files
feat(Sampler): add genericity
1 parent 8e86a7b commit 9b52d61

8 files changed

Lines changed: 123 additions & 100 deletions

File tree

include/geode/stochastic/sampling/direct/object_set_sampler/object_set_sampler.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,13 @@
2424
#pragma once
2525

2626
#include <geode/stochastic/sampling/random_engine.hpp>
27+
2728
#include <geode/stochastic/spatial/object_sets.hpp>
29+
#include <geode/stochastic/spatial/spatial_domain.hpp>
2830

2931
namespace geode
3032
{
33+
3134
template < typename Type >
3235
class ObjectSetSampler
3336
{
@@ -55,4 +58,12 @@ namespace geode
5558
protected:
5659
double log_pdf_{ LOG_PROB_INVALID };
5760
};
61+
62+
template < typename ObjectType >
63+
struct ObjectSamplerConfig;
64+
65+
template < typename ObjectType >
66+
std::unique_ptr< ObjectSetSampler< ObjectType > > build_objectset_sampler(
67+
const SpatialDomain< ObjectType::dim >& domain,
68+
const ObjectSamplerConfig< ObjectType >& config );
5869
} // namespace geode

include/geode/stochastic/sampling/direct/object_set_sampler/point_set_sampler.hpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ namespace geode
3636
class UniformPointSetSampler : public ObjectSetSampler< Point< dimension > >
3737
{
3838
public:
39-
UniformPointSetSampler( const SpatialDomain< dimension >& domain )
39+
UniformPointSetSampler( const SpatialDomain< dimension >& domain,
40+
const ObjectSamplerConfig< Point< dimension > >& config )
4041
: ObjectSetSampler< Point< dimension > >{}, domain_( domain )
4142
{
4243
auto volume = domain_.extended_n_volume();
@@ -45,7 +46,7 @@ namespace geode
4546
"[UniformPointSetSampler] Undefined Extended Bounding "
4647
"Box (volume ==0)." );
4748
this->log_pdf_ = -std::log( volume );
48-
step_move_ = define_step_for_move();
49+
step_move_ = define_step_for_move( config.move_ratio );
4950
OpenGeodeStochasticStochasticException::check_exception(
5051
step_move_ > 0., nullptr, OpenGeodeException::TYPE::data,
5152
"[UniformPointSetSampler] Undefined step length for move "
@@ -83,9 +84,8 @@ namespace geode
8384
}
8485

8586
private:
86-
double define_step_for_move()
87+
double define_step_for_move( double ratio )
8788
{
88-
double ratio = 0.1;
8989
return ratio * domain_.smallest_length();
9090
}
9191

@@ -99,4 +99,20 @@ namespace geode
9999
double step_move_{ 0. };
100100
};
101101

102+
template < index_t dimension >
103+
struct ObjectSamplerConfig< Point< dimension > >
104+
{
105+
// use to define the step for change move (move_ratio*domain volume)
106+
double move_ratio = 0.1;
107+
};
108+
109+
template < index_t dimension >
110+
std::unique_ptr< ObjectSetSampler< Point2D > > build_objectset_sampler(
111+
const SpatialDomain< 2 >& domain,
112+
const ObjectSamplerConfig< Point< dimension > >& config )
113+
{
114+
return std::make_unique< UniformPointSetSampler< 2 > >(
115+
domain, config );
116+
}
117+
102118
} // namespace geode

include/geode/stochastic/sampling/direct/object_set_sampler/segment_set_sampler.hpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ namespace geode
3737
{
3838
public:
3939
UniformSegmentSetSampler( const SpatialDomain< 2 >& domain,
40-
const DoubleSampler::Distribution& length,
41-
const DoubleSampler::Distribution& azimuth )
40+
const ObjectSamplerConfig< Segment2D >& config )
4241
: ObjectSetSampler< OwnerSegment2D >{},
4342
domain_{ domain },
44-
length_{ length },
45-
azimuth_{ azimuth }
43+
length_{ DoubleSampler::build_distribution( config.length ) },
44+
azimuth_{ DoubleSampler::build_distribution( config.azimuth ) },
45+
move_ratio_{ config.move_ratio }
4646
{
4747
auto volume = domain_.extended_n_volume();
4848
OpenGeodeStochasticStochasticException::check_exception(
@@ -62,14 +62,13 @@ namespace geode
6262
OwnerSegment2D change(
6363
const OwnerSegment2D& obj, RandomEngine& engine ) const override
6464
{
65-
double ratio = 0.1;
6665
const auto& extremities = obj.vertices();
6766
const auto current =
6867
static_cast< local_index_t >( engine.sample_bernoulli( 0.5 ) );
6968
const auto other = 1 - current;
7069

7170
geode::Sphere< 2 > ball{ extremities[current],
72-
ratio * obj.length() };
71+
move_ratio_ * obj.length() };
7372

7473
auto new_point = PointUniformSampler::sample< 2 >( engine, ball );
7574
constexpr index_t max_try{ 100 };
@@ -102,6 +101,24 @@ namespace geode
102101
const SpatialDomain< 2 >& domain_;
103102
DoubleSampler::Distribution length_;
104103
DoubleSampler::Distribution azimuth_;
104+
double move_ratio_{ 0.1 };
105105
};
106106

107+
template <>
108+
struct ObjectSamplerConfig< OwnerSegment2D >
109+
{
110+
double move_ratio = 0.1;
111+
112+
DoubleSampler::DistributionDescription length;
113+
DoubleSampler::DistributionDescription azimuth;
114+
};
115+
116+
template <>
117+
std::unique_ptr< ObjectSetSampler< OwnerSegment2D > >
118+
build_objectset_sampler( const SpatialDomain< 2 >& domain,
119+
const ObjectSamplerConfig< OwnerSegment2D >& config )
120+
{
121+
return std::make_unique< UniformSegmentSetSampler >( domain, config );
122+
}
123+
107124
} // namespace geode

include/geode/stochastic/sampling/mcmc/helpers/simulation_context.hpp

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,22 @@ namespace geode
6969
std::unique_ptr< geode::MetropolisHastings< ObjectType > > mh_sampler;
7070
};
7171

72+
template < typename ObjectType >
73+
struct ObjectSetDefinition
74+
{
75+
std::string name;
76+
std::vector< ObjectType > fixed_objects;
77+
78+
ObjectSamplerConfig< ObjectType > sampler;
79+
ObjectSetDynamicsConfig dynamics;
80+
};
81+
7282
template < typename ObjectType >
7383
struct SimulationContextConfig
7484
{
7585
SpatialDomainConfig< ObjectType::dim > domain;
7686

77-
std::vector< ObjectSetConfig > sets;
78-
std::vector< ObjectSetDynamicsConfig > proposals;
87+
std::vector< ObjectSetDefinition< ObjectType > > sets;
7988

8089
geode::ModelConfig model;
8190
};
@@ -95,28 +104,17 @@ namespace geode
95104
// -------------------------
96105
// Sets
97106
// -------------------------
98-
99-
// auto proposal_kernel =
100-
// std::make_unique< geode::ProposalKernel< geode::Point2D >
101-
// >();
102-
// for( const auto& set_desc : set_descriptors_ )
103-
// {
104-
// const auto set_id = context.object_sets->add_set(
105-
// set_desc.name ); context.set_samplers.push_back(
106-
// std::make_unique< geode::UniformPointSetSampler< 2 >
107-
// >(
108-
// *context.domain ) );
109-
// geode::add_birth_death_change_moves(
110-
// context.set_samplers.back(),
111-
// *proposal_kernel, set_id, set_desc.birth_ratio,
112-
// set_desc.death_ratio, set_desc.change_ratio );
113-
// }
114-
// return proposal_kernel;
115-
116-
for( const auto& set_cfg : config.sets )
107+
auto proposal_kernel =
108+
std::make_unique< geode::ProposalKernel< ObjectType > >();
109+
for( const auto& set_def : config.sets )
117110
{
118-
const auto set_id = context.object_sets->add_set( set_cfg.name );
119-
geode_unused( set_id );
111+
auto set_id = context.object_sets->add_set( set_def.name );
112+
auto sampler =
113+
build_objectset_sampler( *context.domain, set_def.sampler );
114+
geode::add_birth_death_change_moves( *sampler, *proposal_kernel,
115+
set_id, set_def.dynamics.birth_ratio,
116+
set_def.dynamics.death_ratio, set_def.dynamics.change_ratio );
117+
context.set_samplers.emplace_back( std::move( sampler ) );
120118
}
121119

122120
// -------------------------
@@ -125,24 +123,6 @@ namespace geode
125123
context.model = geode::build_model< ObjectType >(
126124
config.model, *context.object_sets, *context.domain );
127125

128-
// -------------------------
129-
// Proposal
130-
// -------------------------
131-
auto proposal_kernel =
132-
std::make_unique< geode::ProposalKernel< ObjectType > >();
133-
for( const auto& set_proposal : config.proposals )
134-
{
135-
const auto set_id =
136-
context.object_sets->get_set_uuid( set_proposal.name );
137-
context.set_samplers.push_back(
138-
std::make_unique< geode::UniformPointSetSampler< 2 > >(
139-
*context.domain ) );
140-
141-
geode::add_birth_death_change_moves( context.set_samplers.back(),
142-
*proposal_kernel, set_id, set_proposal.birth_ratio,
143-
set_proposal.death_ratio, set_proposal.change_ratio );
144-
}
145-
146126
// -------------------------
147127
// MH sampler
148128
// -------------------------

include/geode/stochastic/sampling/mcmc/proposal/classical_proposals.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ namespace geode
3232
{
3333
template < typename ObjectType >
3434
void add_birth_death_change_moves(
35-
std::unique_ptr< geode::ObjectSetSampler< ObjectType > >& sampler,
35+
const geode::ObjectSetSampler< ObjectType >& sampler,
3636
geode::ProposalKernel< ObjectType >& kernel,
3737
const uuid& set_id,
3838
double birth_ratio,
@@ -48,13 +48,13 @@ namespace geode
4848
const auto p_birth = birth_ratio / total_ratio;
4949
kernel.add_move(
5050
set_id, std::make_unique< geode::BirthDeathMove< ObjectType > >(
51-
*sampler, total_ratio, p_birth ) );
51+
sampler, total_ratio, p_birth ) );
5252

5353
if( change_ratio > 0. )
5454
{
5555
kernel.add_move(
5656
set_id, std::make_unique< geode::ChangeMove< ObjectType > >(
57-
*sampler, change_ratio ) );
57+
sampler, change_ratio ) );
5858
}
5959
}
6060

include/geode/stochastic/spatial/object_sets.hpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,6 @@ namespace geode
4646

4747
namespace geode
4848
{
49-
struct ObjectSetConfig
50-
{
51-
std::string name;
52-
53-
double birth_ratio = 1.0;
54-
double death_ratio = 1.0;
55-
double change_ratio = 1.0;
56-
};
57-
5849
template < typename Type >
5950
class ObjectSets
6051
{

tests/stochastic/sampling/mcmc/proposal/test-proposal-kernel.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ namespace
5858
box.add_point( max_point );
5959
geode::SpatialDomain domain( box, 0. );
6060

61-
geode::UniformPointSetSampler< 2 > sampler( domain );
61+
geode::ObjectSamplerConfig< geode::Point2D > sampler_config;
62+
geode::UniformPointSetSampler< 2 > sampler( domain, sampler_config );
6263

6364
// Create classical birth-death-change kernel
6465
auto kernel = geode::create_birth_death_change_kernel< geode::Point2D >(

0 commit comments

Comments
 (0)