Added other tests
Added tests for: -Average (all cases) -STD (all cases) -Anomaly detection (on a uniform distribution)
This commit is contained in:
parent
4a97a81d7a
commit
d31bedd63e
@ -6,7 +6,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void initializeReadings();
|
void initializeReadings();
|
||||||
void freeReadings();
|
bool freeReadings();
|
||||||
|
|
||||||
int getSensorsNumber();
|
int getSensorsNumber();
|
||||||
int getSlidingWindowSize();
|
int getSlidingWindowSize();
|
||||||
@ -20,6 +20,12 @@ float getOverallAverage();
|
|||||||
|
|
||||||
float getStandardDeviationOnSensor(int sensorIndex);
|
float getStandardDeviationOnSensor(int sensorIndex);
|
||||||
float getStandardDeviationOnAllSensors();
|
float getStandardDeviationOnAllSensors();
|
||||||
float getStandardDeviationOnAllSensors();
|
float getOverallStandardDeviation();
|
||||||
|
|
||||||
|
float getLastReading(int sensorIndex);
|
||||||
|
|
||||||
|
bool anomalyDetect(float average, float standardDeviation);
|
||||||
|
|
||||||
|
int getOutlierCount();
|
||||||
|
|
||||||
#endif // DATA_ACQUISITION_H
|
#endif // DATA_ACQUISITION_H
|
||||||
@ -3,6 +3,8 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
int outlierCount;
|
||||||
|
|
||||||
// Variable definition
|
// Variable definition
|
||||||
static float **readings;
|
static float **readings;
|
||||||
static int sensorsNumber;
|
static int sensorsNumber;
|
||||||
@ -35,11 +37,19 @@ void initializeReadings(int numSensors, int windowSize) {
|
|||||||
setSlidingWindowSize(windowSize);
|
setSlidingWindowSize(windowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeReadings() {
|
bool freeReadings() {
|
||||||
for (int i = 0; i < sensorsNumber; i++) {
|
for (int i = 0; i < sensorsNumber; i++) {
|
||||||
free(readings[i]);
|
free(readings[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(readings != NULL){
|
||||||
free(readings);
|
free(readings);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
@ -64,6 +74,14 @@ bool isFull(int sensorIndex) {
|
|||||||
return true;
|
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
|
// Add a reading to the readings array
|
||||||
void addReading(float value, int sensorIndex) {
|
void addReading(float value, int sensorIndex) {
|
||||||
if (isFull(sensorIndex)) {
|
if (isFull(sensorIndex)) {
|
||||||
@ -75,6 +93,8 @@ void addReading(float value, int sensorIndex) {
|
|||||||
for (int i = 0; i < slidingWindowSize; i++) {
|
for (int i = 0; i < slidingWindowSize; i++) {
|
||||||
if (readings[sensorIndex][i] == 0) {
|
if (readings[sensorIndex][i] == 0) {
|
||||||
readings[sensorIndex][i] = value;
|
readings[sensorIndex][i] = value;
|
||||||
|
// Update the position index
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +119,7 @@ float getAverageOnSensor(int sensorIndex) {
|
|||||||
float getAverageOnAllSensors() {
|
float getAverageOnAllSensors() {
|
||||||
float sum = 0;
|
float sum = 0;
|
||||||
for (int i = 0; i < sensorsNumber; i++) {
|
for (int i = 0; i < sensorsNumber; i++) {
|
||||||
sum += getAverageOnSensor(i);
|
sum += getLastReading(i);
|
||||||
}
|
}
|
||||||
return sum / sensorsNumber;
|
return sum / sensorsNumber;
|
||||||
}
|
}
|
||||||
@ -137,15 +157,33 @@ float getStandardDeviationOnSensor(int sensorIndex) {
|
|||||||
|
|
||||||
float getStandardDeviationOnAllSensors() {
|
float getStandardDeviationOnAllSensors() {
|
||||||
float sum = 0;
|
float sum = 0;
|
||||||
|
float average = getAverageOnAllSensors();
|
||||||
for (int i = 0; i < sensorsNumber; i++) {
|
for (int i = 0; i < sensorsNumber; i++) {
|
||||||
sum += getStandardDeviationOnSensor(i);
|
float lastReading = getLastReading(i);
|
||||||
|
sum += pow(lastReading - average, 2);
|
||||||
}
|
}
|
||||||
return sum / sensorsNumber;
|
|
||||||
|
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 getOverallStandardDeviation() {
|
||||||
float sum = 0;
|
float sum = 0;
|
||||||
int totalReadings = 0;
|
int totalReadings = 0;
|
||||||
|
float totalAverage = getOverallAverage();
|
||||||
for (int i = 0; i < sensorsNumber; i++) {
|
for (int i = 0; i < sensorsNumber; i++) {
|
||||||
if (!isFull(i)) {
|
if (!isFull(i)) {
|
||||||
printf("The sliding window for sensor %d is not full\n", i);
|
printf("The sliding window for sensor %d is not full\n", i);
|
||||||
@ -156,5 +194,14 @@ float getOverallStandardDeviation() {
|
|||||||
totalReadings++;
|
totalReadings++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sqrt(sum / totalReadings);
|
|
||||||
|
float totalStandardDeviation = sqrt(sum / totalReadings);
|
||||||
|
|
||||||
|
anomalyDetect(totalAverage, totalStandardDeviation);
|
||||||
|
|
||||||
|
return totalStandardDeviation;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getOutlierCount() {
|
||||||
|
return outlierCount;
|
||||||
}
|
}
|
||||||
@ -3,14 +3,105 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "../include/dataAcquisition.h"
|
#include "../include/dataAcquisition.h"
|
||||||
|
|
||||||
|
#define NUMBER_OF_SENSORS 5
|
||||||
|
#define SLIDING_WINDOW_SIZE 10
|
||||||
|
|
||||||
|
#define AVERAGE_UNCERTAINTY 0.01
|
||||||
|
#define STD_UNCERTAINTY 0.01
|
||||||
|
|
||||||
|
// Testing the inizialization and the instanciacion of the sensors' number and sliding window size
|
||||||
void test_initializeReadings() {
|
void test_initializeReadings() {
|
||||||
initializeReadings(5, 100);
|
initializeReadings(NUMBER_OF_SENSORS, SLIDING_WINDOW_SIZE);
|
||||||
assert(getSensorsNumber() == 5);
|
assert(getSensorsNumber() == NUMBER_OF_SENSORS);
|
||||||
assert(getSlidingWindowSize() == 100);
|
assert(getSlidingWindowSize() == SLIDING_WINDOW_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Testing the logic of add readings to see if the slidinw window is full
|
||||||
|
void test_addReading() {
|
||||||
|
for (int sensor = 0; sensor < NUMBER_OF_SENSORS; sensor++) {
|
||||||
|
for (int value = 1; value <= SLIDING_WINDOW_SIZE; value++) {
|
||||||
|
addReading(value, sensor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(isFull(NUMBER_OF_SENSORS-1) == true); // Assuming the last sensor acquired the data
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing the logic of average methods
|
||||||
|
void test_averageOnSensor() {
|
||||||
|
printf("Average on sensor %d: %f\n", NUMBER_OF_SENSORS-1, getAverageOnSensor(NUMBER_OF_SENSORS-1));
|
||||||
|
float average = getAverageOnSensor(NUMBER_OF_SENSORS-1);
|
||||||
|
float expected_average = (SLIDING_WINDOW_SIZE + 1) / 2.0;
|
||||||
|
assert(fabs(average - expected_average) < AVERAGE_UNCERTAINTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_standardDeviationOnSensor() {
|
||||||
|
printf("Standard deviation on sensor %d: %f\n", NUMBER_OF_SENSORS-1, getStandardDeviationOnSensor(NUMBER_OF_SENSORS-1));
|
||||||
|
float standard_deviation = getStandardDeviationOnSensor(NUMBER_OF_SENSORS-1);
|
||||||
|
float expected_standard_deviation = 2.872281323269;
|
||||||
|
assert(fabs(standard_deviation - expected_standard_deviation) < STD_UNCERTAINTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_averageOnAllSensors() {
|
||||||
|
printf("Average on all sensors: %f\n", getAverageOnAllSensors());
|
||||||
|
float average = getAverageOnAllSensors();
|
||||||
|
float expected_average = SLIDING_WINDOW_SIZE;
|
||||||
|
assert(fabs(average - expected_average) < AVERAGE_UNCERTAINTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_standardDeviationOnAllSensors() {
|
||||||
|
printf("Standard deviation on all sensors: %f\n", getStandardDeviationOnAllSensors());
|
||||||
|
float standard_deviation = getStandardDeviationOnAllSensors();
|
||||||
|
float expected_standard_deviation = 0;
|
||||||
|
assert(fabs(standard_deviation - expected_standard_deviation) < STD_UNCERTAINTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_overallAverage(){
|
||||||
|
printf("Overall average on all sensors: %f\n", getOverallAverage());
|
||||||
|
float average = getOverallAverage();
|
||||||
|
float expected_overall_average = (SLIDING_WINDOW_SIZE + 1) / 2.0;
|
||||||
|
assert(fabs(average - expected_overall_average) < AVERAGE_UNCERTAINTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_overallStandardDeviation(){
|
||||||
|
printf("Overall standard deviation: %f\n", getOverallStandardDeviation());
|
||||||
|
float standard_deviation = getStandardDeviationOnSensor(NUMBER_OF_SENSORS-1);
|
||||||
|
float expected_standard_deviation = 2.872281323269;
|
||||||
|
assert(fabs(standard_deviation - expected_standard_deviation) < STD_UNCERTAINTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_anomalyDetect(){
|
||||||
|
float average = getOverallAverage();
|
||||||
|
float standard_deviation = getOverallStandardDeviation();
|
||||||
|
anomalyDetect(average, standard_deviation);
|
||||||
|
printf("Outlier count: %i\n", getOutlierCount());
|
||||||
|
assert(fabs(getOutlierCount() - 0) < 0.01);
|
||||||
|
|
||||||
|
// Adding an outlier
|
||||||
|
addReading(20, NUMBER_OF_SENSORS-1);
|
||||||
|
average = getOverallAverage();
|
||||||
|
standard_deviation = getOverallStandardDeviation();
|
||||||
|
anomalyDetect(average, standard_deviation);
|
||||||
|
printf("Outlier count: %i\n", getOutlierCount());
|
||||||
|
assert(fabs(getOutlierCount() - 1) < 0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Test all the functions with a normal distribution
|
||||||
|
|
||||||
|
// TODO: Evaluate the normal distribution with the anomaly detection
|
||||||
|
void test_freeReadings() {
|
||||||
|
assert(freeReadings() == true);
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
test_initializeReadings();
|
test_initializeReadings();
|
||||||
|
test_addReading();
|
||||||
|
test_averageOnSensor();
|
||||||
|
test_standardDeviationOnSensor();
|
||||||
|
test_averageOnAllSensors();
|
||||||
|
test_standardDeviationOnAllSensors();
|
||||||
|
test_overallAverage();
|
||||||
|
test_overallStandardDeviation();
|
||||||
|
test_anomalyDetect();
|
||||||
|
test_freeReadings();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user