summaryrefslogtreecommitdiff
path: root/third-party/boost-math/include/boost/math/distributions/empirical_cumulative_distribution_function.hpp
diff options
context:
space:
mode:
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.hpp73
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