12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- // Copyright Nick Thompson 2019.
- // Use, modification and distribution are subject to the
- // Boost Software License, Version 1.0. (See accompanying file
- // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_MATH_DISTRIBUTIONS_EMPIRICAL_CUMULATIVE_DISTRIBUTION_FUNCTION_HPP
- #define BOOST_MATH_DISTRIBUTIONS_EMPIRICAL_CUMULATIVE_DISTRIBUTION_FUNCTION_HPP
- #include <algorithm>
- #include <iterator>
- #include <stdexcept>
- #include <type_traits>
- #include <utility>
- #include <boost/math/tools/is_standalone.hpp>
- #ifndef BOOST_MATH_STANDALONE
- #include <boost/config.hpp>
- #ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR
- #error "The header <boost/math/norms.hpp> can only be used in C++17 and later."
- #endif
- #endif
- namespace boost { namespace math{
- template<class RandomAccessContainer>
- class empirical_cumulative_distribution_function {
- using Real = typename RandomAccessContainer::value_type;
- public:
- empirical_cumulative_distribution_function(RandomAccessContainer && v, bool sorted = false)
- {
- if (v.size() == 0) {
- throw std::domain_error("At least one sample is required to compute an empirical CDF.");
- }
- m_v = std::move(v);
- if (!sorted) {
- std::sort(m_v.begin(), m_v.end());
- }
- }
- auto operator()(Real x) const {
- if constexpr (std::is_integral_v<Real>)
- {
- if (x < m_v[0]) {
- return static_cast<double>(0);
- }
- if (x >= m_v[m_v.size()-1]) {
- return static_cast<double>(1);
- }
- auto it = std::upper_bound(m_v.begin(), m_v.end(), x);
- return static_cast<double>(std::distance(m_v.begin(), it))/static_cast<double>(m_v.size());
- }
- else
- {
- if (x < m_v[0]) {
- return Real(0);
- }
- if (x >= m_v[m_v.size()-1]) {
- return Real(1);
- }
- auto it = std::upper_bound(m_v.begin(), m_v.end(), x);
- return static_cast<Real>(std::distance(m_v.begin(), it))/static_cast<Real>(m_v.size());
- }
- }
- RandomAccessContainer&& return_data() {
- return std::move(m_v);
- }
- private:
- RandomAccessContainer m_v;
- };
- }}
- #endif
|