1 #ifndef GENESIS_UTILS_MATH_RANKING_H_
2 #define GENESIS_UTILS_MATH_RANKING_H_
60 template <
class RandomAccessIterator>
61 std::vector<size_t>
ranking_standard( RandomAccessIterator first, RandomAccessIterator last )
64 auto const size =
static_cast<size_t>( std::distance( first, last ));
65 auto result = std::vector<size_t>( size, 1 );
69 auto ordered_value = [&](
size_t i ){
70 return *( first + order[i] );
72 auto ordered_result = [&](
size_t i ) ->
size_t& {
73 return result[ order[i] ];
77 for(
size_t i = 1; i < size; ++i ) {
80 if( ordered_value( i ) == ordered_value( i - 1 ) ) {
81 ordered_result( i ) = ordered_result( i - 1 );
83 ordered_result( i ) = i + 1;
111 template <
class RandomAccessIterator>
112 std::vector<size_t>
ranking_modified( RandomAccessIterator first, RandomAccessIterator last )
115 auto const size =
static_cast<size_t>( std::distance( first, last ));
116 auto result = std::vector<size_t>( size, 1 );
120 auto ordered_value = [&](
size_t i ){
121 return *( first + order[i] );
123 auto ordered_result = [&](
size_t i ) ->
size_t& {
124 return result[ order[i] ];
128 for(
size_t i = 0; i < size; ) {
132 while( i+j < size && ordered_value(i+j) == ordered_value(i) ) {
137 for(
size_t k = 0; k < j; ++k ) {
138 ordered_result( i + k ) = i + j;
168 template <
class RandomAccessIterator>
169 std::vector<size_t>
ranking_dense( RandomAccessIterator first, RandomAccessIterator last )
172 auto const size =
static_cast<size_t>( std::distance( first, last ));
173 auto result = std::vector<size_t>( size, 1 );
177 auto ordered_value = [&](
size_t i ){
178 return *( first + order[i] );
180 auto ordered_result = [&](
size_t i ) ->
size_t& {
181 return result[ order[i] ];
185 for(
size_t i = 1; i < size; ++i ) {
188 if( ordered_value( i ) == ordered_value( i - 1 ) ) {
189 ordered_result( i ) = ordered_result( i - 1 );
191 ordered_result( i ) = ordered_result( i - 1 ) + 1;
218 template <
class RandomAccessIterator>
219 std::vector<size_t>
ranking_ordinal( RandomAccessIterator first, RandomAccessIterator last )
222 auto const size =
static_cast<size_t>( std::distance( first, last ));
223 auto result = std::vector<size_t>( size, 1 );
227 auto ordered_result = [&](
size_t i ) ->
size_t& {
228 return result[ order[i] ];
232 for(
size_t i = 0; i < size; ++i ) {
233 ordered_result( i ) = i + 1;
261 template <
class RandomAccessIterator>
265 auto const size =
static_cast<size_t>( std::distance( first, last ));
266 auto result = std::vector<double>( size, 1 );
270 auto ordered_value = [&](
size_t i ){
271 return *( first + order[i] );
273 auto ordered_result = [&](
size_t i ) ->
double& {
274 return result[ order[i] ];
278 auto sum_avg = [](
size_t l,
size_t r )
291 auto const upper = r * ( r + 1 ) / 2;
292 auto const lower = ( l - 1 ) * l / 2;
293 return static_cast<double>( upper - lower ) /
static_cast<double>( r - l + 1 );
297 for(
size_t i = 0; i < size; ) {
301 while( i+j < size && ordered_value(i+j) == ordered_value(i) ) {
306 auto entry = sum_avg( i + 1, i + j );
307 for(
size_t k = 0; k < j; ++k ) {
308 ordered_result( i + k ) = entry;
338 typename ForwardIterator,
339 typename T =
typename ForwardIterator::value_type,
340 typename Comp = std::less<T>
343 ForwardIterator first, ForwardIterator last,
size_t n, Comp comp = std::less<T>{}
356 std::priority_queue<T, std::vector<T>, decltype(comp)> queue( comp );
358 while( first != last ) {
360 if( queue.size() < n ) {
362 }
else if( comp( v, queue.top() )) {
369 assert(( val_cnt < n && queue.size() == val_cnt ) || queue.size() == n );
374 std::vector<T> result;
375 result.resize( queue.size() );
376 size_t res_idx = result.size();
377 while( ! queue.empty() ) {
378 assert( res_idx > 0 );
380 result[ res_idx ] = queue.top();
383 assert( res_idx == 0 );
384 assert(( val_cnt < n && result.size() == val_cnt ) || result.size() == n );
391 #endif // include guard