embeddedLibrary/libraries/dataAcquisition.c
mrheltic d31bedd63e Added other tests
Added tests for:
-Average (all cases)
-STD (all cases)
-Anomaly detection (on a uniform distribution)
2024-11-21 16:35:08 +01:00

207 lines
5.2 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
int outlierCount;
// Variable definition
static float **readings;
static int sensorsNumber;
static int slidingWindowSize;
static void setSensorsNumber(int number) {
sensorsNumber = number;
}
static void setSlidingWindowSize(int size) {
slidingWindowSize = size;
}
void initializeReadings(int numSensors, int windowSize) {
readings = (float **)malloc(numSensors * sizeof(float *));
if (readings == NULL) {
perror("Failed to allocate memory for readings");
exit(EXIT_FAILURE);
}
for (int i = 0; i < numSensors; i++) {
readings[i] = (float *)calloc(windowSize, sizeof(float));
if (readings[i] == NULL) {
perror("Failed to allocate memory for sensor readings");
exit(EXIT_FAILURE);
}
}
// Chiamate private ai setter
setSensorsNumber(numSensors);
setSlidingWindowSize(windowSize);
}
bool freeReadings() {
for (int i = 0; i < sensorsNumber; i++) {
free(readings[i]);
}
if(readings != NULL){
free(readings);
return true;
}
else{
return false;
}
}
// Functions
// Get the number of sensors
int getSensorsNumber() {
return sensorsNumber;
}
// Get the sliding window size
int getSlidingWindowSize() {
return slidingWindowSize;
}
// Control on the fullness of the sliding window
bool isFull(int sensorIndex) {
for (int i = 0; i < slidingWindowSize; i++) {
if (readings[sensorIndex][i] == 0) {
return false;
}
}
return true;
}
float getLastReading(int sensorIndex) {
if (isFull(sensorIndex)) {
return readings[sensorIndex][slidingWindowSize - 1];
} else {
return readings[sensorIndex][0];
}
}
// Add a reading to the readings array
void addReading(float value, int sensorIndex) {
if (isFull(sensorIndex)) {
for (int i = 0; i < slidingWindowSize - 1; i++) {
readings[sensorIndex][i] = readings[sensorIndex][i + 1];
}
readings[sensorIndex][slidingWindowSize - 1] = value;
} else {
for (int i = 0; i < slidingWindowSize; i++) {
if (readings[sensorIndex][i] == 0) {
readings[sensorIndex][i] = value;
// Update the position index
break;
}
}
}
}
float getAverageOnSensor(int sensorIndex) {
if(isFull(sensorIndex) == false){
printf("The sliding window is not full\n");
return 0;
}
else{
float sum = 0;
for (int i = 0; i < slidingWindowSize; i++) {
sum += readings[sensorIndex][i];
}
return sum / slidingWindowSize;
}
}
float getAverageOnAllSensors() {
float sum = 0;
for (int i = 0; i < sensorsNumber; i++) {
sum += getLastReading(i);
}
return sum / sensorsNumber;
}
float getOverallAverage() {
float sum = 0;
int totalReadings = 0;
for (int i = 0; i < sensorsNumber; i++) {
if (!isFull(i)) {
printf("The sliding window for sensor %d is not full\n", i);
return 0;
}
for (int j = 0; j < slidingWindowSize; j++) {
sum += readings[i][j];
totalReadings++;
}
}
return sum / totalReadings;
}
float getStandardDeviationOnSensor(int sensorIndex) {
if(isFull(sensorIndex) == false){
printf("The sliding window is not full\n");
return 0;
}
else{
float sum = 0;
float average = getAverageOnSensor(sensorIndex);
for (int i = 0; i < slidingWindowSize; i++) {
sum += pow(readings[sensorIndex][i] - average, 2);
}
return sqrt(sum / slidingWindowSize);
}
}
float getStandardDeviationOnAllSensors() {
float sum = 0;
float average = getAverageOnAllSensors();
for (int i = 0; i < sensorsNumber; i++) {
float lastReading = getLastReading(i);
sum += pow(lastReading - average, 2);
}
return sqrt(sum / sensorsNumber);
}
void anomalyDetect(float average, float standardDeviation) {
float upperThreshold = average + 2.17 * standardDeviation; // 97% confidence interval
float lowerThreshold = average - 2.17 * standardDeviation; // Lower bound for anomaly detection
outlierCount = 0;
for (int i = 0; i < sensorsNumber; i++) {
for (int j = 0; j < slidingWindowSize; j++) {
if (readings[i][j] > upperThreshold || readings[i][j] < lowerThreshold) {
outlierCount++;
}
}
}
}
float getOverallStandardDeviation() {
float sum = 0;
int totalReadings = 0;
float totalAverage = getOverallAverage();
for (int i = 0; i < sensorsNumber; i++) {
if (!isFull(i)) {
printf("The sliding window for sensor %d is not full\n", i);
return 0;
}
for (int j = 0; j < slidingWindowSize; j++) {
sum += pow(readings[i][j] - getOverallAverage(), 2);
totalReadings++;
}
}
float totalStandardDeviation = sqrt(sum / totalReadings);
anomalyDetect(totalAverage, totalStandardDeviation);
return totalStandardDeviation;
}
int getOutlierCount() {
return outlierCount;
}