Lagrange
bucket_sort.h
1/*
2 * Copyright 2022 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <lagrange/internal/invert_mapping.h>
15#include <lagrange/utils/DisjointSets.h>
16
17#include <numeric>
18
19namespace lagrange::internal {
20
26template <typename Index>
28{
31
33 std::vector<Index> sorted_elements;
34
37 std::vector<Index> representative_offsets;
38};
39
55template <typename Index>
57 DisjointSets<Index>& unified_indices,
58 span<Index> element_representative)
59{
60 la_debug_assert(unified_indices.size() == element_representative.size());
62
63 auto& num_representatives = result.num_representatives;
64 auto& sorted_elements = result.sorted_elements;
65 auto& representative_offsets = result.representative_offsets;
66
67 Index num_elements = static_cast<Index>(element_representative.size());
68
69 // Calculate representative element for each bucket
70 num_representatives = 0;
71 std::fill(element_representative.begin(), element_representative.end(), invalid<Index>());
72 for (Index e = 0; e < num_elements; ++e) {
73 Index r = unified_indices.find(e);
74 if (element_representative[r] == invalid<Index>()) {
75 element_representative[r] = num_representatives++;
76 }
77 element_representative[e] = element_representative[r];
78 }
79
80 auto mapping = invert_mapping(
81 {element_representative.data(), element_representative.size()},
82 num_representatives);
83 sorted_elements = std::move(mapping.data);
84 representative_offsets = std::move(mapping.offsets);
85
86 return result;
87}
88
94template <typename Index>
96{
99
102 std::vector<Index> representative_offsets;
103};
104
118template <typename Index, typename Function>
120bucket_sort(std::vector<Index>& elements, Index num_buckets, Function get_representative)
121{
123
124 auto& num_representatives = result.num_representatives;
125 auto& representative_offsets = result.representative_offsets;
126 num_representatives = num_buckets;
127 auto mapping = invert_mapping<Index>(
128 static_cast<Index>(elements.size()),
129 get_representative,
130 num_representatives);
131 elements = std::move(mapping.data);
132 representative_offsets = std::move(mapping.offsets);
133 return result;
134}
135
136} // namespace lagrange::internal
Disjoint sets computation.
Definition: DisjointSets.h:32
size_t size() const
Get the number of entries in total.
Definition: DisjointSets.h:56
IndexType find(IndexType i)
Find the root index corresponding to index i.
Definition: DisjointSets.cpp:35
#define la_debug_assert(...)
Debug assertion check.
Definition: assert.h:189
::nonstd::span< T, Extent > span
A bounds-safe view for sequences of objects.
Definition: span.h:27
nullptr_t, size_t, ptrdiff_t basic_ostream bad_weak_ptr extent, remove_extent, is_array,...
Definition: attribute_string_utils.h:21
BucketSortResult< Index > bucket_sort(DisjointSets< Index > &unified_indices, span< Index > element_representative)
Performs a bucket sort over a range of elements.
Definition: bucket_sort.h:56
InverseMapping< Index > invert_mapping(Index num_source_elements, Function old_to_new, Index num_target_elements=invalid< Index >())
Compute the target-to-source (i.e.
Definition: invert_mapping.h:61
Bucket sort offset infos.
Definition: bucket_sort.h:96
Index num_representatives
Number of representatives in the input disjoint set.
Definition: bucket_sort.h:98
std::vector< Index > representative_offsets
Vector of size num_representatives + 1 storing the start/end of each disjoint set in the sorted eleme...
Definition: bucket_sort.h:102
Bucket sort result object.
Definition: bucket_sort.h:28
std::vector< Index > sorted_elements
Sorted element in the input range.
Definition: bucket_sort.h:33
Index num_representatives
Number of representatives in the input disjoint set.
Definition: bucket_sort.h:30
std::vector< Index > representative_offsets
Vector of size num_representatives + 1 storing the start/end of each disjoint set in the sorted eleme...
Definition: bucket_sort.h:37