Improvements, Bug fixes
This commit is contained in:
parent
a94a357f7a
commit
a1bc592bca
84
MMS24-25.c
84
MMS24-25.c
@ -161,7 +161,7 @@ ssize_t getline(char **lineptr, size_t *n, FILE *stream) {
|
||||
|
||||
*pos = '\0';
|
||||
|
||||
#ifdef _DEBUG_
|
||||
#ifdef _DEBUG
|
||||
_debug("getline: Read line '%s' with length %ld.", *lineptr, (pos - *lineptr));
|
||||
#endif
|
||||
|
||||
@ -195,7 +195,7 @@ double interpolateLine(
|
||||
(dXq - dX1) / (dX2 - dX1)
|
||||
);
|
||||
|
||||
#ifdef _DEBUG_
|
||||
#ifdef _DEBUG
|
||||
// DEBUG: print the parameters and result
|
||||
_debug("interpolateLine(%lf, %lf, %lf, %lf, %lf) -> %lf",
|
||||
dX1,dY1,dX2,dY2,dXq,y);
|
||||
@ -237,7 +237,7 @@ void rescaleDoubleArray(
|
||||
// Calculate the offset
|
||||
double dOffset = dMin - dOldMin;
|
||||
|
||||
#ifdef _DEBUG_
|
||||
#ifdef _DEBUG
|
||||
_debug("rescaleDoubleArray: dOldMin = %lf", dOldMin);
|
||||
_debug("rescaleDoubleArray: dOffset = %lf", dOffset);
|
||||
#endif
|
||||
@ -475,6 +475,9 @@ MMSignal *createSignalFromSignal(MMSignal *pmmsIn) {
|
||||
signal->pdValues[i] = pmmsIn->pdValues[i];
|
||||
}
|
||||
} else {
|
||||
if (pmmsIn->iNumValues != 0)
|
||||
_error("createSignalFromSignal: pmmsIn->pdValues is NULL while pmmsIn->iNumValues is not %d", pmmsIn->iNumValues);
|
||||
|
||||
_warn("createSignalFromSignal: pmmsIn->pdValues is NULL");
|
||||
signal->pdValues = NULL;
|
||||
}
|
||||
@ -667,6 +670,21 @@ double calculateStddev(double *pdIn, int iLen) {
|
||||
return sqrt(stdDev / iLen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compares two double values for the qsort function.
|
||||
*/
|
||||
int compareDoubles(const void* a, const void* b) {
|
||||
int val_a = * ( (double*) a );
|
||||
int val_b = * ( (double*) b );
|
||||
|
||||
if ( val_a == val_b )
|
||||
return 0;
|
||||
else if ( val_a < val_b )
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates the median of an array of double values `pdIn` of length `iLen`.
|
||||
* The median is calculated as the middle value of the sorted array if the
|
||||
@ -679,11 +697,28 @@ double calculateMedian(double *pdIn, int iLen) {
|
||||
* \frac{pdIn_{\frac{|pdIn|}{2}} + pdIn_{\frac{|pdIn|}{2}+1}}{2} & \text{if } |pdIn| \text{ is odd}
|
||||
* \end{cases} \]
|
||||
*/
|
||||
double *pdInSorted = NULL;
|
||||
pdInSorted = (double*) malloc(sizeof(double) *iLen);
|
||||
|
||||
if (iLen == 0) {
|
||||
_warn("calculateMedian: iLen is 0");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pdInSorted == NULL)
|
||||
_mem_error("calculateMedian: Failed to allocate memory for pdInSorted");
|
||||
|
||||
for (int i = 0; i < iLen; i++) {
|
||||
pdInSorted[i] = pdIn[i];
|
||||
}
|
||||
|
||||
// Sort the array using stdlib's qsort function
|
||||
qsort(pdInSorted, iLen, sizeof(double), compareDoubles);
|
||||
|
||||
if (iLen % 2 == 0) {
|
||||
return pdIn[iLen/2];
|
||||
return (pdIn[iLen/2 - 1] + pdIn[iLen/2]) / 2;
|
||||
} else {
|
||||
return (pdIn[iLen/2] + pdIn[iLen/2+1]) / 2;
|
||||
return pdIn[iLen/2];
|
||||
}
|
||||
}
|
||||
|
||||
@ -707,9 +742,14 @@ LocalExtrema *initLocalExtrema(int *piInPos, int iLen) {
|
||||
return localExtrema;
|
||||
}
|
||||
|
||||
int getMinMaxPos(double *pdIn, int iLen, int *iMinPos, int *iMaxPos) {
|
||||
*iMaxPos = 0;
|
||||
*iMinPos = 0;
|
||||
void getMinMaxPos(double *pdIn, int iLen, int *iMinPos, int *iMaxPos) {
|
||||
*iMaxPos = -1;
|
||||
*iMinPos = -1;
|
||||
|
||||
if (iLen == 0) {
|
||||
_warn("getMinMaxPos: iLen is 0");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 1; i < iLen; i++) {
|
||||
if (pdIn[i] > pdIn[*iMaxPos])
|
||||
@ -739,6 +779,10 @@ void findLocalExtremaFromArray(
|
||||
if (pdIn[i] > pdIn[i-1] && pdIn[i] > pdIn[i+1]) {
|
||||
iNumLocalMax++;
|
||||
|
||||
#ifdef _DEBUG
|
||||
_debug("findLocalExtremaFromArray: Found local maximum at (%d, %lf)", i, pdIn[i]);
|
||||
#endif
|
||||
|
||||
if (piLocalMaxPos == NULL)
|
||||
piLocalMaxPos = (int*) malloc(sizeof(int) *iNumLocalMax);
|
||||
else
|
||||
@ -753,6 +797,10 @@ void findLocalExtremaFromArray(
|
||||
if (pdIn[i] < pdIn[i-1] && pdIn[i] < pdIn[i+1]) {
|
||||
iNumLocalMin++;
|
||||
|
||||
#ifdef _DEBUG
|
||||
_debug("findLocalExtremaFromArray: Found local minimum at (%d, %lf)", i, pdIn[i]);
|
||||
#endif
|
||||
|
||||
if (piLocalMinPos == NULL)
|
||||
piLocalMinPos = (int*) malloc(sizeof(int) *iNumLocalMin);
|
||||
else
|
||||
@ -765,6 +813,11 @@ void findLocalExtremaFromArray(
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
_debug("findLocalExtremaFromArray: Found %d local maxima", iNumLocalMax);
|
||||
_debug("findLocalExtremaFromArray: Found %d local minima", iNumLocalMin);
|
||||
#endif
|
||||
|
||||
*ppexLocalMax = initLocalExtrema(piLocalMaxPos, iNumLocalMax);
|
||||
*ppexLocalMin = initLocalExtrema(piLocalMinPos, iNumLocalMin);
|
||||
}
|
||||
@ -782,6 +835,13 @@ Extrema *initExtrema(double *pdIn, int iLen) {
|
||||
// Get the global extrema
|
||||
getMinMaxPos(pdIn, iLen, &extrema->iGlobalMinPos, &extrema->iGlobalMaxPos);
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (iLen > 0) {
|
||||
_debug("initExtrema: Found global minimum at (%d, %lf)", extrema->iGlobalMinPos, pdIn[extrema->iGlobalMinPos]);
|
||||
_debug("initExtrema: Found global maximum at (%d, %lf)", extrema->iGlobalMaxPos, pdIn[extrema->iGlobalMaxPos]);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize the local extrema
|
||||
extrema->pexLocalMax = NULL;
|
||||
extrema->pexLocalMin = NULL;
|
||||
@ -831,7 +891,7 @@ Histogram *initHistogram(double *pdIn, int iLen, int iNumBins) {
|
||||
histogram->dIntervalMax = pdIn[i];
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_
|
||||
#ifdef _DEBUG
|
||||
_debug("initHistogram: histogram->dIntervalMin = %lf", histogram->dIntervalMin);
|
||||
_debug("initHistogram: histogram->dIntervalMax = %lf", histogram->dIntervalMax);
|
||||
#endif
|
||||
@ -839,7 +899,7 @@ Histogram *initHistogram(double *pdIn, int iLen, int iNumBins) {
|
||||
histogram->dBinWidth = (histogram->dIntervalMax - histogram->dIntervalMin) / iNumBins;
|
||||
histogram->iNumBins = iNumBins;
|
||||
|
||||
#ifdef _DEBUG_
|
||||
#ifdef _DEBUG
|
||||
_debug("initHistogram: histogram->dBinWidth = %lf", histogram->dBinWidth);
|
||||
#endif
|
||||
|
||||
@ -866,7 +926,7 @@ Histogram *initHistogram(double *pdIn, int iLen, int iNumBins) {
|
||||
histogram->pdBinValues[i] /= iLen;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_
|
||||
#ifdef _DEBUG
|
||||
// DEBUG: print the parameters and result
|
||||
_debug("initHistogram(%lf, %lf, %lf, %d)",
|
||||
histogram->dIntervalMin,histogram->dIntervalMax,histogram->dBinWidth,histogram->iNumBins);
|
||||
@ -914,6 +974,8 @@ double calculateEntropy(Histogram *phisIn) {
|
||||
|
||||
/*
|
||||
* Convolve two signals `pmmsInA` and `pmmsInB` and return the result.
|
||||
* Actually this should be named `convolveSignals` but the task specifies
|
||||
* `convoluteSignals`.
|
||||
*/
|
||||
MMSignal *convoluteSignals(MMSignal *pmmsInA, MMSignal *pmmsInB) {
|
||||
// Calculate output length
|
||||
|
||||
2
Makefile
2
Makefile
@ -1,6 +1,6 @@
|
||||
CC=gcc
|
||||
SOURCE_FILE=MMS24-25.c
|
||||
OPTS=-lm -std=c99
|
||||
OPTS=-lm -std=c99 -D _DEBUG_
|
||||
|
||||
all: clean tests run
|
||||
|
||||
|
||||
57
tests.c
57
tests.c
@ -289,10 +289,18 @@ void testCalculateMedian() {
|
||||
|
||||
double dMedian = calculateMedian(pdValues, 10);
|
||||
|
||||
if (dMedian != 6) {
|
||||
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");
|
||||
}
|
||||
|
||||
@ -385,6 +393,17 @@ void testGetPascalLine() {
|
||||
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");
|
||||
|
||||
@ -443,6 +462,40 @@ void testConvertPolar2Cart() {
|
||||
success("testConvertPolar2Cart");
|
||||
}
|
||||
|
||||
void testCalcExtrema() {
|
||||
info("testCalcExtrema");
|
||||
|
||||
double pdValues[] = {1, 2, 1, 0, -1, -2, -1, 0, 1, 5};
|
||||
|
||||
Extrema *extrema = initExtrema(pdValues, 10);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
int main (int iArgC, char** ppcArgV){
|
||||
testInterpolation();
|
||||
testSineAndReadWriteDoubleArray();
|
||||
@ -460,6 +513,8 @@ int main (int iArgC, char** ppcArgV){
|
||||
testComputeDFT();
|
||||
testConvertCart2Polar();
|
||||
testConvertPolar2Cart();
|
||||
testApplyPascalConvForSeriesGT40();
|
||||
testCalcExtrema();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user