h5geo 0.4.0
C++17 and python API to work with geo-data (seismic, wells, maps, other in process) based on HDF5. Aimed at geoscientists and developers.
Loading...
Searching...
No Matches
h5sort.h
1#ifndef H5SORT_H
2#define H5SORT_H
3
4#include <Eigen/Dense>
5
6namespace h5geo
7{
8
9namespace detail
10{
11
12// std::function to perfomance decrease but only non-capturing fuunctions may be converted to function pointer, see:
13// https://stackoverflow.com/questions/73260538/passing-c-lambda-as-argument-to-non-templated-function
14
19template <typename D>
20void _sort(
21 D M,
22 Eigen::VectorX<ptrdiff_t> &idx,
23 std::function<bool(ptrdiff_t, ptrdiff_t)> cmp_fun);
24
25} // detail
26
27
31template <typename D>
32Eigen::VectorX<ptrdiff_t> sort(const Eigen::DenseBase<D> &v){
33
34 Eigen::VectorX<ptrdiff_t> idx;
35 auto cmp_fun = [&v](
36 const ptrdiff_t& i1,
37 const ptrdiff_t& i2)->bool {return v(i1,0) < v(i2,0);};
38 detail::_sort(v.derived(), idx, cmp_fun);
39
40 return idx;
41}
42
47template <typename DRaw, typename DSort>
48Eigen::VectorX<ptrdiff_t> sort(
49 const Eigen::DenseBase<DRaw> &v,
50 Eigen::DenseBase<DSort> const &v_sorted_)
51{
52 Eigen::VectorX<ptrdiff_t> idx = sort(v);
53
54 Eigen::DenseBase<DSort>& v_sorted =
55 const_cast< Eigen::DenseBase<DSort>& >(v_sorted_);
56 v_sorted = v(idx, Eigen::all);
57 return idx;
58}
59
67template <typename D>
68Eigen::VectorX<ptrdiff_t> sort_rows(const Eigen::DenseBase<D> &M){
69
70 // initialize original index locations
71 Eigen::VectorX<ptrdiff_t> idx;
72
73 auto cmp_fun = [&M](
74 const ptrdiff_t& row1,
75 const ptrdiff_t& row2)->bool
76 {
77 ptrdiff_t N = M.cols()-1;
78 for (ptrdiff_t col = 0; col < N; col++){
79 if (M(row1, col) < M(row2, col))
80 return true;
81
82 if (M(row1, col) > M(row2, col))
83 return false;
84 }
85
86 // notice the operator is '<=' as it is the last column check
87 // i.e. when all other columns are equal at these rows
88 if (M(row1, Eigen::last) <= M(row2, Eigen::last))
89 return true;
90
91 return false;
92 };
93
94 detail::_sort(M.derived(), idx, cmp_fun);
95
96 return idx;
97}
98
104template <typename DRaw, typename DSort>
105Eigen::VectorX<ptrdiff_t> sort_rows(
106 const Eigen::DenseBase<DRaw> &M,
107 Eigen::DenseBase<DSort> &M_sorted_)
108{
109 Eigen::VectorX<ptrdiff_t> idx = sort_rows(M);
110 Eigen::DenseBase<DSort>& M_sorted =
111 const_cast< Eigen::DenseBase<DSort>& >(M_sorted_);
112 M_sorted = M(idx, Eigen::all);
113 return idx;
114}
115
125template <typename DRaw, typename TUval>
126Eigen::VectorX<ptrdiff_t> sort_unique(
127 const Eigen::DenseBase<DRaw> &v,
128 Eigen::VectorX<TUval> &uvals,
129 Eigen::MatrixX2<ptrdiff_t> &uvals_from_size)
130{
131 if (v.size() < 1)
132 return Eigen::VectorX<ptrdiff_t>();
133
134 Eigen::VectorX<ptrdiff_t> idx = sort(v);
135
136 uvals.resize(idx.size());
137 uvals_from_size.resize(idx.size(), Eigen::NoChange);
138
139 // initialize first iteration
140 uvals(0) = v(idx(0));
141 uvals_from_size(0, 0) = 0;
142 uvals_from_size(0, 1) = 1;
143
144 ptrdiff_t ii = 0;
145 for (ptrdiff_t i = 1; i < idx.size(); i++){
146 if (v(idx(i - 1)) == v(idx(i))){
147 uvals_from_size(ii, 1)++;
148 } else {
149 ii++;
150 uvals(ii) = v(idx(i));
151 uvals_from_size(ii, 0) = i;
152 uvals_from_size(ii, 1) = 1;
153 }
154 }
155 uvals.conservativeResize(ii + 1);
156 uvals_from_size.conservativeResize(ii + 1, Eigen::NoChange);
157 return idx;
158}
159
166template <typename DRaw, typename TUval, typename DSort>
167Eigen::VectorX<ptrdiff_t> sort_unique(
168 const Eigen::DenseBase<DRaw> &v,
169 Eigen::VectorX<TUval> &uvals,
170 Eigen::MatrixX2<ptrdiff_t> &uvals_from_size,
171 Eigen::DenseBase<DSort> const &v_sorted_)
172{
173 Eigen::VectorX<ptrdiff_t> idx = sort_unique(v, uvals, uvals_from_size);
174 Eigen::DenseBase<DSort>& v_sorted =
175 const_cast< Eigen::DenseBase<DSort>& >(v_sorted_);
176 v_sorted = v(idx, Eigen::all);
177 return idx;
178}
179
191template <typename DRaw, typename TUval>
192Eigen::VectorX<ptrdiff_t> sort_rows_unique(
193 const Eigen::DenseBase<DRaw> &M,
194 Eigen::MatrixX<TUval> &urows,
195 Eigen::MatrixX2<ptrdiff_t> &urows_from_size)
196{
197 if (M.rows() < 1)
198 return Eigen::VectorX<ptrdiff_t>();
199
200 Eigen::VectorX<ptrdiff_t> idx = sort_rows(M);
201
202 urows.resize(idx.size(), M.cols());
203 urows_from_size.resize(idx.size(), Eigen::NoChange);
204
205 // initialize first iteration
206 urows.row(0) = M.row(idx(0));
207 urows_from_size(0, 0) = 0;
208 urows_from_size(0, 1) = 1;
209
210 ptrdiff_t ii = 0;
211 for (ptrdiff_t i = 1; i < idx.size(); i++){
212 if (M.row(idx(i - 1)) == M.row(idx(i))){
213 urows_from_size(ii, 1)++;
214 } else {
215 ii++;
216 urows.row(ii) = M.row(idx(i));
217 urows_from_size(ii, 0) = i;
218 urows_from_size(ii, 1) = 1;
219 }
220 }
221 urows.conservativeResize(ii + 1, Eigen::NoChange);
222 urows_from_size.conservativeResize(ii + 1, Eigen::NoChange);
223 return idx;
224}
225
232template <typename DRaw, typename TUval, typename DSort>
233Eigen::VectorX<ptrdiff_t> sort_rows_unique(
234 const Eigen::DenseBase<DRaw> &M,
235 Eigen::MatrixX<TUval> &urows,
236 Eigen::MatrixX2<ptrdiff_t> &urows_from_size,
237 const Eigen::DenseBase<DSort> &M_sorted_)
238{
239 Eigen::VectorX<ptrdiff_t> idx = sort_rows_unique(M, urows, urows_from_size);
240 Eigen::DenseBase<DSort>& M_sorted =
241 const_cast< Eigen::DenseBase<DSort>& >(M_sorted_);
242 M_sorted = M(idx, Eigen::all);
243 return idx;
244}
245
246}
247
248
249#endif // H5SORT_H
Basic namespace.
Definition h5base.h:29
Eigen::VectorX< ptrdiff_t > sort_rows(const Eigen::DenseBase< D > &M)
sort_rows sorts the rows of a matrix in ascending order based on the elements in the first column....
Definition h5sort.h:68
Eigen::VectorX< ptrdiff_t > sort_rows_unique(const Eigen::DenseBase< DRaw > &M, Eigen::MatrixX< TUval > &urows, Eigen::MatrixX2< ptrdiff_t > &urows_from_size)
sort_rows_unique find unique rows, sort them, identify unique rows start and end row-indexes and retu...
Definition h5sort.h:192
Eigen::VectorX< ptrdiff_t > sort(const Eigen::DenseBase< D > &v)
sort return indexes such that v_sorted = v(ind).
Definition h5sort.h:32
Eigen::VectorX< ptrdiff_t > sort_unique(const Eigen::DenseBase< DRaw > &v, Eigen::VectorX< TUval > &uvals, Eigen::MatrixX2< ptrdiff_t > &uvals_from_size)
sort_unique find unique elements, sort them, identify unique values start and end indexes and return ...
Definition h5sort.h:126