2424
2525#include < geode/basic/range.hpp>
2626#include < geode/stochastic/spatial/object_set.hpp>
27+ #include < geode/stochastic/spatial/pairwise_interactions.hpp>
2728
2829#include < geode/stochastic/sampling/mcmc/models/components/energy_term.hpp>
2930
3031namespace geode
3132{
3233 // rename PairwiseInteractionTerm
33- template < typename Type, typename InteractionFunc >
34+ template < typename Type >
3435 class PairwiseTerm : public EnergyTerm < Type >
3536 {
3637 public:
3738 explicit PairwiseTerm ( std::string_view name,
3839 double gamma,
39- InteractionFunc interaction_func )
40+ std::unique_ptr< PairwiseInteraction< Type > >&& interaction )
4041 : EnergyTerm< Type >( name, gamma ),
41- interaction_func_ ( std::move( interaction_func ) )
42+ interaction_ ( std::move( interaction ) )
4243 {
4344 }
4445
4546 explicit PairwiseTerm ( std::string_view name,
4647 double gamma,
47- InteractionFunc interaction_func ,
48+ std::unique_ptr< PairwiseInteraction< Type > >&& interaction ,
4849 const uuid& subset_id )
4950 : EnergyTerm< Type >( name, gamma, subset_id ),
50- interaction_func_ ( std::move( interaction_func ) )
51+ interaction_ ( std::move( interaction ) )
5152 {
5253 }
5354
@@ -58,20 +59,22 @@ namespace geode
5859 }
5960
6061 double delta_log_add ( const ObjectSet< Type >& state,
61- const Type& new_object,
62- const uuid& new_object_subset_id ) const final
62+ const ObjectRef< Type >& new_object ) const final
6363 {
64- if ( !this ->is_targeted_subset ( new_object_subset_id ) )
64+ if ( !this ->is_targeted_subset ( new_object. subset ) )
6565 {
6666 return 0.0 ;
6767 }
6868 double delta = 0.0 ;
69- const auto neighbors = state.neighbors ( new_object, 1.1 );
69+ const auto neighbors = state.neighbors ( new_object.object ,
70+ interaction_->neighborhood_searching_distance () );
7071 for ( const auto & neigh_id : neighbors )
7172 {
72- const auto & neigh_obj = state.get_object ( neigh_id );
73- delta += static_cast < double >( interaction_func_ ( neigh_obj,
74- neigh_id.subset , new_object, new_object_subset_id ) );
73+ geode::ObjectRef< Type > neigh_object{
74+ state.get_object ( neigh_id ), neigh_id.subset
75+ };
76+
77+ delta += interaction_->evaluate ( new_object, neigh_object );
7578 }
7679 return this ->contribution ( delta );
7780 }
@@ -84,13 +87,16 @@ namespace geode
8487 return 0.0 ;
8588 }
8689 double delta = 0.0 ;
87- const auto & to_remove = state.get_object ( object_id );
88- const auto neighbors = state.neighbors ( object_id, 1.1 );
90+ ObjectRef< Type > object_to_remove{ state.get_object ( object_id ),
91+ object_id.subset };
92+ const auto neighbors = state.neighbors (
93+ object_id, interaction_->neighborhood_searching_distance () );
8994 for ( auto neigh_id : neighbors )
9095 {
91- const auto & neigh_obj = state.get_object ( neigh_id );
92- delta += static_cast < double >( interaction_func_ (
93- neigh_obj, neigh_id.subset , to_remove, object_id.subset ) );
96+ ObjectRef< Type > neigh_object{ state.get_object ( neigh_id ),
97+ neigh_id.subset };
98+ delta +=
99+ interaction_->evaluate ( object_to_remove, neigh_object );
94100 }
95101 return this ->contribution ( -delta );
96102 }
@@ -108,24 +114,32 @@ namespace geode
108114 double delta = 0.0 ;
109115
110116 // Remove old object's interactions
111- const auto & old_obj = state.get_object ( old_object_id );
112- const auto old_neighbors = state.neighbors ( old_object_id, 1.1 );
117+ ObjectRef< Type > object_to_remove{
118+ state.get_object ( old_object_id ), old_object_id.subset
119+ };
120+ const auto old_neighbors = state.neighbors ( old_object_id,
121+ interaction_->neighborhood_searching_distance () );
113122 for ( auto neigh_id : old_neighbors )
114123 {
115- const auto & neigh_obj = state.get_object ( neigh_id );
116- delta -= static_cast < double >( interaction_func_ ( neigh_obj,
117- neigh_id.subset , old_obj, old_object_id.subset ) );
124+ ObjectRef< Type > neigh_object{ state.get_object ( neigh_id ),
125+ neigh_id.subset };
126+ delta -=
127+ interaction_->evaluate ( object_to_remove, neigh_object );
118128 }
119129
120130 // Add new object's interactions
121- const auto new_neighbors = state.neighbors ( new_object, 1.1 );
131+ ObjectRef< Type > object_to_add{ new_object, new_object_subset_id };
132+ const auto new_neighbors = state.neighbors (
133+ new_object, interaction_->neighborhood_searching_distance () );
122134 for ( auto neigh_id : new_neighbors )
123135 {
124136 if ( old_object_id == neigh_id )
137+ {
125138 continue ; // avoid double-counting
126- const auto & neigh_obj = state.get_object ( neigh_id );
127- delta += static_cast < double >( interaction_func_ ( neigh_obj,
128- neigh_id.subset , new_object, new_object_subset_id ) );
139+ }
140+ ObjectRef< Type > neigh_object{ state.get_object ( neigh_id ),
141+ neigh_id.subset };
142+ delta += interaction_->evaluate ( object_to_add, neigh_object );
129143 }
130144
131145 return this ->contribution ( delta );
@@ -145,15 +159,18 @@ namespace geode
145159 {
146160 continue ;
147161 }
148- sum += static_cast < double >( interaction_func_ ( cur_obj,
149- obj_id.subset , state.get_object ( neigh_obj_id ),
150- neigh_obj_id.subset ) );
162+ ObjectRef< Type > object{ cur_obj, obj_id.subset };
163+ ObjectRef< Type > neigh_object{
164+ state.get_object ( neigh_obj_id ), neigh_obj_id.subset
165+ };
166+
167+ sum += interaction_->evaluate ( object, neigh_object );
151168 }
152169 } );
153170 return sum / 2 .;
154171 }
155172
156173 private:
157- InteractionFunc interaction_func_ ;
174+ std::unique_ptr< PairwiseInteraction< Type > > interaction_ ;
158175 };
159176} // namespace geode
0 commit comments