Refactor finding local extrema for performance
This commit is contained in:
parent
4ac8f2d4be
commit
21962c9131
2
.gitignore
vendored
2
.gitignore
vendored
@ -57,3 +57,5 @@ main
|
||||
*results.txt
|
||||
|
||||
tests
|
||||
*.numbered.*
|
||||
*.old.*
|
||||
|
||||
56
MMS24-25.c
56
MMS24-25.c
@ -748,19 +748,13 @@ double calculateMedian(double *pdIn, int iLen) {
|
||||
/*
|
||||
* Creates a new LocalExtrema struct
|
||||
*/
|
||||
LocalExtrema *initLocalExtrema(int *piInPos, int iLen) {
|
||||
LocalExtrema *createLocalExtrema() {
|
||||
LocalExtrema *localExtrema = (LocalExtrema*) malloc(sizeof(LocalExtrema));
|
||||
if (localExtrema == NULL)
|
||||
_mem_error("initLocalExtrema: Failed to allocate memory for localExtrema");
|
||||
|
||||
localExtrema->iNumLocalExtrema = iLen;
|
||||
localExtrema->piLocalExtremaPos = (int*) malloc(sizeof(int) *iLen);
|
||||
if (localExtrema->piLocalExtremaPos == NULL)
|
||||
_mem_error("initLocalExtrema: Failed to allocate memory for localExtrema->piLocalExtremaPos");
|
||||
|
||||
for (int i = 0; i < iLen; i++) {
|
||||
localExtrema->piLocalExtremaPos[i] = piInPos[i];
|
||||
}
|
||||
localExtrema->iNumLocalExtrema = 0;
|
||||
localExtrema->piLocalExtremaPos = NULL;
|
||||
|
||||
return localExtrema;
|
||||
}
|
||||
@ -793,56 +787,60 @@ void findLocalExtremaFromArray(
|
||||
LocalExtrema **ppexLocalMax,
|
||||
LocalExtrema **ppexLocalMin
|
||||
) {
|
||||
int iNumLocalMax = 0;
|
||||
int iNumLocalMin = 0;
|
||||
int *piLocalMaxPos = NULL;
|
||||
int *piLocalMinPos = NULL;
|
||||
|
||||
LocalExtrema *pexLocalMax = createLocalExtrema();
|
||||
LocalExtrema *pexLocalMin = createLocalExtrema();
|
||||
|
||||
int **ppiLocalMaxPos = &pexLocalMax->piLocalExtremaPos;
|
||||
int **ppiLocalMinPos = &pexLocalMin->piLocalExtremaPos;
|
||||
int *iNumLocalMax = &pexLocalMax->iNumLocalExtrema;
|
||||
int *iNumLocalMin = &pexLocalMin->iNumLocalExtrema;
|
||||
|
||||
for (int i = 1; i < iLen - 1; i++) {
|
||||
if (pdIn[i] > pdIn[i-1] && pdIn[i] > pdIn[i+1]) {
|
||||
iNumLocalMax++;
|
||||
(*iNumLocalMax)++;
|
||||
|
||||
#ifdef _DEBUG
|
||||
_debug("findLocalExtremaFromArray: Found local maximum at (%d, %lf)", i, pdIn[i]);
|
||||
#endif
|
||||
|
||||
if (piLocalMaxPos == NULL)
|
||||
piLocalMaxPos = (int*) malloc(sizeof(int) *iNumLocalMax);
|
||||
if (*ppiLocalMaxPos == NULL)
|
||||
*ppiLocalMaxPos = (int*) malloc(sizeof(int) * (*iNumLocalMax));
|
||||
else
|
||||
piLocalMaxPos = (int*) realloc(piLocalMaxPos, sizeof(int) *iNumLocalMax);
|
||||
*ppiLocalMaxPos = (int*) realloc(*ppiLocalMaxPos, sizeof(int) * (*iNumLocalMax));
|
||||
|
||||
if (piLocalMaxPos == NULL)
|
||||
if (*ppiLocalMaxPos == NULL)
|
||||
_mem_error("findLocalExtremaFromArray: Failed to allocate memory for piLocalMaxPos");
|
||||
|
||||
piLocalMaxPos[iNumLocalMax-1] = i;
|
||||
*ppiLocalMaxPos[(*iNumLocalMax)-1] = i;
|
||||
}
|
||||
|
||||
if (pdIn[i] < pdIn[i-1] && pdIn[i] < pdIn[i+1]) {
|
||||
iNumLocalMin++;
|
||||
(*iNumLocalMin)++;
|
||||
|
||||
#ifdef _DEBUG
|
||||
_debug("findLocalExtremaFromArray: Found local minimum at (%d, %lf)", i, pdIn[i]);
|
||||
#endif
|
||||
|
||||
if (piLocalMinPos == NULL)
|
||||
piLocalMinPos = (int*) malloc(sizeof(int) *iNumLocalMin);
|
||||
if (*ppiLocalMinPos == NULL)
|
||||
*ppiLocalMinPos = (int*) malloc(sizeof(int) * (*iNumLocalMin));
|
||||
else
|
||||
piLocalMinPos = (int*) realloc(piLocalMinPos, sizeof(int) *iNumLocalMin);
|
||||
*ppiLocalMinPos = (int*) realloc(*ppiLocalMinPos, sizeof(int) * (*iNumLocalMin));
|
||||
|
||||
if (piLocalMinPos == NULL)
|
||||
if (*ppiLocalMinPos == NULL)
|
||||
_mem_error("findLocalExtremaFromArray: Failed to allocate memory for piLocalMinPos");
|
||||
|
||||
piLocalMinPos[iNumLocalMin-1] = i;
|
||||
*ppiLocalMinPos[(*iNumLocalMin)-1] = i;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
_debug("findLocalExtremaFromArray: Found %d local maxima", iNumLocalMax);
|
||||
_debug("findLocalExtremaFromArray: Found %d local minima", iNumLocalMin);
|
||||
_debug("findLocalExtremaFromArray: Found %d local maxima", *iNumLocalMax);
|
||||
_debug("findLocalExtremaFromArray: Found %d local minima", *iNumLocalMin);
|
||||
#endif
|
||||
|
||||
*ppexLocalMax = initLocalExtrema(piLocalMaxPos, iNumLocalMax);
|
||||
*ppexLocalMin = initLocalExtrema(piLocalMinPos, iNumLocalMin);
|
||||
*ppexLocalMax = pexLocalMax;
|
||||
*ppexLocalMin = pexLocalMin;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
2
Makefile
2
Makefile
@ -1,6 +1,6 @@
|
||||
CC=gcc
|
||||
SOURCE_FILE=MMS24-25.c
|
||||
OPTS=-lm
|
||||
OPTS=-lm -D _DEBUG
|
||||
|
||||
all: clean tests run
|
||||
|
||||
|
||||
6
tests.c
6
tests.c
@ -469,6 +469,12 @@ void testCalcExtrema() {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user