All but DFT confirmed
This commit is contained in:
parent
5b65a43431
commit
f1783f7ce8
365
MMS24-25.c
365
MMS24-25.c
@ -11,17 +11,16 @@
|
|||||||
* https://git.beimgraben.net/MMS-2024-25/MMS-Loesung-2024-25.git
|
* https://git.beimgraben.net/MMS-2024-25/MMS-Loesung-2024-25.git
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "MMS24-25.h"
|
|
||||||
#include "math.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "MMS24-25.h"
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "MMS24-25.h"
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
// #region Error Handling and Debugging
|
// #region Error Handling and Debugging
|
||||||
void _error(char *fmt, ...) {
|
void _error(char *fmt, ...) {
|
||||||
fprintf(stderr, "<\x1B[31;1m ERROR \x1B[0m: \x1B[34m'");
|
fprintf(stderr, "< \x1B[31;4;1mERROR\x1B[0m : \x1B[34m'");
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
@ -36,7 +35,7 @@ void _error(char *fmt, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _debug(char *fmt, ...) {
|
void _debug(char *fmt, ...) {
|
||||||
fprintf(stderr, "[\x1B[31;1m DEBUG \x1B[0m] \x1B[34m'");
|
fprintf(stderr, "[ \x1B[37;4;1mDEBUG\x1B[0m ] \x1B[34m'");
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
@ -47,7 +46,7 @@ void _debug(char *fmt, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _warn(char *fmt, ...) {
|
void _warn(char *fmt, ...) {
|
||||||
fprintf(stderr, "[\x1B[33;1m WARN \x1B[0m] \x1B[34m'");
|
fprintf(stderr, "[ \x1B[33;4;1mWARN\x1B[0m ] \x1B[34m'");
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
@ -69,9 +68,9 @@ double interpolateLine(
|
|||||||
if (dX2 == dX1)
|
if (dX2 == dX1)
|
||||||
_error("interpolateLine: dX1 and dX2 must differ!");
|
_error("interpolateLine: dX1 and dX2 must differ!");
|
||||||
|
|
||||||
double y = dY1 *(
|
double y = dY1 * (
|
||||||
(dX2 - dXq) / (dX2 - dX1)
|
(dX2 - dXq) / (dX2 - dX1)
|
||||||
) + dY2 *(
|
) + dY2 * (
|
||||||
(dXq - dX1) / (dX2 - dX1)
|
(dXq - dX1) / (dX2 - dX1)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -99,8 +98,19 @@ void rescaleDoubleArray(
|
|||||||
* which naturally results from:
|
* which naturally results from:
|
||||||
* $ pdOut_i = pdIn_i *dFactor + dMin $
|
* $ pdOut_i = pdIn_i *dFactor + dMin $
|
||||||
*/
|
*/
|
||||||
|
// First find the old minimum
|
||||||
|
double dOldMin = pdIn[0];
|
||||||
|
for (int i = 1; i < iLen; i++) {
|
||||||
|
if (pdIn[i] < dOldMin)
|
||||||
|
dOldMin = pdIn[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the offset
|
||||||
|
double dOffset = dMin - dOldMin;
|
||||||
|
|
||||||
|
// Rescale the array
|
||||||
for (int i = 0; i < iLen; i++) {
|
for (int i = 0; i < iLen; i++) {
|
||||||
pdOut[i] = pdIn[i] *dFactor + dMin;
|
pdOut[i] = pdIn[i] * dFactor + dOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,13 +139,13 @@ double *generateSineValues(
|
|||||||
|
|
||||||
// Initialize the output array
|
// Initialize the output array
|
||||||
double *sineArray = NULL;
|
double *sineArray = NULL;
|
||||||
sineArray = (double*) malloc(sizeof(double) *iNumValues);
|
sineArray = (double*) malloc(sizeof(double) * iNumValues);
|
||||||
|
|
||||||
if (sineArray == NULL)
|
if (sineArray == NULL)
|
||||||
_error("*generateSineValues: Failed to allocate memory for Sine Array\n");
|
_error("*generateSineValues: Failed to allocate memory for Sine Array\n");
|
||||||
|
|
||||||
for (int i=0; i<iNumValues;i++){
|
for (int i=0; i<iNumValues;i++){
|
||||||
sineArray[i] = dAmp*sin(((2*M_PI)/iNumSamplesPerPeriod) *i);
|
sineArray[i] = dAmp * sin(((2*M_PI)/iNumSamplesPerPeriod) * i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sineArray;
|
return sineArray;
|
||||||
@ -147,6 +157,12 @@ void writeDoubleArray(double *pdOut, int iLen, char *pcOutName) {
|
|||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
_error("writeDoubleArray: Error while opening file '%s'.\n", pcOutName);
|
_error("writeDoubleArray: Error while opening file '%s'.\n", pcOutName);
|
||||||
|
|
||||||
|
if (pdOut == NULL)
|
||||||
|
_error("writeDoubleArray: pdOut is NULL\n");
|
||||||
|
|
||||||
|
if (iLen == 0)
|
||||||
|
_warn("writeDoubleArray: iLen is 0\n");
|
||||||
|
|
||||||
for (int i = 0; i < iLen; i++) {
|
for (int i = 0; i < iLen; i++) {
|
||||||
fprintf(file, "%f\n", pdOut[i]);
|
fprintf(file, "%f\n", pdOut[i]);
|
||||||
}
|
}
|
||||||
@ -204,16 +220,58 @@ MMSignal *createSignal() {
|
|||||||
return signal;
|
return signal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalExtrema* copyLocalExtrema(LocalExtrema *pexIn) {
|
||||||
|
if (pexIn == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
LocalExtrema *localExtrema = (LocalExtrema*) malloc(sizeof(LocalExtrema));
|
||||||
|
if (localExtrema == NULL)
|
||||||
|
_error("copyLocalExtrema: Failed to allocate memory for localExtrema\n");
|
||||||
|
|
||||||
|
localExtrema->iNumLocalExtrema = pexIn->iNumLocalExtrema;
|
||||||
|
localExtrema->piLocalExtremaPos = (int*) malloc(sizeof(int) *pexIn->iNumLocalExtrema);
|
||||||
|
if (localExtrema->piLocalExtremaPos == NULL)
|
||||||
|
_error("copyLocalExtrema: Failed to allocate memory for localExtrema->piLocalExtremaPos\n");
|
||||||
|
|
||||||
|
for (int i = 0; i < pexIn->iNumLocalExtrema; i++) {
|
||||||
|
localExtrema->piLocalExtremaPos[i] = pexIn->piLocalExtremaPos[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return localExtrema;
|
||||||
|
}
|
||||||
|
|
||||||
|
Extrema* copyExtrema(Extrema *pexIn) {
|
||||||
|
if (pexIn == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
Extrema *extrema = (Extrema*) malloc(sizeof(Extrema));
|
||||||
|
if (extrema == NULL)
|
||||||
|
_error("copyExtrema: Failed to allocate memory for extrema\n");
|
||||||
|
|
||||||
|
extrema->iGlobalMinPos = pexIn->iGlobalMinPos;
|
||||||
|
extrema->iGlobalMaxPos = pexIn->iGlobalMaxPos;
|
||||||
|
|
||||||
|
extrema->pexLocalMax = copyLocalExtrema(pexIn->pexLocalMax);
|
||||||
|
extrema->pexLocalMin = copyLocalExtrema(pexIn->pexLocalMin);
|
||||||
|
|
||||||
|
return extrema;
|
||||||
|
}
|
||||||
|
|
||||||
MMSignal *createSignalFromSignal(MMSignal *pmmsIn) {
|
MMSignal *createSignalFromSignal(MMSignal *pmmsIn) {
|
||||||
MMSignal *signal = createSignal();
|
MMSignal *signal = createSignal();
|
||||||
|
|
||||||
// Initialize and copy the values (deep copy)
|
if (pmmsIn->pdValues != NULL) {
|
||||||
signal->pdValues = (double*) malloc(sizeof(double) *pmmsIn->iNumValues);
|
// Initialize and copy the values (deep copy)
|
||||||
if (signal->pdValues == NULL)
|
signal->pdValues = (double*) malloc(sizeof(double) *pmmsIn->iNumValues);
|
||||||
_error("createSignalFromSignal: Failed to allocate memory for signal->pdValues\n");
|
if (signal->pdValues == NULL)
|
||||||
|
_error("createSignalFromSignal: Failed to allocate memory for signal->pdValues\n");
|
||||||
|
|
||||||
for (int i = 0; i < pmmsIn->iNumValues; i++) {
|
for (int i = 0; i < pmmsIn->iNumValues; i++) {
|
||||||
signal->pdValues[i] = pmmsIn->pdValues[i];
|
signal->pdValues[i] = pmmsIn->pdValues[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_warn("createSignalFromSignal: pmmsIn->pdValues is NULL\n");
|
||||||
|
signal->pdValues = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy shallow items
|
// Copy shallow items
|
||||||
@ -224,38 +282,13 @@ MMSignal *createSignalFromSignal(MMSignal *pmmsIn) {
|
|||||||
signal->dMedian = pmmsIn->dMedian;
|
signal->dMedian = pmmsIn->dMedian;
|
||||||
|
|
||||||
// Deep copy of Extrema
|
// Deep copy of Extrema
|
||||||
signal->pexExtrema = (Extrema*) malloc(sizeof(Extrema));
|
if (pmmsIn->pexExtrema == NULL) {
|
||||||
if (signal->pexExtrema == NULL)
|
_warn("createSignalFromSignal: pmmsIn->pexExtrema is NULL\n");
|
||||||
_error("createSignalFromSignal: Failed to allocate memory for signal->pexExtrema\n");
|
signal->pexExtrema = NULL;
|
||||||
|
return signal;
|
||||||
signal->pexExtrema->iGlobalMinPos = pmmsIn->pexExtrema->iGlobalMinPos;
|
|
||||||
signal->pexExtrema->iGlobalMaxPos = pmmsIn->pexExtrema->iGlobalMaxPos;
|
|
||||||
|
|
||||||
signal->pexExtrema->pexLocalMax = (LocalExtrema*) malloc(sizeof(LocalExtrema));
|
|
||||||
if (signal->pexExtrema->pexLocalMax == NULL)
|
|
||||||
_error("createSignalFromSignal: Failed to allocate memory for signal->pexExtrema->pexLocalMax\n");
|
|
||||||
|
|
||||||
signal->pexExtrema->pexLocalMax->iNumLocalExtrema = pmmsIn->pexExtrema->pexLocalMax->iNumLocalExtrema;
|
|
||||||
signal->pexExtrema->pexLocalMax->piLocalExtremaPos = (int*) malloc(sizeof(int) *pmmsIn->pexExtrema->pexLocalMax->iNumLocalExtrema);
|
|
||||||
if (signal->pexExtrema->pexLocalMax->piLocalExtremaPos == NULL)
|
|
||||||
_error("createSignalFromSignal: Failed to allocate memory for signal->pexExtrema->pexLocalMax->piLocalExtremaPos\n");
|
|
||||||
|
|
||||||
for (int i = 0; i < pmmsIn->pexExtrema->pexLocalMax->iNumLocalExtrema; i++) {
|
|
||||||
signal->pexExtrema->pexLocalMax->piLocalExtremaPos[i] = pmmsIn->pexExtrema->pexLocalMax->piLocalExtremaPos[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
signal->pexExtrema->pexLocalMin = (LocalExtrema*) malloc(sizeof(LocalExtrema));
|
signal->pexExtrema = copyExtrema(pmmsIn->pexExtrema);
|
||||||
if (signal->pexExtrema->pexLocalMin == NULL)
|
|
||||||
_error("createSignalFromSignal: Failed to allocate memory for signal->pexExtrema->pexLocalMin\n");
|
|
||||||
|
|
||||||
signal->pexExtrema->pexLocalMin->iNumLocalExtrema = pmmsIn->pexExtrema->pexLocalMin->iNumLocalExtrema;
|
|
||||||
signal->pexExtrema->pexLocalMin->piLocalExtremaPos = (int*) malloc(sizeof(int) *pmmsIn->pexExtrema->pexLocalMin->iNumLocalExtrema);
|
|
||||||
if (signal->pexExtrema->pexLocalMin->piLocalExtremaPos == NULL)
|
|
||||||
_error("createSignalFromSignal: Failed to allocate memory for signal->pexExtrema->pexLocalMin->piLocalExtremaPos\n");
|
|
||||||
|
|
||||||
for (int i = 0; i < pmmsIn->pexExtrema->pexLocalMin->iNumLocalExtrema; i++) {
|
|
||||||
signal->pexExtrema->pexLocalMin->piLocalExtremaPos[i] = pmmsIn->pexExtrema->pexLocalMin->piLocalExtremaPos[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return signal;
|
return signal;
|
||||||
}
|
}
|
||||||
@ -312,6 +345,9 @@ MMSignal *createSignalFromFile(char *pcInName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void writeMMSignal(char *pcInName, MMSignal *pmmsIn) {
|
void writeMMSignal(char *pcInName, MMSignal *pmmsIn) {
|
||||||
|
if (pmmsIn->pdValues == NULL)
|
||||||
|
_error("writeMMSignal: pmmsIn->pdValues is NULL\n");
|
||||||
|
|
||||||
writeDoubleArray(
|
writeDoubleArray(
|
||||||
pmmsIn->pdValues,
|
pmmsIn->pdValues,
|
||||||
pmmsIn->iNumValues,
|
pmmsIn->iNumValues,
|
||||||
@ -319,13 +355,32 @@ void writeMMSignal(char *pcInName, MMSignal *pmmsIn) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void deleteLocalExtrema(LocalExtrema *pexIn) {
|
||||||
|
if (pexIn == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
free(pexIn->piLocalExtremaPos);
|
||||||
|
free(pexIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteExtrema(Extrema *pexIn) {
|
||||||
|
if (pexIn == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
deleteLocalExtrema(pexIn->pexLocalMax);
|
||||||
|
deleteLocalExtrema(pexIn->pexLocalMin);
|
||||||
|
free(pexIn);
|
||||||
|
}
|
||||||
|
|
||||||
void deleteSignal(MMSignal *pmmsIn) {
|
void deleteSignal(MMSignal *pmmsIn) {
|
||||||
free(pmmsIn->pdValues);
|
if (pmmsIn == NULL)
|
||||||
free(pmmsIn->pexExtrema->pexLocalMax->piLocalExtremaPos);
|
return;
|
||||||
free(pmmsIn->pexExtrema->pexLocalMax);
|
|
||||||
free(pmmsIn->pexExtrema->pexLocalMin->piLocalExtremaPos);
|
if (pmmsIn->pdValues != NULL)
|
||||||
free(pmmsIn->pexExtrema->pexLocalMin);
|
free(pmmsIn->pdValues);
|
||||||
free(pmmsIn->pexExtrema);
|
|
||||||
|
deleteExtrema(pmmsIn->pexExtrema);
|
||||||
|
|
||||||
free(pmmsIn);
|
free(pmmsIn);
|
||||||
}
|
}
|
||||||
// #endregion
|
// #endregion
|
||||||
@ -335,24 +390,31 @@ double calculateArea(double *pdIn, int iLen) {
|
|||||||
double area = 0;
|
double area = 0;
|
||||||
|
|
||||||
// #FIXME: Which one should we use according to the task?
|
// #FIXME: Which one should we use according to the task?
|
||||||
for (int i = 0; i < iLen-1; i++) {
|
for (int i = 0; i < iLen; i++) {
|
||||||
area += (pdIn[i] + pdIn[i+1]) / 2;
|
/* Alternative would be:
|
||||||
|
* area += (pdIn[i] + pdIn[i+1]) / 2;
|
||||||
|
* with i < iLen-1
|
||||||
|
* Which one to use is up to the implemention.
|
||||||
|
*/
|
||||||
|
area += pdIn[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
|
||||||
double calculateMean(double *pdIn, int iLen) {
|
double calculateMean(double *pdIn, int iLen) {
|
||||||
double mean = 0;
|
/* Here the above defined function `calculateArea` is used to calculate the mean, since:
|
||||||
|
* \[ mean(pdIn) = \frac{1}{ |pdIn| } \sum_{i=1}^{ |pdIn| } x_i
|
||||||
for (int i = 0; i < iLen; i++) {
|
* = \frac{area(x)}{ |pdIn| } \]
|
||||||
mean += pdIn[i];
|
*/
|
||||||
}
|
return calculateArea(pdIn, iLen) / iLen;
|
||||||
|
|
||||||
return mean / iLen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double calculateStddev(double *pdIn, int iLen) {
|
double calculateStddev(double *pdIn, int iLen) {
|
||||||
|
/* The standard deviation is calculated as follows:
|
||||||
|
* \[ stddev(pdIn) = \sqrt{ \frac{1}{ |pdIn| } \sum_{i=1}^{ |pdIn| } (x_i - mean(pdIn))^2 } \]
|
||||||
|
*/
|
||||||
|
|
||||||
double mean = calculateMean(pdIn, iLen);
|
double mean = calculateMean(pdIn, iLen);
|
||||||
double stdDev = 0;
|
double stdDev = 0;
|
||||||
|
|
||||||
@ -363,26 +425,41 @@ double calculateStddev(double *pdIn, int iLen) {
|
|||||||
return sqrt(stdDev / iLen);
|
return sqrt(stdDev / iLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double calculateMedian(double *pdIn, int iLen) {
|
||||||
|
/* The median is calculated as follows:
|
||||||
|
* \[ median(pdIn) = \begin{cases}
|
||||||
|
* pdIn_{\frac{|pdIn|}{2}} & \text{if } |pdIn| \text{ is even} \\
|
||||||
|
* \frac{pdIn_{\frac{|pdIn|}{2}} + pdIn_{\frac{|pdIn|}{2}+1}}{2} & \text{if } |pdIn| \text{ is odd}
|
||||||
|
* \end{cases} \]
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (iLen % 2 == 0) {
|
||||||
|
return pdIn[iLen/2];
|
||||||
|
} else {
|
||||||
|
return (pdIn[iLen/2] + pdIn[iLen/2+1]) / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalExtrema *initLocalExtrema(int iLen) {
|
||||||
|
LocalExtrema *localExtrema = (LocalExtrema*) malloc(sizeof(LocalExtrema));
|
||||||
|
if (localExtrema == NULL)
|
||||||
|
_error("initLocalExtrema: Failed to allocate memory for localExtrema\n");
|
||||||
|
|
||||||
|
localExtrema->iNumLocalExtrema = 0;
|
||||||
|
localExtrema->piLocalExtremaPos = (int*) malloc(sizeof(int) *iLen);
|
||||||
|
if (localExtrema->piLocalExtremaPos == NULL)
|
||||||
|
_error("initLocalExtrema: Failed to allocate memory for localExtrema->piLocalExtremaPos\n");
|
||||||
|
|
||||||
|
return localExtrema;
|
||||||
|
}
|
||||||
|
|
||||||
Extrema *initExtrema(double *pdIn, int iLen) {
|
Extrema *initExtrema(double *pdIn, int iLen) {
|
||||||
Extrema *extrema = (Extrema*) malloc(sizeof(Extrema));
|
Extrema *extrema = (Extrema*) malloc(sizeof(Extrema));
|
||||||
if (extrema == NULL)
|
if (extrema == NULL)
|
||||||
_error("initExtrema: Failed to allocate memory for extrema\n");
|
_error("initExtrema: Failed to allocate memory for extrema\n");
|
||||||
|
|
||||||
extrema->pexLocalMax = (LocalExtrema*) malloc(sizeof(LocalExtrema));
|
extrema->pexLocalMax = initLocalExtrema(iLen);
|
||||||
if (extrema->pexLocalMax == NULL)
|
extrema->pexLocalMin = initLocalExtrema(iLen);
|
||||||
_error("initExtrema: Failed to allocate memory for extrema->pexLocalMax\n");
|
|
||||||
|
|
||||||
extrema->pexLocalMin = (LocalExtrema*) malloc(sizeof(LocalExtrema));
|
|
||||||
if (extrema->pexLocalMin == NULL)
|
|
||||||
_error("initExtrema: Failed to allocate memory for extrema->pexLocalMin\n");
|
|
||||||
|
|
||||||
extrema->pexLocalMax->piLocalExtremaPos = (int*) malloc(sizeof(int) *iLen);
|
|
||||||
if (extrema->pexLocalMax->piLocalExtremaPos == NULL)
|
|
||||||
_error("initExtrema: Failed to allocate memory for extrema->pexLocalMax->piLocalExtremaPos\n");
|
|
||||||
|
|
||||||
extrema->pexLocalMin->piLocalExtremaPos = (int*) malloc(sizeof(int) *iLen);
|
|
||||||
if (extrema->pexLocalMin->piLocalExtremaPos == NULL)
|
|
||||||
_error("initExtrema: Failed to allocate memory for extrema->pexLocalMin->piLocalExtremaPos\n");
|
|
||||||
|
|
||||||
extrema->iGlobalMaxPos = 0;
|
extrema->iGlobalMaxPos = 0;
|
||||||
extrema->iGlobalMinPos = 0;
|
extrema->iGlobalMinPos = 0;
|
||||||
@ -390,14 +467,6 @@ Extrema *initExtrema(double *pdIn, int iLen) {
|
|||||||
return extrema;
|
return extrema;
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteExtrema(Extrema *pexIn) {
|
|
||||||
free(pexIn->pexLocalMax->piLocalExtremaPos);
|
|
||||||
free(pexIn->pexLocalMax);
|
|
||||||
free(pexIn->pexLocalMin->piLocalExtremaPos);
|
|
||||||
free(pexIn->pexLocalMin);
|
|
||||||
free(pexIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void initMMSignalFeatures(MMSignal *pmmsIn) {
|
void initMMSignalFeatures(MMSignal *pmmsIn) {
|
||||||
pmmsIn->dArea = 0;
|
pmmsIn->dArea = 0;
|
||||||
pmmsIn->dMean = 0;
|
pmmsIn->dMean = 0;
|
||||||
@ -409,7 +478,13 @@ void initMMSignalFeatures(MMSignal *pmmsIn) {
|
|||||||
Histogram *initHistogram(double *pdIn, int iLen, int iNumBins) {
|
Histogram *initHistogram(double *pdIn, int iLen, int iNumBins) {
|
||||||
Histogram *histogram = (Histogram*) malloc(sizeof(Histogram));
|
Histogram *histogram = (Histogram*) malloc(sizeof(Histogram));
|
||||||
if (histogram == NULL)
|
if (histogram == NULL)
|
||||||
_error("initHistogram: Failed to allocate memory for histogram\n");
|
_error("initHistogram: Failed to allocate memory for histogram");
|
||||||
|
|
||||||
|
if (iNumBins == 0)
|
||||||
|
_error("initHistogram: iNumBins must be non-0");
|
||||||
|
|
||||||
|
if (iLen == 0)
|
||||||
|
_warn("initHistogram: iLen is 0\n");
|
||||||
|
|
||||||
histogram->dIntervalMin = pdIn[0];
|
histogram->dIntervalMin = pdIn[0];
|
||||||
histogram->dIntervalMax = pdIn[0];
|
histogram->dIntervalMax = pdIn[0];
|
||||||
@ -420,26 +495,61 @@ Histogram *initHistogram(double *pdIn, int iLen, int iNumBins) {
|
|||||||
histogram->dIntervalMax = pdIn[i];
|
histogram->dIntervalMax = pdIn[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG_
|
||||||
|
_debug("initHistogram: histogram->dIntervalMin = %lf", histogram->dIntervalMin);
|
||||||
|
_debug("initHistogram: histogram->dIntervalMax = %lf", histogram->dIntervalMax);
|
||||||
|
#endif
|
||||||
|
|
||||||
histogram->dBinWidth = (histogram->dIntervalMax - histogram->dIntervalMin) / iNumBins;
|
histogram->dBinWidth = (histogram->dIntervalMax - histogram->dIntervalMin) / iNumBins;
|
||||||
histogram->iNumBins = iNumBins;
|
histogram->iNumBins = iNumBins;
|
||||||
|
|
||||||
|
#ifdef _DEBUG_
|
||||||
|
_debug("initHistogram: histogram->dBinWidth = %lf", histogram->dBinWidth);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (histogram->dBinWidth == 0)
|
||||||
|
histogram->dBinWidth = 1;
|
||||||
|
|
||||||
histogram->pdBinValues = (double*) malloc(sizeof(double) *iNumBins);
|
histogram->pdBinValues = (double*) malloc(sizeof(double) *iNumBins);
|
||||||
if (histogram->pdBinValues == NULL)
|
if (histogram->pdBinValues == NULL)
|
||||||
_error("initHistogram: Failed to allocate memory for histogram->pdBinValues\n");
|
_error("initHistogram: Failed to allocate memory for histogram->pdBinValues");
|
||||||
|
|
||||||
for (int i = 0; i < iNumBins; i++) {
|
for (int i = 0; i < iNumBins; i++) {
|
||||||
histogram->pdBinValues[i] = 0;
|
histogram->pdBinValues[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < iLen; i++) {
|
||||||
|
int bin = floor((pdIn[i] - histogram->dIntervalMin) / histogram->dBinWidth);
|
||||||
|
if (bin == iNumBins)
|
||||||
|
bin--;
|
||||||
|
|
||||||
|
histogram->pdBinValues[bin]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < iNumBins; i++) {
|
||||||
|
histogram->pdBinValues[i] /= iLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG_
|
||||||
|
// DEBUG: print the parameters and result
|
||||||
|
_debug("initHistogram(%lf, %lf, %lf, %d)",
|
||||||
|
histogram->dIntervalMin,histogram->dIntervalMax,histogram->dBinWidth,histogram->iNumBins);
|
||||||
|
for (int i = 0; i < histogram->iNumBins; i++) {
|
||||||
|
_debug("initHistogram: histogram->pdBinValues[%d] = %lf", i, histogram->pdBinValues[i]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return histogram;
|
return histogram;
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteHistogram(Histogram *phIn) {
|
void deleteHistogram(Histogram *phIn) {
|
||||||
|
if (phIn == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
free(phIn->pdBinValues);
|
free(phIn->pdBinValues);
|
||||||
free(phIn);
|
free(phIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #FIXME: Check if this checks out
|
|
||||||
double calculateEntropy(Histogram *phisIn) {
|
double calculateEntropy(Histogram *phisIn) {
|
||||||
double entropy = 0;
|
double entropy = 0;
|
||||||
|
|
||||||
@ -457,40 +567,49 @@ double calculateEntropy(Histogram *phisIn) {
|
|||||||
// #region Aufgabe 3
|
// #region Aufgabe 3
|
||||||
|
|
||||||
MMSignal *convoluteSignals(MMSignal *pmmsInA, MMSignal *pmmsInB) {
|
MMSignal *convoluteSignals(MMSignal *pmmsInA, MMSignal *pmmsInB) {
|
||||||
MMSignal *signal = createSignal();
|
// Calculate output length
|
||||||
|
int iOutLen = pmmsInA->iNumValues + pmmsInB->iNumValues - 1;
|
||||||
|
|
||||||
if (pmmsInA->iNumValues != pmmsInB->iNumValues)
|
double *pdOut = (double*) malloc(sizeof(double) *iOutLen);
|
||||||
_error("convoluteSignals: Signals must have the same length\n");
|
if (pdOut == NULL)
|
||||||
|
_error("convoluteSignals: Failed to allocate memory for pdOut\n");
|
||||||
|
|
||||||
signal->pdValues = (double*) malloc(sizeof(double) *pmmsInA->iNumValues);
|
for (int i = 0; i < iOutLen; i++) {
|
||||||
if (signal->pdValues == NULL)
|
pdOut[i] = 0;
|
||||||
_error("convoluteSignals: Failed to allocate memory for signal->pdValues\n");
|
|
||||||
|
|
||||||
for (int i = 0; i < pmmsInA->iNumValues; i++) {
|
|
||||||
signal->pdValues[i] = pmmsInA->pdValues[i] * pmmsInB->pdValues[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
signal->iNumValues = pmmsInA->iNumValues;
|
for (int i = 0; i < pmmsInA->iNumValues; i++) {
|
||||||
|
for (int j = 0; j < pmmsInB->iNumValues; j++) {
|
||||||
|
pdOut[i+j] += pmmsInA->pdValues[i] * pmmsInB->pdValues[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MMSignal *signal = createSignalFromDoubleArray(iOutLen, pdOut);
|
||||||
|
initMMSignalFeatures(signal);
|
||||||
|
|
||||||
return signal;
|
return signal;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #FIXME: Check if this checks out
|
// #FIXME: Check if this checks out
|
||||||
MMSignal *getPascalLine(int iLinenum) {
|
MMSignal *getPascalLine(int iLinenum) {
|
||||||
MMSignal *signal = createSignal();
|
if (iLinenum <= 0)
|
||||||
|
_error("getPascalLine: iLinenum must be greater than 0\n");
|
||||||
|
|
||||||
signal->pdValues = (double*) malloc(sizeof(double) *iLinenum);
|
// Calculate a kernel signal using pascales triangle without using the factorial
|
||||||
if (signal->pdValues == NULL)
|
double *pdValues = NULL;
|
||||||
_error("getPascalLine: Failed to allocate memory for signal->pdValues\n");
|
pdValues = (double*) malloc(sizeof(double) * iLinenum);
|
||||||
|
if (pdValues == NULL)
|
||||||
|
_error("getPascalLine: Failed to allocate memory for pdValues\n");
|
||||||
|
|
||||||
signal->pdValues[0] = 1;
|
for (int i = 0; i < iLinenum; i++) {
|
||||||
signal->pdValues[iLinenum-1] = 1;
|
pdValues[i] = 1;
|
||||||
|
for (int j = i-1; j > 0; j--) {
|
||||||
for (int i = 1; i < iLinenum-1; i++) {
|
pdValues[j] = pdValues[j] + pdValues[j-1];
|
||||||
signal->pdValues[i] = signal->pdValues[i-1] *(iLinenum-i) / i;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signal->iNumValues = iLinenum;
|
MMSignal *signal = createSignalFromDoubleArray(iLinenum, pdValues);
|
||||||
|
initMMSignalFeatures(signal);
|
||||||
|
|
||||||
return signal;
|
return signal;
|
||||||
}
|
}
|
||||||
@ -498,10 +617,12 @@ MMSignal *getPascalLine(int iLinenum) {
|
|||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
// #region Aufgabe 4
|
// #region Aufgabe 4
|
||||||
void computeDFT(int iLen,
|
void computeDFT(
|
||||||
double *pdRealIn, double *pdImgIn,
|
int iLen,
|
||||||
double *pdRealOut, double *pdImgOut,
|
double *pdRealIn, double *pdImgIn,
|
||||||
int iDirection /*-1,1*/) {
|
double *pdRealOut, double *pdImgOut,
|
||||||
|
int iDirection
|
||||||
|
) {
|
||||||
// Check the value of iDirection
|
// Check the value of iDirection
|
||||||
if (iDirection != -1 && iDirection != 1)
|
if (iDirection != -1 && iDirection != 1)
|
||||||
_error("computeDFT: iDirection must be either -1 or 1\n");
|
_error("computeDFT: iDirection must be either -1 or 1\n");
|
||||||
@ -509,9 +630,21 @@ void computeDFT(int iLen,
|
|||||||
for (int k = 0; k < iLen; k++) {
|
for (int k = 0; k < iLen; k++) {
|
||||||
pdRealOut[k] = 0;
|
pdRealOut[k] = 0;
|
||||||
pdImgOut[k] = 0;
|
pdImgOut[k] = 0;
|
||||||
|
|
||||||
|
// Compute the sum for the k-th output element
|
||||||
for (int n = 0; n < iLen; n++) {
|
for (int n = 0; n < iLen; n++) {
|
||||||
pdRealOut[k] += pdRealIn[n] * cos(2*M_PI *k *n / iLen) + iDirection * pdImgIn[n] * sin(2*M_PI *k *n / iLen);
|
double angle = iDirection * 2.0 * M_PI * k * n / iLen;
|
||||||
pdImgOut[k] += -iDirection * pdRealIn[n] * sin(2*M_PI *k *n / iLen) + pdImgIn[n] * cos(2*M_PI *k *n / iLen);
|
double cosTerm = cos(angle);
|
||||||
|
double sinTerm = sin(angle);
|
||||||
|
|
||||||
|
pdRealOut[k] += pdRealIn[n] * cosTerm - pdImgIn[n] * sinTerm;
|
||||||
|
pdImgOut[k] += pdRealIn[n] * sinTerm + pdImgIn[n] * cosTerm;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize the output
|
||||||
|
if (iDirection == -1) {
|
||||||
|
pdRealOut[k] /= iLen;
|
||||||
|
pdImgOut[k] /= iLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -91,6 +91,6 @@ void computeDFT(int iLen,
|
|||||||
double *pdRealIn, double *pdImgIn,
|
double *pdRealIn, double *pdImgIn,
|
||||||
double *pdRealOut, double *pdImgOut,
|
double *pdRealOut, double *pdImgOut,
|
||||||
int iDirection /*-1,1*/);
|
int iDirection /*-1,1*/);
|
||||||
void convertCart2Polar(double *pdRealIn, double *pdImgIn,double *pdRadiusOut, double *pdAngleOut, int iLen);
|
void convertCart2Polar(double *pdRealIn, double *pdImgIn, double *pdRadiusOut, double *pdAngleOut, int iLen);
|
||||||
void convertPolar2Cart(double *pdRadiusIn, double *pdAngleIn, double *pdRealOut, double *pdImgOut,int iLen);
|
void convertPolar2Cart(double *pdRadiusIn, double *pdAngleIn, double *pdRealOut, double *pdImgOut, int iLen);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
2
Makefile
2
Makefile
@ -1,6 +1,6 @@
|
|||||||
CC=gcc
|
CC=gcc
|
||||||
SOURCE_FILE=MMS24-25.c
|
SOURCE_FILE=MMS24-25.c
|
||||||
OPTS=-lm -D _TESTS_NONSTOP
|
OPTS=-lm -D _DEBUG_
|
||||||
|
|
||||||
all: clean tests run
|
all: clean tests run
|
||||||
|
|
||||||
|
|||||||
320
tests.c
320
tests.c
@ -44,8 +44,8 @@ void error(const char* fmt, ...) {
|
|||||||
void testInterpolation() {
|
void testInterpolation() {
|
||||||
info("testInterpolation");
|
info("testInterpolation");
|
||||||
|
|
||||||
double dRangeMin = -3;
|
double dRangeMin = -1;
|
||||||
double dRangeMax = 3;
|
double dRangeMax = 1;
|
||||||
double dRangeStep = 0.33;
|
double dRangeStep = 0.33;
|
||||||
|
|
||||||
for (double dX1=dRangeMin;dX1<dRangeMax;dX1+=dRangeStep) {
|
for (double dX1=dRangeMin;dX1<dRangeMax;dX1+=dRangeStep) {
|
||||||
@ -117,6 +117,8 @@ void testSineAndReadWriteDoubleArraySingle(int nValues, int dPLen, double dAmp)
|
|||||||
info("use `plot \"%s\", \"%s\" with lines` to view.", fileName, fileName);
|
info("use `plot \"%s\", \"%s\" with lines` to view.", fileName, fileName);
|
||||||
|
|
||||||
free(fileName);
|
free(fileName);
|
||||||
|
free(pdSineValues);
|
||||||
|
free(pdReadValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
void testSineAndReadWriteDoubleArray() {
|
void testSineAndReadWriteDoubleArray() {
|
||||||
@ -130,9 +132,323 @@ void testSineAndReadWriteDoubleArray() {
|
|||||||
success("testSineAndWriteDoubleArray");
|
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 != 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){
|
int main (int iArgC, char** ppcArgV){
|
||||||
testInterpolation();
|
testInterpolation();
|
||||||
testSineAndReadWriteDoubleArray();
|
testSineAndReadWriteDoubleArray();
|
||||||
|
testCreateSignalWithDefault();
|
||||||
|
testCreateSignalFromDoubleArray();
|
||||||
|
testCreateSignalFromFile();
|
||||||
|
testWriteMMSignal();
|
||||||
|
testCalculateArea();
|
||||||
|
testCalculateMean();
|
||||||
|
testCalculateStdDev();
|
||||||
|
testCalculateMedian();
|
||||||
|
testCalculateEntropy();
|
||||||
|
testConvoluteSignals();
|
||||||
|
testGetPascalLine();
|
||||||
|
testComputeDFT();
|
||||||
|
testConvertCart2Polar();
|
||||||
|
testConvertPolar2Cart();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user