XMM - Probabilistic Models for Motion Recognition and Mapping

xmmCircularbuffer.hpp
Go to the documentation of this file.
1 /*
2  * xmmCircularBuffer.hpp
3  *
4  * Simple Circular Buffer Utility
5  *
6  * Contact:
7  * - Jules Francoise <jules.francoise@ircam.fr>
8  *
9  * This code has been initially authored by Jules Francoise
10  * <http://julesfrancoise.com> during his PhD thesis, supervised by Frederic
11  * Bevilacqua <href="http://frederic-bevilacqua.net>, in the Sound Music
12  * Movement Interaction team <http://ismm.ircam.fr> of the
13  * STMS Lab - IRCAM, CNRS, UPMC (2011-2015).
14  *
15  * Copyright (C) 2015 UPMC, Ircam-Centre Pompidou.
16  *
17  * This File is part of XMM.
18  *
19  * XMM is free software: you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation, either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * XMM is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with XMM. If not, see <http://www.gnu.org/licenses/>.
31  */
32 
33 #ifndef xmmCircularbuffer_h
34 #define xmmCircularbuffer_h
35 
36 #include <exception>
37 #include <stdexcept>
38 #include <vector>
39 
40 namespace xmm {
48 template <typename T, unsigned int channels = 1>
50  public:
55  CircularBuffer(unsigned int length = 1) {
56  length_ = length;
57  for (int c = 0; c < channels; c++) {
58  data_[c].resize(length_);
59  }
60  current_index_ = 0;
61  full_ = false;
62  }
63 
68  T operator()(unsigned int channel, unsigned int index) const {
69  if (channel >= channels)
70  throw std::out_of_range("CircularBuffer: channel out of bounds");
71  unsigned int m = full_ ? length_ : current_index_;
72  if (index >= m)
73  throw std::out_of_range("CircularBuffer: index out of bounds");
74  return data_[channel][index];
75  }
76 
80  void clear() {
81  current_index_ = 0;
82  full_ = false;
83  }
84 
90  void push(T const value) {
91  if (channels > 1)
92  throw std::invalid_argument("You must pass a vector or array");
93  data_[0][current_index_] = value;
95  if (current_index_ == length_) full_ = true;
97  }
98 
103  void push(T const *value) {
104  for (int c = 0; c < channels; c++) {
105  data_[c][current_index_] = value[c];
106  }
107  current_index_++;
108  if (current_index_ == length_) full_ = true;
110  }
111 
116  void push(std::vector<T> const &value) {
117  for (int c = 0; c < channels; c++) {
118  data_[c][current_index_] = value[c];
119  }
120  current_index_++;
121  if (current_index_ == length_) full_ = true;
123  }
124 
129  unsigned int size() const { return length_; }
130 
136  unsigned int size_t() const { return (full_ ? length_ : current_index_); }
137 
142  void resize(unsigned int length) {
143  if (length == length_) return;
144  if (length > length_) {
145  full_ = false;
146  } else if (current_index_ >= length) {
147  full_ = true;
148  current_index_ = 0;
149  }
150  length_ = length;
151  for (int c = 0; c < channels; c++) {
152  data_[c].resize(length_);
153  }
154  }
155 
160  std::vector<T> mean() const {
161  std::vector<T> _mean(channels, 0.0);
162  int size = full_ ? length_ : current_index_;
163  for (int c = 0; c < channels; c++) {
164  for (int i = 0; i < size; i++) {
165  _mean[c] += data_[c][i];
166  }
167  _mean[c] /= T(size);
168  }
169  return _mean;
170  }
171 
172  protected:
176  std::vector<T> data_[channels];
177 
181  unsigned int length_;
182 
186  unsigned int current_index_;
187 
191  bool full_;
192 };
193 }
194 
195 #endif
unsigned int size_t() const
Get the actual size of the CircularBuffer (< size() if the buffer is not full)
Definition: xmmCircularbuffer.hpp:136
void push(T const *value)
Add an element to the buffer (multi-channel method)
Definition: xmmCircularbuffer.hpp:103
Simple CircularBuffer Class.
Definition: xmmCircularbuffer.hpp:49
T operator()(unsigned int channel, unsigned int index) const
Access data by index & channel.
Definition: xmmCircularbuffer.hpp:68
void push(std::vector< T > const &value)
Add an element to the buffer (multi-channel method)
Definition: xmmCircularbuffer.hpp:116
unsigned int length_
length of the buffer
Definition: xmmCircularbuffer.hpp:181
void clear()
Clear the content of the buffer.
Definition: xmmCircularbuffer.hpp:80
std::vector< T > mean() const
Compute the mean of the buffer.
Definition: xmmCircularbuffer.hpp:160
void push(T const value)
Add an element to the buffer (single-channel method)
Definition: xmmCircularbuffer.hpp:90
std::vector< T > data_[channels]
buffer data
Definition: xmmCircularbuffer.hpp:176
unsigned int current_index_
current index in the buffer
Definition: xmmCircularbuffer.hpp:186
CircularBuffer(unsigned int length=1)
Constructor.
Definition: xmmCircularbuffer.hpp:55
Definition: xmmAttribute.hpp:42
void resize(unsigned int length)
Resize the buffer to a specific length.
Definition: xmmCircularbuffer.hpp:142
bool full_
Defines if the CircularBuffer is already full.
Definition: xmmCircularbuffer.hpp:191
unsigned int size() const
Get the size of the CircularBuffer.
Definition: xmmCircularbuffer.hpp:129