21 boost::get(boost::vertex_bundle, this->
main_graph);
23 boost::get(boost::edge_bundle, this->
main_graph);
26 std::pair<T, T> pair_energy;
30 for (uint32_t ind_ver = 0; ind_ver < this->
nVertex; ind_ver++) {
33 for (uint32_t i_dim = 0; i_dim < this->
dim; i_dim++) {
34 energy += .5 * vertex_attribute_map(i_ver).weight *
35 pow(vertex_attribute_map(i_ver).observation[i_dim] -
36 vertex_attribute_map(i_ver).value[i_dim],
40 pair_energy.first = energy;
43 i_edg_end = boost::edges(this->
main_graph).second;
44 for (i_edg = boost::edges(this->
main_graph).first; i_edg != i_edg_end;
46 if (!edge_attribute_map(*i_edg).realEdge) {
49 energy += .5 * edge_attribute_map(*i_edg).isActive *
50 this->parameter.reg_strenth *
51 edge_attribute_map(*i_edg).weight;
53 pair_energy.second = energy;
70 uint32_t nb_comp =
static_cast<uint32_t
>(this->
components.size());
72 boost::get(boost::vertex_bundle, this->
main_graph);
76 std::vector<bool> binary_label(this->
nVertex);
87 T unary_weight = pow(this->
parameter.weight_decay,
88 -
float(this->parameter.flow_steps));
89 for (uint32_t i_step = 0; i_step < this->
parameter.flow_steps;
91 unary_weight = unary_weight * this->
parameter.weight_decay;
100 boost::boykov_kolmogorov_max_flow(
109 for (uint32_t ind_com = 0; ind_com < nb_comp; ind_com++) {
114 for (uint32_t i_ver = 0;
115 i_ver < this->
components[ind_com].size(); i_ver++) {
116 binary_label[vertex_index_map(
118 (vertex_attribute_map(
121 vertex_attribute_map(this->
sink).color);
134 std::vector<bool>& binary_label,
139 boost::get(boost::vertex_bundle, this->
main_graph);
142 uint32_t nb_comp =
static_cast<uint32_t
>(this->
components.size());
146 uint32_t dim_spat = spatial_part ? this->
dim - 0 : this->
dim;
149 #pragma omp parallel for if (nb_comp >= omp_get_num_threads()) schedule(dynamic)
151 for (uint32_t ind_com = 0; ind_com < nb_comp; ind_com++) {
152 std::vector<std::vector<T>> kernels(2, std::vector<T>(this->
dim));
157 static_cast<uint32_t
>(this->
components[ind_com].size());
158 std::vector<bool> potential_label(comp_size);
159 std::vector<T> energy_array(comp_size);
163 for (uint32_t init_kmeans = 0;
164 init_kmeans < this->
parameter.kmeans_resampling;
168 uint32_t first_kernel = std::rand() % comp_size,
170 for (uint32_t i_dim = 0; i_dim < this->
dim; i_dim++) {
172 vertex_attribute_map(
179 #pragma omp parallel for if (nb_comp < omp_get_num_threads()) \
180 shared(best_energy) schedule(static)
182 for (uint32_t i_ver = 0; i_ver < comp_size; i_ver++) {
183 energy_array[i_ver] = 0;
184 for (uint32_t i_dim = 0; i_dim < dim_spat; i_dim++) {
185 energy_array[i_ver] +=
186 pow(vertex_attribute_map(
188 .observation[i_dim] -
191 vertex_attribute_map(
195 best_energy += energy_array[i_ver];
200 for (uint32_t i_ver = 0; i_ver < comp_size; i_ver++) {
201 current_energy -= energy_array[i_ver];
204 second_kernel = i_ver;
208 for (uint32_t i_dim = 0; i_dim < this->
dim;
211 vertex_attribute_map(
216 for (uint32_t ite_kmeans = 0;
217 ite_kmeans < this->
parameter.kmeans_ite; ite_kmeans++) {
221 #pragma omp parallel for if (nb_comp < omp_get_num_threads()) \
222 shared(potential_label) schedule(static)
224 for (uint32_t i_ver = 0; i_ver < comp_size; i_ver++) {
225 std::vector<T> distance_kernels(2);
226 for (uint32_t i_dim = 0; i_dim < dim_spat; i_dim++) {
227 distance_kernels[0] += pow(
228 vertex_attribute_map(
230 .observation[i_dim] -
233 distance_kernels[1] += pow(
234 vertex_attribute_map(
236 .observation[i_dim] -
240 potential_label[i_ver] =
241 distance_kernels[0] > distance_kernels[1];
245 total_weight[0] = 0.;
246 total_weight[1] = 0.;
247 for (uint32_t i_dim = 0; i_dim < this->
dim; i_dim++) {
248 kernels[0][i_dim] = 0;
249 kernels[1][i_dim] = 0;
252 #pragma omp parallel for if (nb_comp < omp_get_num_threads()) \
253 shared(potential_label) schedule(static)
255 for (uint32_t i_ver = 0; i_ver < comp_size; i_ver++) {
256 if (vertex_attribute_map(
261 if (potential_label[i_ver]) {
263 vertex_attribute_map(
266 for (uint32_t i_dim = 0; i_dim < this->
dim;
269 vertex_attribute_map(
272 .observation[i_dim] *
273 vertex_attribute_map(
280 vertex_attribute_map(
283 for (uint32_t i_dim = 0; i_dim < this->
dim;
286 vertex_attribute_map(
289 .observation[i_dim] *
290 vertex_attribute_map(
298 if ((total_weight[0] == 0) || (total_weight[1] == 0)) {
301 for (uint32_t i_dim = 0; i_dim < this->
dim; i_dim++) {
302 kernels[0][i_dim] = kernels[0][i_dim] / total_weight[0];
303 kernels[1][i_dim] = kernels[1][i_dim] / total_weight[1];
309 #pragma omp parallel for if (nb_comp < omp_get_num_threads()) \
310 shared(potential_label) schedule(static)
312 for (uint32_t i_ver = 0; i_ver < comp_size; i_ver++) {
313 for (uint32_t i_dim = 0; i_dim < dim_spat; i_dim++) {
314 if (potential_label[i_ver]) {
316 pow(vertex_attribute_map(
319 .observation[i_dim] -
322 vertex_attribute_map(
327 pow(vertex_attribute_map(
330 .observation[i_dim] -
333 vertex_attribute_map(
339 if (current_energy < best_energy) {
340 best_energy = current_energy;
341 for (uint32_t i_ver = 0; i_ver < comp_size; i_ver++) {
342 binary_label[vertex_index_map(
344 potential_label[i_ver];
356 const uint32_t& nb_comp,
357 const std::vector<bool>& binary_label) {
360 #pragma omp parallel for if (nb_comp >= omp_get_num_threads()) schedule(dynamic)
362 for (uint32_t ind_com = 0; ind_com < nb_comp; ind_com++) {
375 const uint32_t& ind_com,
376 const std::vector<bool>& binary_label) {
380 boost::get(boost::vertex_bundle, this->
main_graph);
384 total_weight[0] = 0.;
385 total_weight[1] = 0.;
388 for (uint32_t i_ver = 0; i_ver < this->
components[ind_com].size();
390 if (vertex_attribute_map(this->
components[ind_com][i_ver]).weight ==
394 if (binary_label[vertex_index_map(
397 vertex_attribute_map(this->
components[ind_com][i_ver])
399 for (uint32_t i_dim = 0; i_dim < this->
dim; i_dim++) {
401 vertex_attribute_map(
403 .observation[i_dim] *
404 vertex_attribute_map(
410 vertex_attribute_map(this->
components[ind_com][i_ver])
412 for (uint32_t i_dim = 0; i_dim < this->
dim; i_dim++) {
414 vertex_attribute_map(
416 .observation[i_dim] *
417 vertex_attribute_map(
423 if ((total_weight[0] == 0) || (total_weight[1] == 0)) {
426 for (uint32_t i_dim = 0; i_dim < this->
dim; i_dim++) {
428 vertex_attribute_map(this->
components[ind_com][0])
431 vertex_attribute_map(this->
components[ind_com][0])
435 for (uint32_t i_dim = 0; i_dim < this->
dim; i_dim++) {
436 center[0][i_dim] = center[0][i_dim] / total_weight[0];
437 center[1][i_dim] = center[1][i_dim] / total_weight[1];
449 boost::get(boost::vertex_bundle, this->
main_graph);
451 boost::get(boost::edge_bundle, this->
main_graph);
455 uint32_t nb_comp =
static_cast<uint32_t
>(this->
components.size());
457 #pragma omp parallel for if (nb_comp >= omp_get_num_threads()) schedule(dynamic)
459 for (uint32_t ind_com = 0; ind_com < nb_comp; ind_com++) {
467 for (uint32_t i_ver = 0; i_ver < this->
components[ind_com].size();
476 edge_attribute_map(desc_v2source)
482 if (vertex_attribute_map(desc_v).weight ==
484 edge_attribute_map(desc_source2v).capacity = 0;
485 edge_attribute_map(desc_v2sink).capacity = 0;
488 for (uint32_t i_dim = 0; i_dim < this->
dim; i_dim++) {
489 cost_B += 0.5 * vertex_attribute_map(desc_v).weight *
490 (pow(centers.
centroids[ind_com][0][i_dim], 2) -
491 2 * (centers.
centroids[ind_com][0][i_dim] *
492 vertex_attribute_map(desc_v)
493 .observation[i_dim]));
494 cost_notB += 0.5 * vertex_attribute_map(desc_v).weight *
495 (pow(centers.
centroids[ind_com][1][i_dim], 2) -
496 2 * (centers.
centroids[ind_com][1][i_dim] *
497 vertex_attribute_map(desc_v)
498 .observation[i_dim]));
500 if (cost_B > cost_notB) {
501 edge_attribute_map(desc_source2v).capacity =
502 (cost_B - cost_notB);
503 edge_attribute_map(desc_v2sink).capacity = 0.;
505 edge_attribute_map(desc_source2v).capacity = 0.;
506 edge_attribute_map(desc_v2sink).capacity =
507 (cost_notB - cost_B);
514 for (boost::tie(i_edg, i_edg_end) = boost::edges(this->
main_graph);
515 i_edg != i_edg_end; ++i_edg) {
516 if (!edge_attribute_map(*i_edg).realEdge) {
519 if (!edge_attribute_map(*i_edg).isActive) {
520 edge_attribute_map(*i_edg).capacity =
521 edge_attribute_map(*i_edg).weight *
522 this->parameter.reg_strenth / unary_weight;
524 edge_attribute_map(*i_edg).capacity = 0;
534 const uint32_t& ind_com)
override {
536 boost::get(boost::vertex_bundle, this->
main_graph);
538 std::vector<T> compValue(this->
dim);
539 std::fill((compValue.begin()), (compValue.end()), 0);
541 #pragma omp parallel for if (this->parameter.parallel) schedule(static)
543 for (uint32_t ind_ver = 0; ind_ver < this->
components[ind_com].size();
546 vertex_attribute_map(this->
components[ind_com][ind_ver])
548 for (uint32_t i_dim = 0; i_dim < this->
dim; i_dim++) {
550 vertex_attribute_map(this->
components[ind_com][ind_ver])
551 .observation[i_dim] *
552 vertex_attribute_map(this->
components[ind_com][ind_ver])
555 vertex_attribute_map(this->
components[ind_com][ind_ver])
556 .in_component = ind_com;
558 for (uint32_t i_dim = 0; i_dim < this->
dim; i_dim++) {
559 compValue[i_dim] = compValue[i_dim] / total_weight;
561 for (uint32_t ind_ver = 0; ind_ver < this->
components[ind_com].size();
563 for (uint32_t i_dim = 0; i_dim < this->
dim; i_dim++) {
564 vertex_attribute_map(this->
components[ind_com][ind_ver])
565 .value[i_dim] = compValue[i_dim];
568 return std::pair<std::vector<T>, T>(compValue, total_weight);
580 std::vector<T> merge_value(this->
dim);
583 for (uint32_t i_dim = 0; i_dim < this->
dim; i_dim++) {
585 (reduced_vertex_attribute_map(comp1).weight *
586 reduced_vertex_attribute_map(comp1).value[i_dim] +
587 reduced_vertex_attribute_map(comp2).weight *
588 reduced_vertex_attribute_map(comp2).value[i_dim]) /
589 (reduced_vertex_attribute_map(comp1).weight +
590 reduced_vertex_attribute_map(comp2).weight);
592 (pow(merge_value[i_dim], 2) *
593 (reduced_vertex_attribute_map(comp1).weight +
594 reduced_vertex_attribute_map(comp2).weight) -
595 pow(reduced_vertex_attribute_map(comp1).value[i_dim], 2) *
596 reduced_vertex_attribute_map(comp1).weight -
597 pow(reduced_vertex_attribute_map(comp2).value[i_dim], 2) *
598 reduced_vertex_attribute_map(comp2).weight);
600 return std::pair<std::vector<T>, T>(merge_value, gain);
std::vector< std::vector< std::vector< T > > > centroids
boost::vec_adj_list_vertex_property_map< Graph< T >, Graph< T > *, VertexAttribute< T >, VertexAttribute< T > &, boost::vertex_bundle_t > VertexAttributeMap
typename boost::graph_traits< Graph< T > >::edge_iterator EdgeIterator
boost::graph_traits< boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS > >::edge_descriptor EdgeDescriptor
typename boost::graph_traits< CP::Graph< T > >::vertex_descriptor VertexDescriptor
typename boost::property_map< Graph< T >, boost::vertex_index_t >::type VertexIndexMap
boost::adj_list_edge_property_map< boost::directed_tag, EdgeAttribute< T >, EdgeAttribute< T > &, uint64_t, CP::EdgeAttribute< T >, boost::edge_bundle_t > EdgeAttributeMap
Matrix< T > random_sample(Matrix< T > &srcMatrix, size_t size, bool remove=false)
void init_labels(std::vector< bool > &binary_label, bool spatial_part)
void compute_centers(VectorOfCentroids< T > ¢ers, const uint32_t &nb_comp, const std::vector< bool > &binary_label)
void compute_center(std::vector< std::vector< T >> ¢er, const uint32_t &ind_com, const std::vector< bool > &binary_label)
std::pair< T, T > compute_energy() override
void set_capacities(const VectorOfCentroids< T > ¢ers, T unary_weight)
std::pair< std::vector< T >, T > compute_merge_gain(const VertexDescriptor< T > &comp1, const VertexDescriptor< T > &comp2) override
std::pair< std::vector< T >, T > compute_value(const uint32_t &ind_com) override
CPparameter< T > parameter
std::vector< std::vector< VertexDescriptor< T > > > components
VertexDescriptor< T > sink
VertexDescriptor< T > source
size_t activate_edges(bool allows_saturation=true)
std::vector< bool > saturated_components