Skip to content

Commit 178ebb7

Browse files
feat(SampleAzimuth): modify the segment sampler.
1 parent 807defe commit 178ebb7

8 files changed

Lines changed: 98 additions & 9 deletions

File tree

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ namespace geode
8484

8585
static Distribution create_distribution(
8686
const DistributionDescription& desc );
87+
static Distribution create_angle_distribution_in_rad(
88+
const DistributionDescription& desc );
8789

8890
static double sample( RandomEngine& engine, const Distribution& dist );
8991
};

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ namespace geode
4141
{
4242
if( !is_valid_object( obj ) )
4343
{
44+
Logger::warn( "[ObjectSetSampler] - invalid object proposed." );
4445
return LOG_PROB_INVALID;
4546
}
4647
return log_pdf_;

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ namespace geode
6363
const auto& extremities = obj.vertices();
6464
const auto current =
6565
static_cast< local_index_t >( engine.sample_bernoulli( 0.5 ) );
66+
const auto other = 1 - current;
6667

6768
geode::Sphere< 2 > ball{ extremities[current],
6869
ratio * obj.length() };
@@ -71,7 +72,8 @@ namespace geode
7172
constexpr index_t max_try{ 100 };
7273
for( const auto try_id : geode::Range{ max_try } )
7374
{
74-
if( box_.contains( new_point ) )
75+
if( box_.contains( new_point )
76+
|| box_.contains( extremities[other] ) )
7577
{
7678
OwnerSegment2D new_segment{ obj };
7779
new_segment.set_point( current, new_point );
@@ -91,7 +93,7 @@ namespace geode
9193
const auto& extremities = obj.vertices();
9294

9395
return box_.contains( extremities[0] )
94-
&& box_.contains( extremities[1] );
96+
|| box_.contains( extremities[1] );
9597
}
9698

9799
private:

include/geode/stochastic/sampling/distributions.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,34 @@ namespace geode
176176
}
177177
};
178178

179+
struct opengeode_stochastic_stochastic_api VonMises
180+
{
181+
VonMises() = default;
182+
183+
// 2D von Mises parameters
184+
double mean{ 0.0 }; // mean direction in radians
185+
double concentration{ 1.0 }; // kappa (concentration parameter)
186+
187+
[[nodiscard]] static DistributionType distribution_type_static()
188+
{
189+
return DistributionType{ "VonMises" };
190+
}
191+
192+
[[nodiscard]] DistributionType distribution_type() const
193+
{
194+
return distribution_type_static();
195+
}
196+
197+
[[nodiscard]] bool is_valid() const
198+
{
199+
return concentration >= 0.0 && std::isfinite( mean );
200+
}
201+
202+
std::string string() const
203+
{
204+
return absl::StrCat( distribution_type().get(), "(mean=", mean,
205+
", kappa=", concentration, ")" );
206+
}
207+
};
208+
179209
} // namespace geode

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ namespace geode
9797
auto length_distribution =
9898
DoubleSampler::create_distribution( set_desc.length );
9999
auto azimuth_distribution =
100-
DoubleSampler::create_distribution( set_desc.azimuth );
100+
DoubleSampler::create_angle_distribution_in_rad(
101+
set_desc.azimuth );
101102
this->set_samplers_.push_back(
102103
std::make_unique< UniformSegmentSetSampler >(
103104
box_, length_distribution, azimuth_distribution ) );

src/geode/stochastic/sampling/direct/double_sampler.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@
2323

2424
#include <geode/stochastic/sampling/direct/double_sampler.hpp>
2525

26+
#include <geode/geometry/angle.hpp>
27+
2628
#include <geode/stochastic/common.hpp>
2729
#include <geode/stochastic/sampling/random_engine.hpp>
30+
2831
namespace
2932
{
3033
struct DistributionParams
@@ -129,6 +132,40 @@ namespace geode
129132
return it->second( desc );
130133
}
131134

135+
DoubleSampler::Distribution DoubleSampler::create_angle_distribution_in_rad(
136+
const DistributionDescription& desc_deg )
137+
{
138+
DistributionDescription desc_rad = desc_deg;
139+
if( desc_rad.mean )
140+
{
141+
auto mean_angle = Angle::create_from_degrees( *( desc_rad.mean ) );
142+
desc_rad.mean = mean_angle.normalized_between_0_and_2pi().radians();
143+
}
144+
if( desc_rad.standard_deviation )
145+
{
146+
auto std_angle =
147+
Angle::create_from_degrees( *( desc_rad.standard_deviation ) );
148+
desc_rad.standard_deviation =
149+
std_angle.normalized_between_0_and_2pi().radians();
150+
}
151+
if( desc_rad.min_value )
152+
{
153+
auto min_angle =
154+
Angle::create_from_degrees( *( desc_rad.min_value ) );
155+
desc_rad.min_value =
156+
min_angle.normalized_between_0_and_2pi().radians();
157+
}
158+
if( desc_rad.max_value )
159+
{
160+
auto max_angle =
161+
Angle::create_from_degrees( *( desc_rad.max_value ) );
162+
desc_rad.max_value =
163+
max_angle.normalized_between_0_and_2pi().radians();
164+
}
165+
// Call the general create_distribution
166+
return create_distribution( desc_rad );
167+
}
168+
132169
double DoubleSampler::sample(
133170
RandomEngine& engine, const Distribution& dist )
134171
{

src/geode/stochastic/sampling/direct/segment_uniform_sampler.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,34 @@
2626
#include <geode/stochastic/common.hpp>
2727
#include <geode/stochastic/sampling/random_engine.hpp>
2828

29+
#include <geode/geometry/angle.hpp>
2930
#include <geode/geometry/basic_objects/segment.hpp>
31+
#include <geode/geometry/vector.hpp>
3032

33+
namespace
34+
{
35+
geode::Vector2D direction_from_azimuth_angle( const geode::Angle& azimuth )
36+
{
37+
return geode::Vector2D( { azimuth.sin(), azimuth.cos() } );
38+
}
39+
} // namespace
3140
namespace geode
3241
{
3342

3443
OwnerSegment2D SegmentUniformSampler::sample( RandomEngine& engine,
3544
const PointUniformSampler::Object< 2 >& object,
3645
const DoubleSampler::Distribution& length,
37-
const DoubleSampler::Distribution& azimuth )
46+
const DoubleSampler::Distribution& azimuth_rad )
3847
{
39-
geode_unused( length );
40-
geode_unused( azimuth );
4148
auto point1 = PointUniformSampler::sample( engine, object );
42-
auto point2 = PointUniformSampler::sample( engine, object );
49+
50+
auto segment_length = DoubleSampler::sample( engine, length );
51+
auto segment_azimuth = Angle::create_from_radians(
52+
DoubleSampler::sample( engine, azimuth_rad ) );
53+
54+
auto point2 =
55+
point1
56+
+ direction_from_azimuth_angle( segment_azimuth ) * segment_length;
4357

4458
return OwnerSegment2D{ point1, point2 };
4559
}

tests/stochastic/sampling/direct/test-segment-uniform-sampler.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,16 @@ void test_sample_segment(
4343
{
4444
geode::UniformClosed< double > length;
4545
geode::UniformClosed< double > az;
46+
auto box_enlarged = box;
47+
box_enlarged.extends( 1.01 );
4648

4749
for( const auto i : geode::Range{ NUMBER_OF_SAMPLES } )
4850
{
4951
auto value =
5052
geode::SegmentUniformSampler::sample( engine, box, length, az );
51-
OPENGEODE_EXCEPTION( box.contains( value.vertices()[0] ),
53+
OPENGEODE_EXCEPTION( box_enlarged.contains( value.vertices()[0] ),
5254
"[SegmentUniformSampler] - segment out of box." );
53-
OPENGEODE_EXCEPTION( box.contains( value.vertices()[1] ),
55+
OPENGEODE_EXCEPTION( box_enlarged.contains( value.vertices()[1] ),
5456
"[SegmentUniformSampler] - segment out of box." );
5557
}
5658
}

0 commit comments

Comments
 (0)