diff options
Diffstat (limited to 'third-party/boost-math/include/boost/math/distributions/empirical_cumulative_distribution_function.hpp')
| -rw-r--r-- | third-party/boost-math/include/boost/math/distributions/empirical_cumulative_distribution_function.hpp | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/third-party/boost-math/include/boost/math/distributions/empirical_cumulative_distribution_function.hpp b/third-party/boost-math/include/boost/math/distributions/empirical_cumulative_distribution_function.hpp new file mode 100644 index 000000000000..0d43db16f21a --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/empirical_cumulative_distribution_function.hpp @@ -0,0 +1,73 @@ +// 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 |
