#include <vector>
#include <cmath>
#include <Arduino.h>
template <typename T>
class CircularArray {
public:
CircularArray(size_t maxSize) {
maxCnt = maxSize;
buffer.resize(maxSize);
front = 0;
rear = 0;
count = 0;
minVal = T();
maxVal = T();
sum = 0.0;
sumSquared = 0.0;
}
void push(const T& value) {
if (count == maxCnt) {
removeOldestValue(buffer[front]);
front = (front + 1) % maxCnt;
}
buffer[rear] = value;
rear = (rear + 1) % maxCnt;
count = std::min(count + 1, maxCnt);
updateStatistics(value);
}
size_t currentSize() const {
return count;
}
void print() const {
if (count == 0) {
Serial.print("Empty ");
} else {
size_t index = front;
for (size_t i = 0; i < count; ++i) {
Serial.print(buffer[index]);
Serial.write(' ');
index = (index + 1) % maxCnt;
}
}
}
double average() const {
if (count == 0) return 0;
return sum / count;
}
T getMin() const {
return minVal;
}
T getMax() const {
return maxVal;
}
double getStandardDeviation() const {
if (count < 2) return 0;
double mean = average();
double variance = (sumSquared - (sum * sum) / count) / (count - 1);
return std::sqrt(variance);
}
private:
size_t maxCnt;
std::vector<T> buffer;
size_t front;
size_t rear;
size_t count;
T minVal;
T maxVal;
double sum;
double sumSquared;
void removeOldestValue(const T& value) {
if (value == minVal || value == maxVal) {
recalculateMinMax();
}
sum -= value;
sumSquared -= value * value;
}
void updateStatistics(const T& value) {
sum += value;
sumSquared += value * value;
if (count == 1) {
minVal = maxVal = value;
} else {
minVal = std::min(minVal, value);
maxVal = std::max(maxVal, value);
}
}
void recalculateMinMax() {
minVal = maxVal = buffer[front];
for (size_t i = 1; i < count; ++i) {
minVal = std::min(minVal, buffer[(front + i) % maxCnt]);
maxVal = std::max(maxVal, buffer[(front + i) % maxCnt]);
}
}
};
constexpr size_t N = 5;
CircularArray<double> circularArray(N);
void setup() {
Serial.begin(115200);
for (int i = 1; i <= 10; ++i) {
circularArray.push(i);
circularArray.print();
Serial.printf(" => average = %f, min = %f, max = %f, std deviation = %f\n",
circularArray.average(), circularArray.getMin(), circularArray.getMax(),
circularArray.getStandardDeviation());
}
}
void loop() {
}