Antkeeper  0.0.1
moving-average.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef ANTKEEPER_MATH_MOVING_AVERAGE_HPP
21 #define ANTKEEPER_MATH_MOVING_AVERAGE_HPP
22 
23 #include <algorithm>
24 #include <cstdint>
25 #include <vector>
26 
27 namespace math {
28 
34 template <class T>
36 {
37 public:
39  using sample_type = T;
40 
47  explicit moving_average(std::size_t capacity):
48  m_samples(capacity)
49  {}
50  moving_average() noexcept = default;
52 
60  sample_type operator()(sample_type value) noexcept
61  {
62  m_sum += value;
63  if (m_sample_index < m_samples.size())
64  {
65  m_samples[m_sample_index] = value;
66  ++m_sample_index;
67  m_average = m_sum / static_cast<sample_type>(m_sample_index);
68  }
69  else
70  {
71  sample_type& sample = m_samples[m_sample_index % m_samples.size()];
72  m_sum -= sample;
73  sample = value;
74  ++m_sample_index;
75  m_average = m_sum / static_cast<sample_type>(m_samples.size());
76  }
77 
78  return m_average;
79  }
80 
84  void reset() noexcept
85  {
86  m_sample_index = 0;
87  m_sum = sample_type{0};
88  m_average = sample_type{0};
89  }
90 
96  void reserve(std::size_t capacity)
97  {
98  m_samples.resize(capacity, sample_type{0});
99  }
100 
106  void resize(std::size_t size)
107  {
108  if (size > m_samples.size())
109  {
110  m_samples.resize(size);
111  }
112  m_sample_index = size;
113  }
114 
116  [[nodiscard]] inline constexpr sample_type* data() const noexcept
117  {
118  return m_samples.data();
119  }
120 
122  [[nodiscard]] inline sample_type average() const noexcept
123  {
124  return m_average;
125  }
126 
128  [[nodiscard]] inline sample_type sum() const noexcept
129  {
130  return m_sum;
131  }
132 
134  [[nodiscard]] inline std::size_t size() const noexcept
135  {
136  return std::min<std::size_t>(m_sample_index, m_samples.size());
137  }
138 
140  [[nodiscard]] inline constexpr std::size_t capacity() const noexcept
141  {
142  return m_samples.size();
143  }
144 
146  [[nodiscard]] inline constexpr bool empty() const noexcept
147  {
148  return !m_sample_index;
149  }
150 
152  [[nodiscard]] inline constexpr bool full() const noexcept
153  {
154  return m_sample_index >= m_samples.size();
155  }
156 
157 private:
158  std::vector<sample_type> m_samples;
159  std::size_t m_sample_index{0};
160  sample_type m_sum{0};
161  sample_type m_average{0};
162 };
163 
164 } // namespace math
165 
166 #endif // ANTKEEPER_MATH_MOVING_AVERAGE_HPP
Calculates a moving average.
std::size_t size() const noexcept
Returns the current number of samples.
sample_type sum() const noexcept
Returns the sum of all current samples.
void reset() noexcept
Resets the moving average.
constexpr sample_type * data() const noexcept
Returns a pointer to the sample data.
T sample_type
Type of value to average.
constexpr std::size_t capacity() const noexcept
Returns the maximum number of samples.
moving_average(std::size_t capacity)
Constructs a moving average.
void reserve(std::size_t capacity)
Changes the sample capacity of the moving average.
sample_type average() const noexcept
Returns the current moving average value.
constexpr bool empty() const noexcept
Return true if there are currently no samples in the average, false otherwise.
void resize(std::size_t size)
Changes the current number of samples of the moving average.
moving_average() noexcept=default
Constructs a moving average.
constexpr bool full() const noexcept
Return true if the number of samples in the average has reached its capacity, false otherwise.
Mathematical functions and data types.
Definition: angles.hpp:26