WeightedLowess
A C++ library for LOWESS with various weighting schemes
Loading...
Searching...
No Matches
SortBy.hpp
Go to the documentation of this file.
1#ifndef WEIGHTEDLOWESS_SORTBY_HPP
2#define WEIGHTEDLOWESS_SORTBY_HPP
3
4#include <algorithm>
5#include <numeric>
6#include <vector>
7#include <cstdint>
8#include <type_traits>
9#include <initializer_list>
10
16namespace WeightedLowess {
17
27class SortBy {
28private:
29 std::vector<size_t> my_permutation;
30 bool my_sorted = true;
31
32public:
38 template<typename Sortable_>
39 SortBy(size_t num_points, const Sortable_* x) {
40 set(num_points, x);
41 }
42
47 SortBy() = default;
48
54 template<typename Sortable_>
55 void set(size_t num_points, const Sortable_* x) {
56 if (num_points) {
57 my_sorted = std::is_sorted(x, x + num_points);
58 if (!my_sorted) {
59 my_permutation.resize(num_points);
60 std::iota(my_permutation.begin(), my_permutation.end(), static_cast<size_t>(0));
61 std::sort(my_permutation.begin(), my_permutation.end(), [&](size_t left, size_t right) -> bool { return x[left] < x[right]; });
62 }
63 }
64 }
65
66private:
67 template<typename AllData_, typename Used_>
68 void permute_raw(AllData_& data, Used_* work) const {
69 if (my_sorted) {
70 return;
71 }
72
73 size_t num_points = my_permutation.size();
74 std::fill_n(work, num_points, 0);
75
76 // Reordering values in place.
77 for (size_t i = 0; i < num_points; ++i) {
78 if (work[i]) {
79 continue;
80 }
81 work[i] = 1;
82
83 size_t current = i, replacement = my_permutation[i];
84 while (replacement != i) {
85 if constexpr(std::is_pointer<AllData_>::value) {
86 std::swap(data[current], data[replacement]);
87 } else {
88 for (auto d : data) {
89 std::swap(d[current], d[replacement]);
90 }
91 }
92 current = replacement;
93 work[replacement] = 1;
94 replacement = my_permutation[replacement];
95 }
96 }
97 }
98
99public:
108 template<typename Data_, typename Used_>
109 void permute(Data_* data, Used_* work) const {
110 permute_raw(data, work);
111 }
112
121 template<typename Data_, typename Used_>
122 void permute(std::initializer_list<Data_> data, Used_* work) const {
123 permute_raw(data, work);
124 }
125
134 template<typename DataPointers_, typename Used_>
135 void permute(DataPointers_ data, Used_* work) const {
136 permute_raw(data, work);
137 }
138
147 template<typename Data_, typename Used_>
148 void permute(Data_* data, std::vector<Used_>& work) const {
149 size_t num_points = my_permutation.size();
150 work.resize(num_points);
151 permute(data, work.data());
152 }
153
162 template<typename Data_, typename Used_>
163 void permute(std::initializer_list<Data_> data, std::vector<Used_>& work) const {
164 size_t num_points = my_permutation.size();
165 work.resize(num_points);
166 permute(data, work.data());
167 }
168
177 template<typename DataPointers_, typename Used_>
178 void permute(DataPointers_ data, std::vector<Used_>& work) const {
179 size_t num_points = my_permutation.size();
180 work.resize(num_points);
181 permute(data, work.data());
182 }
183
184private:
185 template<typename AllData_, typename Used_>
186 void unpermute_raw(AllData_& data, Used_* work) const {
187 if (my_sorted) {
188 return;
189 }
190
191 size_t num_points = my_permutation.size();
192 std::fill_n(work, num_points, 0);
193
194 for (size_t i = 0; i < num_points; ++i) {
195 if (work[i]) {
196 continue;
197 }
198 work[i] = 1;
199
200 size_t replacement = my_permutation[i];
201 while (replacement != i) {
202 if constexpr(std::is_pointer<AllData_>::value) {
203 std::swap(data[i], data[replacement]);
204 } else {
205 for (auto d : data) {
206 std::swap(d[i], d[replacement]);
207 }
208 }
209 work[replacement] = 1;
210 replacement = my_permutation[replacement];
211 }
212 }
213 }
214
215public:
223 template<typename Data_, typename Used_>
224 void unpermute(Data_* data, Used_* work) const {
225 unpermute_raw(data, work);
226 }
227
235 template<typename Data_, typename Used_>
236 void unpermute(std::initializer_list<Data_*> data, Used_* work) const {
237 unpermute_raw(data, work);
238 }
239
247 template<typename DataPointers_, typename Used_>
248 void unpermute(DataPointers_ data, Used_* work) const {
249 unpermute_raw(data, work);
250 }
251
259 template<typename Data_, typename Used_>
260 void unpermute(Data_* data, std::vector<Used_>& work) const {
261 size_t num_points = my_permutation.size();
262 work.resize(num_points);
263 unpermute(data, work.data());
264 }
265
273 template<typename Data_, typename Used_>
274 void unpermute(std::initializer_list<Data_*> data, std::vector<Used_>& work) const {
275 size_t num_points = my_permutation.size();
276 work.resize(num_points);
277 unpermute(data, work.data());
278 }
279
287 template<typename DataPointers_, typename Used_>
288 void unpermute(DataPointers_ data, std::vector<Used_>& work) const {
289 size_t num_points = my_permutation.size();
290 work.resize(num_points);
291 unpermute(data, work.data());
292 }
293};
294
295}
296
297#endif
Utility class for sorting on a covariate.
Definition SortBy.hpp:27
void unpermute(Data_ *data, std::vector< Used_ > &work) const
Definition SortBy.hpp:260
void unpermute(Data_ *data, Used_ *work) const
Definition SortBy.hpp:224
void unpermute(std::initializer_list< Data_ * > data, std::vector< Used_ > &work) const
Definition SortBy.hpp:274
void unpermute(DataPointers_ data, Used_ *work) const
Definition SortBy.hpp:248
void permute(std::initializer_list< Data_ > data, std::vector< Used_ > &work) const
Definition SortBy.hpp:163
void permute(std::initializer_list< Data_ > data, Used_ *work) const
Definition SortBy.hpp:122
void unpermute(std::initializer_list< Data_ * > data, Used_ *work) const
Definition SortBy.hpp:236
void permute(Data_ *data, std::vector< Used_ > &work) const
Definition SortBy.hpp:148
void permute(DataPointers_ data, std::vector< Used_ > &work) const
Definition SortBy.hpp:178
SortBy(size_t num_points, const Sortable_ *x)
Definition SortBy.hpp:39
void permute(DataPointers_ data, Used_ *work) const
Definition SortBy.hpp:135
void permute(Data_ *data, Used_ *work) const
Definition SortBy.hpp:109
void unpermute(DataPointers_ data, std::vector< Used_ > &work) const
Definition SortBy.hpp:288
void set(size_t num_points, const Sortable_ *x)
Definition SortBy.hpp:55
Namespace for LOWESS functions.
Definition compute.hpp:14