brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.8 KiB · 4e52116 Raw
141 lines · plain
1//  (C) Copyright Matt Borland 20222//  Use, modification and distribution are subject to the3//  Boost Software License, Version 1.0. (See accompanying file4//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)5 6#ifndef BOOST_MATH_STATISTICS_DETAIL_RANK_HPP7#define BOOST_MATH_STATISTICS_DETAIL_RANK_HPP8 9#include <cstdint>10#include <vector>11#include <numeric>12#include <utility>13#include <iterator>14#include <algorithm>15#include <boost/math/tools/config.hpp>16 17#ifdef BOOST_MATH_EXEC_COMPATIBLE18#include <execution>19#endif20 21namespace boost { namespace math { namespace statistics { namespace detail {22 23struct pair_equal24{25    template <typename T1, typename T2>26    bool operator()(const std::pair<T1, T2>& a, const std::pair<T1, T2>& b) const27    {28        return a.first == b.first;29    }30};31 32}}}} // Namespaces33 34#ifndef BOOST_MATH_EXEC_COMPATIBLE35 36namespace boost { namespace math { namespace statistics { namespace detail {37 38template <typename ForwardIterator, typename T = typename std::iterator_traits<ForwardIterator>::value_type>39auto rank(ForwardIterator first, ForwardIterator last) -> std::vector<std::size_t>40{41    std::size_t elements = std::distance(first, last);42 43    std::vector<std::pair<T, std::size_t>> rank_vector(elements);44    std::size_t i = 0;45    while (first != last)46    {47        rank_vector[i] = std::make_pair(*first, i);48        ++i;49        ++first;50    }51 52    std::sort(rank_vector.begin(), rank_vector.end());53 54    // Remove duplicates55    rank_vector.erase(std::unique(rank_vector.begin(), rank_vector.end(), pair_equal()), rank_vector.end());56    elements = rank_vector.size();57 58    std::pair<T, std::size_t> rank;59    std::vector<std::size_t> result(elements);60    for (i = 0; i < elements; ++i)61    {62        if (rank_vector[i].first != rank.first)63        {64            rank = std::make_pair(rank_vector[i].first, i);65        }66        result[rank_vector[i].second] = rank.second;67    }68 69    return result;70}71 72template <typename Container>73inline auto rank(const Container& c) -> std::vector<std::size_t>74{75    return rank(std::begin(c), std::end(c));76}77 78}}}} // Namespaces79 80#else81 82namespace boost::math::statistics::detail {83 84template <typename ExecutionPolicy, typename ForwardIterator, typename T = typename std::iterator_traits<ForwardIterator>::value_type>85auto rank(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last)86{87    std::size_t elements = std::distance(first, last);88 89    std::vector<std::pair<T, std::size_t>> rank_vector(elements);90    std::size_t i = 0;91    while (first != last)92    {93        rank_vector[i] = std::make_pair(*first, i);94        ++i;95        ++first;96    }97 98    std::sort(exec, rank_vector.begin(), rank_vector.end());99 100    // Remove duplicates101    rank_vector.erase(std::unique(exec, rank_vector.begin(), rank_vector.end(), pair_equal()), rank_vector.end());102    elements = rank_vector.size();103 104    std::pair<T, std::size_t> rank;105    std::vector<std::size_t> result(elements);106    for (i = 0; i < elements; ++i)107    {108        if (rank_vector[i].first != rank.first)109        {110            rank = std::make_pair(rank_vector[i].first, i);111        }112        result[rank_vector[i].second] = rank.second;113    }114 115    return result;116}117 118template <typename ExecutionPolicy, typename Container>119inline auto rank(ExecutionPolicy&& exec, const Container& c)120{121    return rank(exec, std::cbegin(c), std::cend(c));122}123 124template <typename ForwardIterator, typename T = typename std::iterator_traits<ForwardIterator>::value_type>125inline auto rank(ForwardIterator first, ForwardIterator last)126{127    return rank(std::execution::seq, first, last);128}129 130template <typename Container>131inline auto rank(const Container& c)132{133    return rank(std::execution::seq, std::cbegin(c), std::cend(c));134}135 136} // Namespaces137 138#endif // BOOST_MATH_EXEC_COMPATIBLE139 140#endif // BOOST_MATH_STATISTICS_DETAIL_RANK_HPP141