MMS-Loesung-2024-25/tests.c
2025-01-17 21:19:23 +01:00

798 lines
26 KiB
C

//
// Created by frederik on 1/11/25.
//
#include "MMS24-25.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
// Preprocessor Definitions in case they are not defined
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif
#ifndef NULL
#define NULL 0
#endif
void info(char* fmt,...) {
fprintf(stderr, "[\x1B[37;1m INFO \x1B[0m] \x1B[34m'");
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "'\x1B[0m\n");
}
void success(char* fmt,...) {
fprintf(stderr, "[\x1B[32;1m PASS \x1B[0m] \x1B[34m'");
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "'\x1B[0m\n");
}
void error(const char* fmt, ...) {
va_list args;
fprintf(stderr, "<\x1B[31;1m ERROR \x1B[0m: \x1B[34m'");
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "'\x1B[0m >\n");
exit(-1);
}
void testInterpolation() {
info("testInterpolation");
double dRangeMin = -1;
double dRangeMax = 1;
double dRangeStep = 0.33;
for (double dX1=dRangeMin;dX1<dRangeMax;dX1+=dRangeStep) {
for (double dX2=dRangeMin;dX2<dRangeMax;dX2+=dRangeStep) {
for (double dY1=dRangeMin;dY1<dRangeMax;dY1+=dRangeStep) {
for (double dY2=dRangeMin;dY2<dRangeMax;dY2+=dRangeStep) {
for (double dX=dRangeMin;dX<dRangeMax;dX+=dRangeStep) {
if (dX1 == dX2 || dX1 == dX || dX2 == dX)
continue;
double dR1 = interpolateLine(dX1, dY1, dX2, dY2, dX);
double dR2 = interpolateLine(dX1, dY1, dX, dR1, dX2);
if (round(dR2*1e6) != round(dY2*1e6))
error("Failed assertion for: (%lf, %lf), (%lf, %lf) -> (%lf, %lf); %lf", dX1, dY1, dX2, dY2, dX, dR1, dR2);
}
}
}
}
}
success("testInterpolation();");
}
void testSineAndReadWriteDoubleArraySingle(int nValues, int dPLen, double dAmp) {
info("Trying: %d, %d, %lf", nValues, dPLen, dAmp);
char* fileName = NULL;
fileName = malloc(100*sizeof(char));
if (fileName == NULL) {
error("Could not allocate Memory for `fileName`!");
}
sprintf(fileName, "sine_%d_%d_%lf.results.txt", nValues, dPLen, dAmp);
double *pdSineValues = generateSineValues(
nValues,
dPLen,
dAmp
);
writeDoubleArray(
pdSineValues,
nValues,
fileName
);
success("Wrote %d values to %s", nValues, fileName);
double *pdReadValues = NULL;
int iReadValues = readDoubleArray(
fileName,
&pdReadValues
);
if (iReadValues != nValues) {
error("Failed to read the correct number of values: %d != %d", iReadValues, nValues);
}
success("Read %d values from %s", iReadValues, fileName);
for (int i=0; i<nValues; i++) {
if (round(pdSineValues[i]*1e6) != round(pdReadValues[i]*1e6)) {
error("Failed to read the correct value at index %d: %lf != %lf", i, pdSineValues[i], pdReadValues[i]);
}
}
info("use `plot \"%s\", \"%s\" with lines` to view.", fileName, fileName);
free(fileName);
free(pdSineValues);
free(pdReadValues);
}
void testSineAndReadWriteDoubleArray() {
info("testSineAndWriteDoubleArray");
testSineAndReadWriteDoubleArraySingle(1000, 300, 1);
testSineAndReadWriteDoubleArraySingle(10, 10, 0.5);
testSineAndReadWriteDoubleArraySingle(10, -10, 0.5);
testSineAndReadWriteDoubleArraySingle(10, 10, 0);
success("testSineAndWriteDoubleArray");
}
void testCreateSignalWithDefault() {
info("testCreateSignalWithDefault");
MMSignal *signal = createSignalWithDefault(10, M_PI);
if (signal->iNumValues != 10) {
error("Failed to create signal with 10 values: %d != 10", signal->iNumValues);
}
for (int i=0; i<10; i++) {
if (signal->pdValues[i] != M_PI) {
error("Failed to create signal with default value 0 at index %d: %lf != 0", i, signal->pdValues[i]);
}
}
success("testCreateSignalWithDefault");
deleteSignal(signal);
}
void testCreateSignalFromDoubleArray() {
info("testCreateSignalFromDoubleArray");
double pdValues[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
MMSignal *signal = createSignalFromDoubleArray(10, pdValues);
if (signal->iNumValues != 10) {
error("Failed to create signal with 10 values: %d != 10", signal->iNumValues);
}
for (int i=0; i<10; i++) {
if (signal->pdValues[i] != pdValues[i]) {
error("Failed to create signal with default value 0 at index %d: %lf != 0", i, signal->pdValues[i]);
}
}
success("testCreateSignalFromDoubleArray");
deleteSignal(signal);
}
void testCreateSignalFromFile() {
info("testCreateSignalFromFile");
double pdValues[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
char* fileName = "testCreateSignalFromFile.results.txt";
writeDoubleArray(pdValues, 10, fileName);
MMSignal *signal = createSignalFromFile(fileName);
if (signal->iNumValues != 10) {
error("Failed to create signal with 10 values: %d != 10", signal->iNumValues);
}
for (int i=0; i<10; i++) {
if (signal->pdValues[i] != pdValues[i]) {
error("Failed to create signal with default value 0 at index %d: %lf != 0", i, signal->pdValues[i]);
}
}
success("testCreateSignalFromFile");
deleteSignal(signal);
}
void testWriteMMSignal() {
info("testWriteMMSignal");
double pdValues[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
char* fileName = "testWriteMMSignal.results.txt";
MMSignal *signal = createSignalFromDoubleArray(10, pdValues);
writeMMSignal(fileName, signal);
MMSignal *readSignal = createSignalFromFile(fileName);
if (signal->iNumValues != readSignal->iNumValues) {
error("Failed to read the correct number of values: %d != %d", signal->iNumValues, readSignal->iNumValues);
}
for (int i=0; i<10; i++) {
if (signal->pdValues[i] != readSignal->pdValues[i]) {
error("Failed to read the correct value at index %d: %lf != %lf", i, signal->pdValues[i], readSignal->pdValues[i]);
}
}
deleteSignal(signal);
deleteSignal(readSignal);
success("testWriteMMSignal");
}
void testCalculateArea() {
info("testCalculateArea");
double pdValues[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
double dArea = calculateArea(pdValues, 10);
if (round(dArea*1e6) != 55e6) {
error("Failed to calculate the correct area: %lf != 55", dArea);
}
success("testCalculateArea");
}
void testCalculateMean() {
info("testCalculateMean");
double pdValues[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
double dMean = calculateMean(pdValues, 10);
if (round(dMean*1e6) != 5.5e6) {
error("Failed to calculate the correct mean: %lf != 5.5", dMean);
}
success("testCalculateMean");
}
void testCalculateStdDev() {
info("testCalculateStdDev");
double pdValues[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
double dStdDev = calculateStddev(pdValues, 10);
if (round(dStdDev*1e6) != 2.872281e6) {
error("Failed to calculate the correct standard deviation: %lf != 2.872281", dStdDev);
}
success("testCalculateStdDev");
}
void testCalculateMedian() {
info("testCalculateMedian");
double pdValues[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
double dMedian = calculateMedian(pdValues, 10);
if (dMedian != 5.5) {
error("Failed to calculate the correct median: %lf != 5.5", dMedian);
}
double pdValues2[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
dMedian = calculateMedian(pdValues2, 9);
if (dMedian != 5) {
error("Failed to calculate the correct median: %lf != 5", dMedian);
}
success("testCalculateMedian");
}
void testCalculateEntropy() {
info("testCalculateEntropy");
double pdValues[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Histogram *histogram = initHistogram(pdValues, 11, 11);
double dEntropy = calculateEntropy(histogram);
if (round(dEntropy*1e6) != 3.459432e6) { // Should be log2(1/11) = 3.459432
error("Failed to calculate the correct entropy: %lf != 3.459432", dEntropy);
}
success("testCalculateEntropy");
}
void testConvoluteSignals() {
info("testConvoluteSignals");
double pdValues1[] = {1, 2, 3, 4, 5};
double pdValues2[] = {1, 2, 3, 4, 5};
MMSignal *signal1 = createSignalFromDoubleArray(5, pdValues1);
MMSignal *signal2 = createSignalFromDoubleArray(5, pdValues2);
MMSignal *signal3 = convoluteSignals(signal1, signal2);
if (signal3->iNumValues != 9) {
error("Failed to calculate the correct number of values: %d != 9", signal3->iNumValues);
}
double pdExpectedValues[] = {1, 4, 10, 20, 35, 44, 46, 40, 25};
for (int i=0; i<9; i++) {
if (signal3->pdValues[i] != pdExpectedValues[i]) {
error("Failed to calculate the correct value at index %d: %lf != %lf", i, signal3->pdValues[i], pdExpectedValues[i]);
}
}
success("testConvoluteSignals");
}
void testGetPascalLine() {
info("testGetPascalLine");
// For 5
MMSignal *signal = getPascalLine(5);
if (signal->iNumValues != 5) {
error("Failed to calculate the correct number of values: %d != 5", signal->iNumValues);
}
double pdExpectedValues[] = {1, 4, 6, 4, 1};
for (int i=0; i<5; i++) {
if (signal->pdValues[i] != pdExpectedValues[i]) {
error("Failed to calculate the correct value at index %d: %lf != %lf", i, signal->pdValues[i], pdExpectedValues[i]);
}
}
// For 1
signal = getPascalLine(1);
if (signal->iNumValues != 1) {
error("Failed to calculate the correct number of values: %d != 1", signal->iNumValues);
}
if (signal->pdValues[0] != 1) {
error("Failed to calculate the correct value at index 0: %lf != 1", signal->pdValues[0]);
}
// For 11
signal = getPascalLine(11);
if (signal->iNumValues != 11) {
error("Failed to calculate the correct number of values: %d != 11", signal->iNumValues);
}
double pdExpectedValues11[] = {1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1};
for (int i=0; i<11; i++) {
if (signal->pdValues[i] != pdExpectedValues11[i]) {
error("Failed to calculate the correct value at index %d: %lf != %lf", i, signal->pdValues[i], pdExpectedValues11[i]);
}
}
success("testGetPascalLine");
}
void testApplyPascalConvForSeriesGT40() {
info("testApplyPascalForSeriesGT40");
MMSignal *signal = getPascalLine(40);
MMSignal *signal2 = convoluteSignals(signal, signal);
writeMMSignal("testApplyPascalForSeriesGT40.results.txt", signal2);
success("testApplyPascalForSeriesGT40");
}
void testComputeDFT() {
info("testComputeDFT");
double pdRealIn[] = {1, 2, 3, 4, 5};
double pdImgIn[] = {1, 2, 3, 4, 5};
double pdRealOut[5];
double pdImgOut[5];
computeDFT(5, pdRealIn, pdImgIn, pdRealOut, pdImgOut, 1);
for (int i=0; i<5; i++) {
if (pdImgOut[i] < 0) {
printf("%lf - %lfi\n", pdRealOut[i], -pdImgOut[i]);
} else {
printf("%lf + %lfi\n", pdRealOut[i], pdImgOut[i]);
}
}
success("testComputeDFT");
}
void testConvertCart2Polar() {
// convertCart2Polar(double *pdRealIn, double *pdImgIn, double *pdRadiusOut, double *pdAngleOut, int iLen)
info("testConvertCart2Polar");
double pdRealIn[] = {1, 0, 1, -1, 0};
double pdImgIn[] = {0, 1, 1, 0, -1};
double pdRadiusOut[5];
double pdAngleOut[5];
convertCart2Polar(pdRealIn, pdImgIn, pdRadiusOut, pdAngleOut, 5);
for (int i=0; i<5; i++) {
printf("%lf + %lfi -> r=%lf / θ=%lfπ\n", pdRealIn[i], pdImgIn[i], pdRadiusOut[i], pdAngleOut[i] / M_PI);
}
success("testConvertCart2Polar");
}
void testConvertPolar2Cart() {
// convertPolar2Cart(double *pdRadiusIn, double *pdAngleIn, double *pdRealOut, double *pdImgOut, int iLen)
info("testConvertPolar2Cart");
double pdRadiusIn[] = {1, 1, 1, 1, 1};
double pdAngleIn[] = {0, M_PI/2, M_PI, 3*M_PI/2, 2*M_PI};
double pdRealOut[5];
double pdImgOut[5];
convertPolar2Cart(pdRadiusIn, pdAngleIn, pdRealOut, pdImgOut, 5);
for (int i=0; i<5; i++) {
printf("r=%lf / θ=%lfπ -> %lf + %lfi\n", pdRadiusIn[i], pdAngleIn[i] / M_PI, pdRealOut[i], pdImgOut[i]);
}
success("testConvertPolar2Cart");
}
void testCalcExtrema() {
info("testCalcExtrema");
double pdValues[] = {1, 2, 1, 0, -1, -2, -1, 0, 1, 5};
Extrema *extrema = initExtrema(pdValues, 10);
info("*extrema: %p", extrema);
info("*extrema->pexLocalMax: %p", extrema->pexLocalMax);
info("*extrema->pexLocalMin: %p", extrema->pexLocalMin);
info("*extrema->pexLocalMax->piLocalExtremaPos: %p", extrema->pexLocalMax->piLocalExtremaPos);
info("*extrema->pexLocalMin->piLocalExtremaPos: %p", extrema->pexLocalMin->piLocalExtremaPos);
if (extrema->pexLocalMax->iNumLocalExtrema != 1) {
error("Failed to calculate the correct number of local maxima: %d != 1", extrema->pexLocalMax->iNumLocalExtrema);
}
if (extrema->pexLocalMin->iNumLocalExtrema != 1) {
error("Failed to calculate the correct number of local minima: %d != 1", extrema->pexLocalMin->iNumLocalExtrema);
}
if (extrema->iGlobalMaxPos != 9) {
error("Failed to calculate the correct global maximum position: %d != 9", extrema->iGlobalMaxPos);
}
if (extrema->iGlobalMinPos != 5) {
error("Failed to calculate the correct global minimum position: %d != 4", extrema->iGlobalMinPos);
}
if (extrema->pexLocalMax->piLocalExtremaPos[0] != 1) {
error("Failed to calculate the correct local maximum position: %d != 9", extrema->pexLocalMax->piLocalExtremaPos[0]);
}
if (extrema->pexLocalMin->piLocalExtremaPos[0] != 5) {
error("Failed to calculate the correct local minimum position: %d != 4", extrema->pexLocalMin->piLocalExtremaPos[0]);
}
success("testCalcExtrema");
}
void testInitMMSignalFeatures() {
/*
* Test for Signals of multiple lengths including edge cases.
*/
info("testInitMMSignalFeatures");
// Test for 0 values
info("Test for 0 values");
MMSignal *signal = createSignalWithDefault(0, 0);
initMMSignalFeatures(signal);
if (signal->dArea != 0) {
error("Failed to calculate the correct area: %lf != 0", signal->dArea);
}
if (signal->dMean != 0) {
error("Failed to calculate the correct mean: %lf != 0", signal->dMean);
}
if (signal->dStdDev != 0) {
error("Failed to calculate the correct standard deviation: %lf != 0", signal->dStdDev);
}
if (signal->dMedian != 0) {
error("Failed to calculate the correct median: %lf != 0", signal->dMedian);
}
if (signal->pexExtrema->iGlobalMinPos != 0) {
error("Failed to calculate the correct global minimum position: %d != 0", signal->pexExtrema->iGlobalMinPos);
}
if (signal->pexExtrema->iGlobalMaxPos != 0) {
error("Failed to calculate the correct global maximum position: %d != 0", signal->pexExtrema->iGlobalMaxPos);
}
if (signal->pexExtrema->pexLocalMax->iNumLocalExtrema != 0) {
error("Failed to calculate the correct number of local maxima: %d != 0", signal->pexExtrema->pexLocalMax->iNumLocalExtrema);
}
deleteSignal(signal);
// List of 1 to 10
double pdValuesL[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
signal = createSignalFromDoubleArray(10, pdValuesL);
initMMSignalFeatures(signal);
if (signal->dArea != 55) {
error("Failed to calculate the correct area: %lf != 55", signal->dArea);
}
if (signal->dMean != 5.5) {
error("Failed to calculate the correct mean: %lf != 5.5", signal->dMean);
}
if (round(signal->dStdDev*1e6) != 2.872281e6) {
error("Failed to calculate the correct standard deviation: %lf != 2.872281", signal->dStdDev);
}
if (signal->dMedian != 5.5) {
error("Failed to calculate the correct median: %lf != 5.5", signal->dMedian);
}
if (signal->pexExtrema->iGlobalMinPos != 0) {
error("Failed to calculate the correct global minimum position: %d != 0", signal->pexExtrema->iGlobalMinPos);
}
if (signal->pexExtrema->iGlobalMaxPos != 9) {
error("Failed to calculate the correct global maximum position: %d != 9", signal->pexExtrema->iGlobalMaxPos);
}
if (signal->pexExtrema->pexLocalMax->iNumLocalExtrema != 0) {
error("Failed to calculate the correct number of local maxima: %d != 1", signal->pexExtrema->pexLocalMax->iNumLocalExtrema);
}
deleteSignal(signal);
// Test for 1 value
info("Test for 1 value");
signal = createSignalWithDefault(1, 1);
initMMSignalFeatures(signal);
if (signal->dArea != 1) {
error("Failed to calculate the correct area: %lf != 1", signal->dArea);
}
if (signal->dMean != 1) {
error("Failed to calculate the correct mean: %lf != 1", signal->dMean);
}
if (signal->dStdDev != 0) {
error("Failed to calculate the correct standard deviation: %lf != 0", signal->dStdDev);
}
if (signal->dMedian != 1) {
error("Failed to calculate the correct median: %lf != 1", signal->dMedian);
}
if (signal->pexExtrema->iGlobalMinPos != 0) {
error("Failed to calculate the correct global minimum position: %d != 0", signal->pexExtrema->iGlobalMinPos);
}
if (signal->pexExtrema->iGlobalMaxPos != 0) {
error("Failed to calculate the correct global maximum position: %d != 0", signal->pexExtrema->iGlobalMaxPos);
}
if (signal->pexExtrema->pexLocalMax->iNumLocalExtrema != 0) {
error("Failed to calculate the correct number of local maxima: %d != 1", signal->pexExtrema->pexLocalMax->iNumLocalExtrema);
}
deleteSignal(signal);
// Test for 2 values
info("testInitMMSignalFeatures: 2 values");
double pdValuesT[] = {1, 1};
signal = createSignalFromDoubleArray(2, pdValuesT);
initMMSignalFeatures(signal);
if (signal->dArea != 2) {
error("Failed to calculate the correct area: %lf != 2", signal->dArea);
}
if (signal->dMean != 1) {
error("Failed to calculate the correct mean: %lf != 1", signal->dMean);
}
if (signal->dStdDev != 0) {
error("Failed to calculate the correct standard deviation: %lf != 0", signal->dStdDev);
}
if (signal->dMedian != 1) {
error("Failed to calculate the correct median: %lf != 1", signal->dMedian);
}
if (signal->pexExtrema->iGlobalMinPos != 0) {
error("Failed to calculate the correct global minimum position: %d != 0", signal->pexExtrema->iGlobalMinPos);
}
if (signal->pexExtrema->iGlobalMaxPos != 0) {
error("Failed to calculate the correct global maximum position: %d != 0", signal->pexExtrema->iGlobalMaxPos);
}
if (signal->pexExtrema->pexLocalMax->iNumLocalExtrema != 0) {
error("Failed to calculate the correct number of local maxima: %d != 0", signal->pexExtrema->pexLocalMax->iNumLocalExtrema);
}
deleteSignal(signal);
// Test for 3 values with local maximum
info("testInitMMSignalFeatures: 3 values with local maximum");
double pdValues[] = {1, 2, 1};
signal = createSignalFromDoubleArray(3, pdValues);
initMMSignalFeatures(signal);
if (signal->dArea != 4) {
error("Failed to calculate the correct area: %lf != 4", signal->dArea);
}
if (signal->dMean != 4.0/3.0) {
error("Failed to calculate the correct mean: %lf != 4/3", signal->dMean);
}
if (round(signal->dStdDev*1e6) != 0.471405e6) {
error("Failed to calculate the correct standard deviation: %lf != 0.471405", signal->dStdDev);
}
if (signal->dMedian != 1) {
error("Failed to calculate the correct median: %lf != 1", signal->dMedian);
}
if (signal->pexExtrema->iGlobalMinPos != 0) {
error("Failed to calculate the correct global minimum position: %d != 2", signal->pexExtrema->iGlobalMinPos);
}
if (signal->pexExtrema->iGlobalMaxPos != 1) {
error("Failed to calculate the correct global maximum position: %d != 1", signal->pexExtrema->iGlobalMaxPos);
}
if (signal->pexExtrema->pexLocalMax->iNumLocalExtrema != 1) {
error("Failed to calculate the correct number of local maxima: %d != 1", signal->pexExtrema->pexLocalMax->iNumLocalExtrema);
}
deleteSignal(signal);
// Test for 3 values with local minimum
info("testInitMMSignalFeatures: 3 values with local minimum");
double pdValues2[] = {1, 0, 1};
signal = createSignalFromDoubleArray(3, pdValues2);
initMMSignalFeatures(signal);
if (signal->dArea != 2) {
error("Failed to calculate the correct area: %lf != 2", signal->dArea);
}
if (signal->dMean != 2.0/3.0) {
error("Failed to calculate the correct mean: %lf != 2/3", signal->dMean);
}
if (round(signal->dStdDev*1e6) != 0.471405e6) {
error("Failed to calculate the correct standard deviation: %lf != 0.471405", signal->dStdDev);
}
if (signal->dMedian != 1) {
error("Failed to calculate the correct median: %lf != 1", signal->dMedian);
}
if (signal->pexExtrema->iGlobalMinPos != 1) {
error("Failed to calculate the correct global minimum position: %d != 1", signal->pexExtrema->iGlobalMinPos);
}
if (signal->pexExtrema->iGlobalMaxPos != 0) {
error("Failed to calculate the correct global maximum position: %d != 2", signal->pexExtrema->iGlobalMaxPos);
}
if (signal->pexExtrema->pexLocalMin->iNumLocalExtrema != 1) {
error("Failed to calculate the correct number of local minima: %d != 1", signal->pexExtrema->pexLocalMin->iNumLocalExtrema);
}
deleteSignal(signal);
success("testInitMMSignalFeatures");
}
int eqToNDecimals(double dValueA, double dValueB, int iDecimals) {
return round(dValueA * pow(10, iDecimals)) == round(dValueB * pow(10, iDecimals));
}
void testRescaleDoubleArraySingle(
double *pdValues,
double *pdExpectedValues,
int iNumValues,
double dMin,
double dFactor
) {
double pdOut[10];
rescaleDoubleArray(pdValues, iNumValues, dMin, dFactor, pdOut);
for (int i=0; i<iNumValues; i++) {
if (pdOut[i] != pdExpectedValues[i]) {
error("Failed to rescale the correct value at index %d: %lf != %lf", i, pdOut[i], pdExpectedValues[i]);
}
}
for (int i=1; i<iNumValues; i++) {
if (!eqToNDecimals(pdOut[i] - pdOut[i-1], (pdValues[i] - pdValues[i-1]) * dFactor, 6)) {
error("Failed scaling at index %d->%d: %lf != %lf", i-1, i, pdOut[i] - pdOut[i-1], (pdValues[i] - pdValues[i-1]) * dFactor);
}
}
int minIndex = 0;
for (int i=1; i<iNumValues; i++) {
if (pdOut[i] < pdOut[minIndex]) {
minIndex = i;
}
}
if (pdOut[minIndex] != dMin) {
error("Failed to rescale the minimum value: %lf != %lf", pdOut[minIndex], dMin);
}
success("testRescaleDoubleArraySingle");
}
void testRescaleDoubleArray() {
// void rescaleDoubleArray(double *pdIn, int iLen, double dMin, double dFactor, double *pdOut);
/* Rescales an array of double values so that the minimum value is dMin and
* the difference between any two values is scaled by dFactor.
* The result is stored in pdOut.
*/
info("testRescaleDoubleArray");
double pdValues[] = {17, 4, -8, 0, 3, 5, 2, 1, 9, 6};
double pdOut[10];
double pdExpectedValues[] = {50, 24, 0, 16, 22, 26, 20, 18, 34, 28};
testRescaleDoubleArraySingle(pdValues, pdExpectedValues, 10, 0, 2);
double pdExpectedValues2[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
testRescaleDoubleArraySingle(pdValues, pdExpectedValues2, 10, 0, 0);
double pdExpectedValues3[] = {12.5, 6, 0, 4, 5.5, 6.5, 5, 4.5, 8.5, 7};
testRescaleDoubleArraySingle(pdValues, pdExpectedValues3, 10, 0, 0.5);
double pdExpectedValues4[] = {22.5, 16, 10, 14, 15.5, 16.5, 15, 14.5, 18.5, 17};
testRescaleDoubleArraySingle(pdValues, pdExpectedValues4, 10, 10, 0.5);
double pdValues2[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
double pdExpectedValues2_4[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
testRescaleDoubleArraySingle(pdValues2, pdExpectedValues2_4, 10, 0, 1);
double pdExpectedValues2_5[] = {0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5};
testRescaleDoubleArraySingle(pdValues2, pdExpectedValues2_5, 10, 0, 0.5);
// 1 element
double pdValues3[] = {1};
double pdExpectedValues3_1[] = {0};
testRescaleDoubleArraySingle(pdValues3, pdExpectedValues3_1, 1, 0, 1);
double pdExpectedValues3_2[] = {5};
testRescaleDoubleArraySingle(pdValues3, pdExpectedValues3_2, 1, 5, 1);
double pdExpectedValues3_3[] = {5};
testRescaleDoubleArraySingle(pdValues3, pdExpectedValues3_3, 1, 5, 0);
// 2 elements
double pdValues4[] = {1, 2};
double pdExpectedValues4_1[] = {0, 1};
testRescaleDoubleArraySingle(pdValues4, pdExpectedValues4_1, 2, 0, 1);
double pdExpectedValues4_2[] = {0, 5};
testRescaleDoubleArraySingle(pdValues4, pdExpectedValues4_2, 2, 0, 5);
success("testRescaleDoubleArray");
}
int main (int iArgC, char** ppcArgV){
testInterpolation();
testSineAndReadWriteDoubleArray();
testCreateSignalWithDefault();
testCreateSignalFromDoubleArray();
testCreateSignalFromFile();
testWriteMMSignal();
testCalculateArea();
testCalculateMean();
testCalculateStdDev();
testCalculateMedian();
testCalculateEntropy();
testConvoluteSignals();
testGetPascalLine();
testComputeDFT();
testConvertCart2Polar();
testConvertPolar2Cart();
testApplyPascalConvForSeriesGT40();
testCalcExtrema();
testInitMMSignalFeatures();
testRescaleDoubleArray();
return 0;
}