added NLMS function

This commit is contained in:
gurkenhabicht 2018-06-12 11:14:19 +02:00
parent 4d70cb8261
commit 50896e98d0
2 changed files with 105 additions and 9 deletions

View File

@ -53,6 +53,7 @@ double sum_array(double x[], int length);
void localMean ( mldata_t *mlData,point_t points[] ); // First,
void directPredecessor ( mldata_t *mlData, point_t points[] ); // Second,
void differentialPredecessor ( mldata_t *mlData, point_t points[] ); // Third filter implementation
void standardNLMS ( mldata_t *mlData, point_t points[] );
double windowXMean(int _arraylength, int xCount); // Returns mean value of given window
@ -168,8 +169,10 @@ int main( int argc, char **argv ) {
fclose(fp0);
localMean ( mlData, points ); // math magic functions
directPredecessor ( mlData, points );
differentialPredecessor( mlData, points );
standardNLMS ( mlData, points );
if ( include == 1 ) {
mkSvgGraph(points, templatePath); // Graph building
@ -183,6 +186,85 @@ int main( int argc, char **argv ) {
printf("\nDONE!\n");
}
/*
======================================================================================================
standardNLMS
basic nullified least mean square implementation
======================================================================================================
*/
void standardNLMS( mldata_t *mlData, point_t points[] ) {
double *localWeights = (double *) malloc ( sizeof(double) * mlData->windowSize + 1);
memcpy(localWeights, mlData->weights, sizeof(double) * mlData->windowSize + 1);
char fileName[50];
const unsigned xErrorLength = mlData->samplesCount;
double xError[xErrorLength];
unsigned i, xCount = 0;
mkFileName ( fileName, sizeof(fileName), STANDARD_NLMS);
FILE* fp01 = fopen( fileName, "w" );
fprintf( fp01, fileHeader(STANDARD_NLMS_HEADER) );
mkFileName ( fileName, sizeof(fileName), USED_WEIGHTS_STANDARD_NLMS );
FILE* fp9 = fopen( fileName, "w" );
double xMean = xSamples[0];
double xSquared = 0.0;
double xPredicted = 0.0;
double xActual = 0.0;
for ( xCount = 1; xCount < mlData->samplesCount - 1; xCount++ ) {
unsigned _arrayLength = ( xCount > mlData->windowSize ) ? mlData->windowSize + 1 : xCount;
xMean = ( xCount > 0 ) ? windowXMean ( _arrayLength, xCount ) : 0;
xPredicted = 0.0;
xActual = xSamples[xCount];
for ( i = 1; i < _arrayLength; i++ ){
xPredicted += localWeights[i - 1] * xSamples[xCount - i];
}
xError[xCount] = xActual - xPredicted;
xSquared = 0.0;
for ( i = 1; i < _arrayLength; i++ ) {
xSquared += xSamples[xCount - i] * xSamples[xCount - i];
}
if ( xSquared == 0 ) {
xSquared = 1.0;
}
for ( i = 1; i < _arrayLength; i++ ) {
localWeights[i - 1] = localWeights[i - 1] + mlData->learnrate * xError[xCount]
* (xSamples[xCount - i] /xSquared);
fprintf ( fp9, "%lf;", localWeights[i - 1] );
}
fprintf ( fp9, "\n" );
fprintf ( fp01, "%d\t%f\t%f\t%f\n", xCount, xPredicted, xActual, xError[xCount] );
points[xCount].xVal[7] = xCount;
points[xCount].yVal[7] = xPredicted;
points[xCount].xVal[8] = xCount;
points[xCount].yVal[8] = xError[xCount];
}
fclose(fp9);
double mean = sum_array(xError, xErrorLength) / xErrorLength;
double deviation = 0.0;
for ( i = 1; i < xErrorLength; i++ ) {
deviation += (xError[i] - mean) * (xError[i] - mean);
}
deviation /= xErrorLength;
printf("mean square err: %lf, variance: %lf\t\tNLMS\n", mean, deviation);
fprintf( fp01, "\nQuadratische Varianz(x_error): %f\nMittelwert:(x_error): %f\n\n", deviation, mean );
free(localWeights);
}
/*
======================================================================================================
@ -314,8 +396,9 @@ void directPredecessor( mldata_t *mlData, point_t points[]) {
for ( i = 1; i < _arrayLength; i++ ) { // Update weights
localWeights[i - 1] = localWeights[i-1] + mlData->learnrate * xError[xCount]
* ( (xSamples[xCount - 1] - xSamples[xCount - i - 1]) / xSquared);
fprintf( fp9, "%lf\n", localWeights[i - 1] );
fprintf( fp9, "%lf;", localWeights[i - 1] );
}
fprintf(fp9, "\n");
fprintf(fp3, "%d\t%f\t%f\t%f\n", xCount, xPredicted, xActual, xError[xCount]); // Write to logfile
points[xCount].xVal[2] = xCount; // Fill point_t array for graph building
@ -393,9 +476,10 @@ void differentialPredecessor ( mldata_t *mlData, point_t points[] ) {
for (i = 1; i < _arrayLength; i++) {
localWeights[i - 1] = localWeights[i - 1] + mlData->learnrate * xError[xCount]
* ((xSamples[xCount - i] - xSamples[xCount - i - 1]) / xSquared);
fprintf( fp9, "%lf\n", localWeights[i - 1] );
fprintf( fp9, "%lf;", localWeights[i - 1] );
}
fprintf(fp9, "\n");
fprintf(fp6, "%d\t%f\t%f\t%f\n", xCount, xPredicted, xActual, xError[xCount]); // Write to logfile
points[xCount].xVal[3] = xCount;
@ -463,6 +547,8 @@ char * fileSuffix ( int id ) {
"_differential_predecessor.txt",
"_weights_used_local_mean.txt",
"_weights_used_diff_pred.txt",
"_standard_least_mean_square.txt",
"_weights_used_std_nlms.txt"
};
return suffix[id];
}
@ -479,7 +565,8 @@ Contains and returns header from logfiles
char * fileHeader ( int id ) {
char * header[] = { "\n=========================== Local Mean ===========================\nNo.\txPredicted\txAcutal\t\txError\n",
"\n=========================== Direct Predecessor ===========================\nNo.\txPredicted\txAcutal\t\txError\n",
"\n=========================== Differential Predecessor ===========================\nNo.\txPredicted\txAcutal\t\txError\n"
"\n=========================== Differential Predecessor ===========================\nNo.\txPredicted\txAcutal\t\txError\n",
"\n========================= Nullified Least Mean Square =========================\nNo.\txPredicted\txAcutal\t\txError\n"
};
return header[id];
}
@ -543,6 +630,12 @@ void bufferLogger(char *buffer, point_t points[]) {
strcat(buffer, _buffer);
}
strcat(buffer, "\" fill=\"none\" id=\"svg_4\" stroke=\"red\" stroke-width=\"0.4px\"/>\n");
for (i = 1; i < mlData->samplesCount - 1; i++) { //xPredicted from diff Pred
sprintf(_buffer, "L %f %f\n", points[i].xVal[7], points[i].yVal[7]);
strcat(buffer, _buffer);
}
strcat(buffer, "\" fill=\"none\" id=\"svg_5\" stroke=\"yellow\" stroke-width=\"0.4px\"/>\n");
}
/*

View File

@ -9,8 +9,8 @@ typedef struct {
/* *svg graph building* */
typedef struct { // Axis x,y
double xVal[7];
double yVal[7];
double xVal[9];
double yVal[9];
}point_t;
/* *ppm read, copy, write* */
@ -33,12 +33,15 @@ enum fileSuffix_t{ // Used in conjunction with MkFileName()
TEST_VALUES,
DIFFERENTIAL_PREDECESSOR,
USED_WEIGHTS_LOCAL_MEAN,
USED_WEIGHTS_DIFF_PRED
USED_WEIGHTS_DIFF_PRED,
STANDARD_NLMS,
USED_WEIGHTS_STANDARD_NLMS
};
enum fileHeader{ // Used in conjunction with MkFilename()
LOCAL_MEAN_HEADER,
DIRECT_PREDECESSOR_HEADER,
DIFFERENTIAL_PREDECESSOR_HEADER
DIFFERENTIAL_PREDECESSOR_HEADER,
STANDARD_NLMS_HEADER
};