forked from BRAINSia/BRAINSTools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvnl_index_sort.h
172 lines (149 loc) · 4.12 KB
/
vnl_index_sort.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#ifndef vnl_index_sort_h_
#define vnl_index_sort_h_
#ifdef VCL_NEEDS_PRAGMA_INTERFACE
#pragma interface
#endif
//:
// \file
// \author Michael R. Bowers
//
#include <vnl/vnl_vector.h>
#include <vcl_algorithm.h>
#include <vcl_utility.h>
#include <vcl_vector.h>
template<class TValue, class TIndex>
class vnl_index_sort
{
public:
//: typedefs for vector sorting
typedef vnl_vector<TValue> SortVectorType;
typedef vnl_vector<TIndex> SortVectorIndexType;
//: typedefs for matrix sorting
typedef vnl_matrix<TValue> SortMatrixType;
typedef vnl_matrix<TIndex> SortMatrixIndexType;
//: matrix sort along rows or columns?
enum DirectionType {ByRow, ByColumn} Direction;
//: just sort indices
void vector_sort(
const SortVectorType& values,
SortVectorIndexType& indices)
{
sortIndices(values, indices);
}
//: sort indices and values
void vector_sort(
const SortVectorType& values,
SortVectorType& sorted_values,
SortVectorIndexType& indices)
{
vector_sort(values, indices);
// gets values from sorted indices
reindexValues(values, indices, sorted_values);
}
//: sort indices, return sorted values in place
void vector_sort_in_place(
SortVectorType& values,
SortVectorIndexType& indices)
{
vector_sort(values, indices);
SortVectorType tmpValues(values);
// gets values and indices from sorted indices
reindexValues(tmpValues, indices, values);
}
//: matrix sort
// specify along rows or columns
void matrix_sort(
DirectionType direction,
const SortMatrixType& values,
SortMatrixType& sorted_values,
SortMatrixIndexType& indices)
{
sorted_values.set_size(values.rows(), values.cols());
indices.set_size(values.rows(), values.cols());
SortVectorType valVect;
SortVectorType sortedValVect;
SortVectorIndexType indVect;
for (unsigned int vIx = 0;
vIx < (direction == ByRow ? values.rows() : values.cols()); vIx++)
{
getVector(values, direction, vIx, valVect);
vector_sort(valVect, sortedValVect, indVect);
putVector(sortedValVect, direction, vIx, sorted_values);
putVector(indVect, direction, vIx, indices);
}
}
private:
//: Implementation class - Do Not Use.
//: Author - Ian Scott
template <class T, class I>
struct sort_index_compare_functor
{
const T *data;
bool operator () (const I &a, const I &b)
{
return data[a] < data[b];
}
};
//: sort the indices of a vector
//: Author - Ian Scott
void sortIndices(const SortVectorType& v, SortVectorIndexType& s)
{
sort_index_compare_functor<TValue, TIndex> c;
c.data = v.data_block();
s.set_size(v.size());
for (TIndex ix = 0; ix < (TIndex) v.size(); ix++) s[ix] = ix;
vcl_sort(s.begin(), s.end(), c);
}
//: reorder values from sorted indices
void reindexValues(
const SortVectorType& values,
const SortVectorIndexType& indices,
SortVectorType& sorted_values)
{
sorted_values.set_size(values.size());
for (TIndex ix = 0; ix < (TIndex) values.size(); ix++)
sorted_values[ix] = values[indices[ix]];
}
//: get specified vector from matrix depending on direction
template<class T>
void getVector(
const vnl_matrix<T>& fromMat,
DirectionType direction,
int whichVect,
vnl_vector<T>& toVect)
{
switch (direction)
{
case ByRow:
toVect = fromMat.get_row(whichVect);
break;
case ByColumn:
toVect = fromMat.get_column(whichVect);
break;
default:
toVect.clear();
break;
}
}
//: put specified vector to matrix depending on direction
template<class T>
void putVector(
const vnl_vector<T>& fromVect,
DirectionType direction,
int whichVect,
vnl_matrix<T>& toMat)
{
switch (direction)
{
case ByRow:
toMat.set_row(whichVect, fromVect);
break;
case ByColumn:
toMat.set_column(whichVect, fromVect);
break;
default:
break;
}
}
};
#endif