summaryrefslogtreecommitdiff
path: root/src/third_party/boost/boost/math/statistics/ljung_box.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/boost/boost/math/statistics/ljung_box.hpp')
-rw-r--r--src/third_party/boost/boost/math/statistics/ljung_box.hpp70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/third_party/boost/boost/math/statistics/ljung_box.hpp b/src/third_party/boost/boost/math/statistics/ljung_box.hpp
new file mode 100644
index 00000000000..6417665ce4b
--- /dev/null
+++ b/src/third_party/boost/boost/math/statistics/ljung_box.hpp
@@ -0,0 +1,70 @@
+// (C) 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_STATISTICS_LJUNG_BOX_HPP
+#define BOOST_MATH_STATISTICS_LJUNG_BOX_HPP
+
+#include <cmath>
+#include <iterator>
+#include <utility>
+#include <boost/math/distributions/chi_squared.hpp>
+#include <boost/math/statistics/univariate_statistics.hpp>
+
+namespace boost::math::statistics {
+
+template<class RandomAccessIterator>
+auto ljung_box(RandomAccessIterator begin, RandomAccessIterator end, int64_t lags = -1, int64_t fit_dof = 0) {
+ using Real = typename std::iterator_traits<RandomAccessIterator>::value_type;
+ int64_t n = std::distance(begin, end);
+ if (lags >= n) {
+ throw std::domain_error("Number of lags must be < number of elements in array.");
+ }
+
+ if (lags == -1) {
+ // This is the same default as Mathematica; it seems sensible enough . . .
+ lags = static_cast<int64_t>(std::ceil(std::log(Real(n))));
+ }
+
+ if (lags <= 0) {
+ throw std::domain_error("Must have at least one lag.");
+ }
+
+ auto mu = boost::math::statistics::mean(begin, end);
+
+ std::vector<Real> r(lags + 1, Real(0));
+ for (size_t i = 0; i < r.size(); ++i) {
+ for (auto it = begin + i; it != end; ++it) {
+ Real ak = *(it) - mu;
+ Real akml = *(it-i) - mu;
+ r[i] += ak*akml;
+ }
+ }
+
+ Real Q = 0;
+
+ for (size_t k = 1; k < r.size(); ++k) {
+ Q += r[k]*r[k]/(r[0]*r[0]*(n-k));
+ }
+ Q *= n*(n+2);
+
+ typedef boost::math::policies::policy<
+ boost::math::policies::promote_float<false>,
+ boost::math::policies::promote_double<false> >
+ no_promote_policy;
+
+ auto chi = boost::math::chi_squared_distribution<Real, no_promote_policy>(Real(lags - fit_dof));
+
+ Real pvalue = 1 - boost::math::cdf(chi, Q);
+ return std::make_pair(Q, pvalue);
+}
+
+
+template<class RandomAccessContainer>
+auto ljung_box(RandomAccessContainer const & v, int64_t lags = -1, int64_t fit_dof = 0) {
+ return ljung_box(v.begin(), v.end(), lags, fit_dof);
+}
+
+}
+#endif