1 #ifndef GENESIS_UTILS_MATH_RANKING_H_
2 #define GENESIS_UTILS_MATH_RANKING_H_
58 template <
class RandomAccessIterator>
59 std::vector<size_t>
ranking_standard( RandomAccessIterator first, RandomAccessIterator last )
62 auto const size =
static_cast<size_t>( std::distance( first, last ));
63 auto result = std::vector<size_t>( size, 1 );
67 auto ordered_value = [&](
size_t i ){
68 return *( first + order[i] );
70 auto ordered_result = [&](
size_t i ) ->
size_t& {
71 return result[ order[i] ];
75 for(
size_t i = 1; i < size; ++i ) {
78 if( ordered_value( i ) == ordered_value( i - 1 ) ) {
79 ordered_result( i ) = ordered_result( i - 1 );
81 ordered_result( i ) = i + 1;
109 template <
class RandomAccessIterator>
110 std::vector<size_t>
ranking_modified( RandomAccessIterator first, RandomAccessIterator last )
113 auto const size =
static_cast<size_t>( std::distance( first, last ));
114 auto result = std::vector<size_t>( size, 1 );
118 auto ordered_value = [&](
size_t i ){
119 return *( first + order[i] );
121 auto ordered_result = [&](
size_t i ) ->
size_t& {
122 return result[ order[i] ];
126 for(
size_t i = 0; i < size; ) {
130 while( i+j < size && ordered_value(i+j) == ordered_value(i) ) {
135 for(
size_t k = 0; k < j; ++k ) {
136 ordered_result( i + k ) = i + j;
166 template <
class RandomAccessIterator>
167 std::vector<size_t>
ranking_dense( RandomAccessIterator first, RandomAccessIterator last )
170 auto const size =
static_cast<size_t>( std::distance( first, last ));
171 auto result = std::vector<size_t>( size, 1 );
175 auto ordered_value = [&](
size_t i ){
176 return *( first + order[i] );
178 auto ordered_result = [&](
size_t i ) ->
size_t& {
179 return result[ order[i] ];
183 for(
size_t i = 1; i < size; ++i ) {
186 if( ordered_value( i ) == ordered_value( i - 1 ) ) {
187 ordered_result( i ) = ordered_result( i - 1 );
189 ordered_result( i ) = ordered_result( i - 1 ) + 1;
216 template <
class RandomAccessIterator>
217 std::vector<size_t>
ranking_ordinal( RandomAccessIterator first, RandomAccessIterator last )
220 auto const size =
static_cast<size_t>( std::distance( first, last ));
221 auto result = std::vector<size_t>( size, 1 );
225 auto ordered_result = [&](
size_t i ) ->
size_t& {
226 return result[ order[i] ];
230 for(
size_t i = 0; i < size; ++i ) {
231 ordered_result( i ) = i + 1;
259 template <
class RandomAccessIterator>
263 auto const size =
static_cast<size_t>( std::distance( first, last ));
264 auto result = std::vector<double>( size, 1 );
268 auto ordered_value = [&](
size_t i ){
269 return *( first + order[i] );
271 auto ordered_result = [&](
size_t i ) ->
double& {
272 return result[ order[i] ];
276 auto sum_avg = [](
size_t l,
size_t r )
289 auto const upper = r * ( r + 1 ) / 2;
290 auto const lower = ( l - 1 ) * l / 2;
291 return static_cast<double>( upper - lower ) /
static_cast<double>( r - l + 1 );
295 for(
size_t i = 0; i < size; ) {
299 while( i+j < size && ordered_value(i+j) == ordered_value(i) ) {
304 auto entry = sum_avg( i + 1, i + j );
305 for(
size_t k = 0; k < j; ++k ) {
306 ordered_result( i + k ) = entry;
327 #endif // include guard