// // Created by frederik on 1/11/25. // #include "MMS24-25.h" #include #include #include #include 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 (%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; iiNumValues != 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 != 6) { error("Failed to calculate the correct median: %lf != 5.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 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"); } int main (int iArgC, char** ppcArgV){ testInterpolation(); testSineAndReadWriteDoubleArray(); testCreateSignalWithDefault(); testCreateSignalFromDoubleArray(); testCreateSignalFromFile(); testWriteMMSignal(); testCalculateArea(); testCalculateMean(); testCalculateStdDev(); testCalculateMedian(); testCalculateEntropy(); testConvoluteSignals(); testGetPascalLine(); testComputeDFT(); testConvertCart2Polar(); testConvertPolar2Cart(); return 0; }