introduced mldata_t, updated README file

This commit is contained in:
gurkenhabicht 2018-05-18 18:51:59 +02:00
parent 9743c82408
commit 26158281ef
2 changed files with 236 additions and 146 deletions

View File

@ -13,60 +13,78 @@
#include <float.h> // DBL_MAX #include <float.h> // DBL_MAX
#include "nlms_types.h" // added types #include "nlms_types.h" // added types
#define NUMBER_OF_SAMPLES 50
#define WINDOWSIZE 5
#define learnrate 0.8
#define RGB_COLOR 255 #define RGB_COLOR 255
#if defined(_MSC_VER) #if defined(_MSC_VER)
#include <BaseTsd.h> #include <BaseTsd.h>
typedef SSIZE_T ssize_t; typedef SSIZE_T ssize_t;
#endif #endif
double xSamples[NUMBER_OF_SAMPLES] = { 0.0 }; typedef struct {
double *weights;
unsigned windowSize;
unsigned samplesCount;
double learnrate;
} mldata_t;
point_t points[NUMBER_OF_SAMPLES]; // [0] = xActual, [1]=xpredicted from localMean, [2]=xpredicted from directPredecessor, [3] = xpredicted from differentialpredecessor, [4] = xError from localMean, [5] xError from directPredecessor, [6] xError from differentialPredecessor enum fileHeader{
LOCAL_MEAN_HEADER,
DIRECT_PREDECESSOR_HEADER,
DIFFERENTIAL_PREDECESSOR_HEADER
};
static imagePixel_t * rdPPM(char *fileName); // read PPM file format double *xSamples;
void mkPpmFile(char *fileName, imagePixel_t *image); // writes PPM file mldata_t *mlData = NULL; // Machine learning
int ppmColorChannel(FILE* fp, imagePixel_t *image, char *colorChannel); // writes colorChannel from PPM file to log file point_t *points = NULL; // Graphing
void colorSamples(FILE* fp); // stores color channel values in xSamples[]
/* *graph building* */
static imagePixel_t * rdPPM(char *fileName); // Read PPM file format
void mkPpmFile(char *fileName, imagePixel_t *image); // Writes PPM file
int ppmColorChannel(FILE* fp, imagePixel_t *image, // Writes colorChannel from PPM file to log file
char *colorChannel, mldata_t *mlData);
void colorSamples(FILE* fp, mldata_t *mlData); // Stores color channel values in xSamples
/* *file handling* */ /* *file handling* */
char * mkFileName(char* buffer, size_t max_len, int suffixId); char * mkFileName ( char* buffer,
char *fileSuffix(int id); size_t max_len, int suffixId );
void myLogger(FILE* fp, point_t points[]); char *fileSuffix ( int id );
void mkSvgGraph(point_t points[]); char *fileHeader ( int id ); // Header inside the logfiles
//void weightsLogger(double *weights, int var); //void myLogger ( FILE* fp, point_t points[] );
void bufferLogger(char *buffer, point_t points[]); // Writes points to graph template
void mkSvgGraph ( point_t points[] ); // Parses graph template and calls bufferLogger()
void weightsLogger ( double *weights, int suffix ); // Writes updated weights to a file
/* *rand seed* */ /* *rand seed* */
double r2(void); double r2 ( void ); // Random val between 0 and 1
double rndm(void); double rndm ( void );
/* *args parser* */ /* *args parser* */
void usage ( void ); void usage ( void ); // Help text called by args parser
/* *math* */ /* *math* */
mldata_t * init_mldata_t(unsigned windowSize, unsigned samplesCount, double learnrate);
double sum_array(double x[], int length); double sum_array(double x[], int length);
void directPredecessor(double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]);
void localMean(double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]); void localMean ( mldata_t *mlData,point_t points[] ); // First,
void differentialPredecessor(double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]); void directPredecessor ( mldata_t *mlData, point_t points[] ); // Second,
//void directPredecessor(double **weights, unsigned int windowSize, unsigned int samplesCount); void differentialPredecessor ( mldata_t *mlData, point_t points[] ); // Third filter implementation
//void localMean(double **weights, unsigned int windowSize, unsigned int samplesCount);
//void differentialPredecessor(double **weightsi, unsigned int windowSize, unsigned int samplesCount); double *popNAN(double *xError); // Returns array without NAN values, if any exist
double *popNAN(double *xError); // Returns array without NAN values, if any exist double windowXMean(int _arraylength, int xCount); // Returns mean value of given window
double windowXMean(int _arraylength, int xCount);// returns mean value of given window
int main( int argc, char **argv ) { int main( int argc, char **argv ) {
char *colorChannel = (char *) malloc(sizeof(char)* 32); char *colorChannel = (char *) malloc(sizeof(char)* 32);
double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]; // = { { 0.0 }, { 0.0 } };
char *inputfile = (char *)malloc(sizeof(char) * 32); char *inputfile = (char *)malloc(sizeof(char) * 32);
unsigned int *seed = NULL; unsigned int *seed = NULL;
int i,k, xLength; unsigned k, xLength;
unsigned int windowSize = 0; unsigned int windowSize = 5;
unsigned int samplesCount = 0; unsigned int samplesCount = 20;
char *stdcolor = "green"; char *stdcolor = "green";
colorChannel = stdcolor; colorChannel = stdcolor;
unsigned int uint_buffer[1]; unsigned int uint_buffer[1];
double **buffer = NULL; double learnrate = 0.8;
while( (argc > 1) && (argv[1][0] == '-') ) { // Parses parameters from stdin while( (argc > 1) && (argv[1][0] == '-') ) { // Parses parameters from stdin
switch( argv[1][1] ) { switch( argv[1][1] ) {
@ -94,11 +112,17 @@ int main( int argc, char **argv ) {
case 'n': case 'n':
sscanf(&argv[1][3], "%u", &samplesCount); sscanf(&argv[1][3], "%u", &samplesCount);
++argv; ++argv;
--argc; --argc;
case 'h': break;
case'h':
printf("Program name: %s\n", argv[0]); printf("Program name: %s\n", argv[0]);
usage(); usage();
break; break;
case 'l':
sscanf(&argv[1][3], "%lf", &learnrate);
++argv;
--argc;
break;
default: default:
printf("Wrong Arguments: %s\n", argv[1]); printf("Wrong Arguments: %s\n", argv[1]);
usage(); usage();
@ -107,56 +131,51 @@ int main( int argc, char **argv ) {
++argv; ++argv;
--argc; --argc;
} }
/* init_mldata_t(windowSize, samplesCount, learnrate);
if ( windowSize > 0 ) { xSamples = (double *) malloc ( sizeof(double) * mlData->samplesCount );
buffer = (double *) realloc (weights, sizeof(double) * windowSize * NUMBER_OF_SAMPLES ); points = (point_t *) malloc ( sizeof(point_t) * mlData->samplesCount);
weights = buffer;
} else if ( samplesCount > 0 ) {
buffer = (double *) realloc (weights, sizeof(double) * WINDOWSIZE * samplesCount);
weights = buffer;
} else if ( (samplesCount > 0) && (windowSize > 0) ){
buffer = (double *) realloc(weights, sizeof(double) *windowSize * samplesCount);
weights = buffer;
}
*/
imagePixel_t *image; imagePixel_t *image;
char fileName[50]; char fileName[50];
image = rdPPM(inputfile); image = rdPPM(inputfile);
mkFileName(fileName, sizeof(fileName), TEST_VALUES); mkFileName(fileName, sizeof(fileName), TEST_VALUES);
FILE* fp5 = fopen(fileName, "w"); FILE* fp5 = fopen(fileName, "w");
xLength = ppmColorChannel(fp5, image, colorChannel); // Returns length of ppm input values xLength = ppmColorChannel(fp5, image, colorChannel, mlData); // Returns length of ppm input values
printf("%d\n", xLength); printf("%d\n", xLength);
FILE* fp6 = fopen(fileName, "r"); FILE* fp6 = fopen(fileName, "r");
colorSamples(fp6); colorSamples(fp6, mlData);
if ( (seed != NULL) && (seed >= 0) ){ // seed >= 0 is redundant if ( (seed != NULL) ){
srand( *seed ); // Seed for random number generating srand( *seed ); // Seed for random number generating
printf("srand is reproducable : %u", seed); printf("srand is reproducable : %u", seed);
} else { } else {
srand( (unsigned int)time(NULL) ); srand( (unsigned int)time(NULL) );
printf("srand from time"); // Default seed is time(NULL) printf("srand from time\n"); // Default seed is time(NULL)
} }
for (i = 0; i < NUMBER_OF_SAMPLES; i++) { // for (i = 0; i < NUMBER_OF_SAMPLES; i++) {
for (int k = 0; k < WINDOWSIZE; k++) { for (k = 0; k < mlData->windowSize; k++) {
weights[k][i] = rndm(); // Init random weights mlData->weights[k] = rndm(); // Init random weights
printf("%lf\n", weights[k][i]); printf("%lf\n", mlData->weights[k]);
} }
} // }
mkFileName(fileName, sizeof(fileName), PURE_WEIGHTS); mkFileName(fileName, sizeof(fileName), PURE_WEIGHTS);
FILE *fp0 = fopen(fileName, "w"); FILE *fp0 = fopen(fileName, "w");
for (i = 0; i < NUMBER_OF_SAMPLES; i++) { // for (i = 0; i < NUMBER_OF_SAMPLES; i++) {
for (k = 0; k < WINDOWSIZE; k++) { for (k = 0; k < mlData->windowSize; k++) {
fprintf(fp0, "[%d][%d]%lf\n", k, i, weights[k][i]); // Save generated weights to to file fprintf(fp0, "[%d]%lf\n", k, mlData->weights[k]); // Save generated weights to to file
} }
} // }
fclose(fp0); fclose(fp0);
// math magic // math magic
localMean(weights); localMean ( mlData, points );
directPredecessor(weights); directPredecessor ( mlData, points);
differentialPredecessor(weights); differentialPredecessor( mlData, points );
mkSvgGraph(points); mkSvgGraph(points);
free(xSamples);
free(points);
printf("\nDONE!\n"); printf("\nDONE!\n");
} }
@ -169,51 +188,56 @@ Variant (1/3), substract local mean.
====================================================================================================== ======================================================================================================
*/ */
void localMean(double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]) { void localMean ( mldata_t *mlData, point_t points[] ) {
double (*local_weights)[WINDOWSIZE] =(double (*)[WINDOWSIZE]) malloc(sizeof(double) * (WINDOWSIZE+1) * (NUMBER_OF_SAMPLES+1)); // double (*local_weights)[WINDOWSIZE] =(double (*)[WINDOWSIZE]) malloc(sizeof(double) * (WINDOWSIZE+1) * (NUMBER_OF_SAMPLES+1));
memcpy(local_weights, weights, sizeof(double) * WINDOWSIZE * NUMBER_OF_SAMPLES); //memcpy(local_weights, weights, sizeof(double) * WINDOWSIZE * NUMBER_OF_SAMPLES);
double *localWeights = (double *) malloc ( sizeof(double) * mlData->windowSize + 1);
memcpy ( localWeights, mlData->weights, sizeof(mlData->windowSize) ); // TODO: check size !!!
char fileName[50]; char fileName[50];
double xError[2048]; // includes e(n) double xError[2048]; // includes e(n)
memset(xError, 0.0, NUMBER_OF_SAMPLES);// initialize xError-array with Zero memset(xError, 0.0, mlData->samplesCount);// initialize xError-array with Zero
int xCount = 0, i; // runtime var; unsigned i, xCount = 0; // runtime var
mkFileName(fileName, sizeof(fileName), LOCAL_MEAN); mkFileName(fileName, sizeof(fileName), LOCAL_MEAN);
FILE* fp4 = fopen(fileName, "w"); FILE* fp4 = fopen(fileName, "w");
fprintf(fp4, "\n===================================== LocalMean =====================================\nNo.\txPredicted\txActual\t\txError\n"); fprintf( fp4, fileHeader(LOCAL_MEAN_HEADER) );
double xMean = xSamples[0]; double xMean = xSamples[0];
double xSquared = 0.0; double xSquared = 0.0;
double xPredicted = 0.0; double xPredicted = 0.0;
double xActual = 0.0; double xActual = 0.0;
for (xCount = 1; xCount < NUMBER_OF_SAMPLES; xCount++) { // first value will not get predicted for (xCount = 1; xCount < mlData->samplesCount; xCount++) { // first value will not get predicted
int _arrayLength = ( xCount > WINDOWSIZE ) ? WINDOWSIZE + 1 : xCount; unsigned _arrayLength = ( xCount > mlData->windowSize ) ? mlData->windowSize + 1 : xCount;
xMean = (xCount > 0) ? windowXMean(_arrayLength, xCount) : 0; xMean = (xCount > 0) ? windowXMean(_arrayLength, xCount) : 0;
xPredicted = 0.0; xPredicted = 0.0;
xActual = xSamples[xCount + 1]; xActual = xSamples[xCount];
// weightedSum += _x[ xCount-1 ] * w[xCount][0];
for (i = 1; i < _arrayLength; i++) { //get predicted value for (i = 1; i < _arrayLength; i++) { //get predicted value
xPredicted += (local_weights[i][xCount] * (xSamples[xCount - i] - xMean)); xPredicted += (localWeights[i] * (xSamples[xCount - i] - xMean));
} }
xPredicted += xMean; xPredicted += xMean;
xError[xCount] = xActual - xPredicted; xError[xCount] = xActual - xPredicted;
xSquared = 0.0;
for (i = 1; i < _arrayLength; i++) { //get xSquared
xSquared += pow(xSamples[xCount - i] - xMean, 2);
}
if ( xSquared == 0.0 ) { // Otherwise returns Pred: -1.#IND00 in some occassions
xSquared = 1.0;
}
for ( i = 1; i < _arrayLength; i++ ) { //update weights
localWeights[ i + 1 ] = localWeights[i] + mlData->learnrate * xError[xCount] * ( (xSamples[xCount - i] - xMean) / xSquared );
}
fprintf(fp4, "%d\t%f\t%f\t%f\n", xCount, xPredicted, xActual, xError[xCount]);
points[xCount].xVal[1] = xCount; points[xCount].xVal[1] = xCount;
points[xCount].yVal[1] = xPredicted; points[xCount].yVal[1] = xPredicted;
points[xCount].xVal[4] = xCount; points[xCount].xVal[4] = xCount;
points[xCount].yVal[4] = xError[xCount]; points[xCount].yVal[4] = xError[xCount];
xSquared = 0.0;
for (i = 1; i < _arrayLength; i++) { //get xSquared
xSquared += pow(xSamples[xCount - i] - xMean, 2);
}
if (xSquared == 0.0) { // Otherwise returns Pred: -1.#IND00 in some occassions
xSquared = 1.0;
}
for (i = 1; i < _arrayLength; i++) { //update weights
local_weights[i][xCount+1] = local_weights[i][xCount] + learnrate * xError[xCount] * ((xSamples[xCount - i] - xMean) / xSquared);
}
fprintf(fp4, "%d\t%f\t%f\t%f\n", xCount, xPredicted, xActual, xError[xCount]);
} }
double *xErrorPtr = popNAN(xError); // delete NAN values from xError[] double *xErrorPtr = popNAN(xError); // delete NAN values from xError[]
double xErrorLength = *xErrorPtr; // Watch popNAN()! double xErrorLength = *xErrorPtr; // Watch popNAN()!
@ -234,7 +258,7 @@ void localMean(double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]) {
//FILE *fp2 = fopen(fileName, "w"); //FILE *fp2 = fopen(fileName, "w");
fprintf(fp4, "\nQuadratische Varianz(x_error): %f\nMittelwert:(x_error): %f\n\n", deviation, mean); fprintf(fp4, "\nQuadratische Varianz(x_error): %f\nMittelwert:(x_error): %f\n\n", deviation, mean);
//fclose(fp2); //fclose(fp2);
free(local_weights); free(localWeights);
fclose(fp4); fclose(fp4);
//weightsLogger( local_weights, USED_WEIGHTS ); //weightsLogger( local_weights, USED_WEIGHTS );
@ -250,46 +274,53 @@ substract direct predecessor
====================================================================================================== ======================================================================================================
*/ */
void directPredecessor(double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]) { void directPredecessor( mldata_t *mlData, point_t points[]) {
double (*local_weights)[WINDOWSIZE] = (double (*)[WINDOWSIZE]) malloc(sizeof(double) * (WINDOWSIZE+1) * (NUMBER_OF_SAMPLES+1)); double *localWeights = ( double * ) malloc ( sizeof(double) * mlData->windowSize + 1 );
memcpy ( localWeights, mlData->weights, sizeof(mlData->windowSize) );
memcpy(local_weights, weights, sizeof(double) * WINDOWSIZE * NUMBER_OF_SAMPLES );
char fileName[512]; char fileName[512];
double xError[2048]; double xError[2048];
int xCount = 0, i; unsigned xCount = 0, i;
double xActual = 0.0; double xActual = 0.0;
double xPredicted = 0.0; double xPredicted = 0.0;
// File handling
mkFileName(fileName, sizeof(fileName), DIRECT_PREDECESSOR); mkFileName(fileName, sizeof(fileName), DIRECT_PREDECESSOR);
FILE *fp3 = fopen(fileName, "w"); FILE *fp3 = fopen(fileName, "w");
fprintf(fp3, "\n===================================== DirectPredecessor =====================================\nNo.\txPredicted\txAcutal\t\txError\n"); fprintf( fp3, fileHeader(DIRECT_PREDECESSOR_HEADER) );
mkFileName ( fileName, sizeof(fileName), USED_WEIGHTS);
FILE *fp9 = fopen(fileName, "w");
for (xCount = 1; xCount < NUMBER_OF_SAMPLES; xCount++) { // first value will not get predicted for (xCount = 1; xCount < mlData->samplesCount; xCount++) { // first value will not get predicted
int _arrayLength = (xCount > WINDOWSIZE) ? WINDOWSIZE + 1 : xCount; unsigned _arrayLength = ( xCount > mlData->windowSize ) ? mlData->windowSize + 1 : xCount;
xPredicted = 0.0; xPredicted = 0.0;
xActual = xSamples[xCount + 1]; xActual = xSamples[xCount];
for (i = 1; i < _arrayLength; i++) { for (i = 1; i < _arrayLength; i++) {
xPredicted += (local_weights[i][xCount] * (xSamples[xCount - 1] - xSamples[xCount - i - 1])); xPredicted += ( localWeights[i - 1] * (xSamples[xCount - 1] - xSamples[xCount - i - 1]));
} }
xPredicted += xSamples[xCount - 1]; xPredicted += xSamples[xCount - 1];
xError[xCount] = xActual - xPredicted; xError[xCount] = xActual - xPredicted;
points[xCount].xVal[2] = xCount; // Fill point_t array for graph building
points[xCount].yVal[2] = xPredicted;
points[xCount].xVal[5] = xCount;
points[xCount].yVal[5] = xError[xCount];
double xSquared = 0.0; double xSquared = 0.0;
for (i = 1; i < _arrayLength; i++) { for (i = 1; i < _arrayLength; i++) {
xSquared += pow(xSamples[xCount - 1] - xSamples[xCount - i - 1], 2); // substract direct predecessor xSquared += pow(xSamples[xCount - 1] - xSamples[xCount - i - 1], 2); // substract direct predecessor
} }
for (i = 1; i < _arrayLength; i++) { for (i = 1; i < _arrayLength; i++) {
local_weights[i][xCount+1] = local_weights[i][xCount] + learnrate * xError[xCount] * ( (xSamples[xCount - 1] - xSamples[xCount - i - 1]) / xSquared); localWeights[i + 1] = localWeights[i] + mlData->learnrate * xError[xCount] * ( (xSamples[xCount - 1] - xSamples[xCount - i - 1]) / xSquared);
fprintf( fp9, "%lf\n", localWeights[i] );
} }
fprintf(fp3, "%d\t%f\t%f\t%f\n", xCount, xPredicted, xActual, xError[xCount]);
} fprintf(fp3, "%d\t%f\t%f\t%f\n", xCount, xPredicted, xActual, xError[xCount]);
points[xCount].xVal[2] = xCount; // Fill point_t array for graph building
points[xCount].yVal[2] = xPredicted;
points[xCount].xVal[5] = xCount;
points[xCount].yVal[5] = xError[xCount];
// weightsLogger( fp, localWeights, USED_WEIGHTS );
}
fclose(fp9);
double *xErrorPtr = popNAN(xError); // delete NAN values from xError[] double *xErrorPtr = popNAN(xError); // delete NAN values from xError[]
//printf("%lf", xErrorPtr[499]); //printf("%lf", xErrorPtr[499]);
double xErrorLength = *xErrorPtr; // Watch popNAN()! double xErrorLength = *xErrorPtr; // Watch popNAN()!
@ -312,9 +343,8 @@ void directPredecessor(double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]) {
fprintf(fp3, "\nQuadratische Varianz(x_error): %f\nMittelwert:(x_error): %f\n\n", deviation, mean); fprintf(fp3, "\nQuadratische Varianz(x_error): %f\nMittelwert:(x_error): %f\n\n", deviation, mean);
fclose(fp3); fclose(fp3);
//fclose(fp2); //fclose(fp2);
free(local_weights); free(localWeights);
//weightsLogger( local_weights, USED_WEIGHTS );
} }
/* /*
@ -327,45 +357,47 @@ differential predecessor.
====================================================================================================== ======================================================================================================
*/ */
void differentialPredecessor(double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]) { void differentialPredecessor ( mldata_t *mlData, point_t points[] ) {
double (*local_weights)[WINDOWSIZE] = (double (*)[WINDOWSIZE]) malloc(sizeof(double) * (WINDOWSIZE+1) * (NUMBER_OF_SAMPLES+1)); double *localWeights = (double *) malloc ( sizeof(double) * mlData->windowSize + 1 );
memcpy(local_weights, weights, sizeof(double) * WINDOWSIZE * NUMBER_OF_SAMPLES ); memcpy( localWeights, mlData->weights, sizeof(mlData->windowSize) );
char fileName[512]; char fileName[512];
double xError[2048]; double xError[2048];
int xCount = 0, i; unsigned xCount = 0, i;
double xPredicted = 0.0; double xPredicted = 0.0;
double xActual = 0.0; double xActual = 0.0;
// File handling // File handling
mkFileName(fileName, sizeof(fileName), DIFFERENTIAL_PREDECESSOR); mkFileName(fileName, sizeof(fileName), DIFFERENTIAL_PREDECESSOR);
FILE *fp6 = fopen(fileName, "w"); FILE *fp6 = fopen(fileName, "w");
fprintf(fp6, "\n===================================== DifferentialPredecessor =====================================\nNo.\txPredicted\txAcutal\t\txError\n"); fprintf(fp6, fileHeader(DIFFERENTIAL_PREDECESSOR_HEADER) );
for (xCount = 1; xCount < NUMBER_OF_SAMPLES; xCount++) { // first value will not get predicted for (xCount = 1; xCount < mlData->samplesCount; xCount++) { // first value will not get predicted
int _arrayLength = (xCount > WINDOWSIZE) ? WINDOWSIZE + 1 : xCount; unsigned _arrayLength = (xCount > mlData->windowSize) ? mlData->windowSize + 1 : xCount;
xPredicted = 0.0; xPredicted = 0.0;
xActual = xSamples[xCount + 1]; xActual = xSamples[xCount];
for (i = 1; i < _arrayLength; i++) { for (i = 1; i < _arrayLength; i++) {
xPredicted += (local_weights[i][xCount] * (xSamples[xCount - i] - xSamples[xCount - i - 1])); xPredicted += ( localWeights[i - 1] * (xSamples[xCount - i] - xSamples[xCount - i - 1]));
} }
xPredicted += xSamples[xCount - 1]; xPredicted += xSamples[xCount - 1];
xError[xCount] = xActual - xPredicted; xError[xCount] = xActual - xPredicted;
points[xCount].xVal[3] = xCount;
points[xCount].yVal[3] = xPredicted;
points[xCount].xVal[6] = xCount;
points[xCount].yVal[6] = xError[xCount];
double xSquared = 0.0; double xSquared = 0.0;
for (i = 1; i < _arrayLength; i++) { for (i = 1; i < _arrayLength; i++) {
xSquared += pow(xSamples[xCount - i] - xSamples[xCount - i - 1], 2); // substract direct predecessor xSquared += pow(xSamples[xCount - i] - xSamples[xCount - i - 1], 2); // substract direct predecessor
} }
for (i = 1; i < _arrayLength; i++) { for (i = 1; i < _arrayLength; i++) {
local_weights[i][xCount+1] = local_weights[i][xCount] + learnrate * xError[xCount] * ((xSamples[xCount - i] - xSamples[xCount - i - 1]) / xSquared); localWeights[i+1] = localWeights[i] + mlData->learnrate * xError[xCount] * ((xSamples[xCount - i] - xSamples[xCount - i - 1]) / xSquared);
} }
fprintf(fp6, "%d\t%f\t%f\t%f\n", xCount, xPredicted, xActual, xError[xCount]); // Write to logfile fprintf(fp6, "%d\t%f\t%f\t%f\n", xCount, xPredicted, xActual, xError[xCount]); // Write to logfile
points[xCount].xVal[3] = xCount;
points[xCount].yVal[3] = xPredicted;
points[xCount].xVal[6] = xCount;
points[xCount].yVal[6] = xError[xCount];
} }
double *xErrorPtr = popNAN(xError); // delete NAN values from xError[] double *xErrorPtr = popNAN(xError); // delete NAN values from xError[]
@ -390,9 +422,9 @@ void differentialPredecessor(double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]) {
fprintf(fp6, "\nQuadratische Varianz(x_error): %f\nMittelwert:(x_error): %f\n\n", deviation, mean); fprintf(fp6, "\nQuadratische Varianz(x_error): %f\nMittelwert:(x_error): %f\n\n", deviation, mean);
//fclose(fp2); //fclose(fp2);
fclose(fp6); fclose(fp6);
free(local_weights); free(localWeights);
//weightsLogger( local_weights, USED_WEIGHTS ); // weightsLogger( localWeights, USED_WEIGHTS );
} }
/* /*
@ -427,31 +459,55 @@ Contains and returns every suffix for all existing filenames
====================================================================================================== ======================================================================================================
*/ */
char * fileSuffix(int id) { char * fileSuffix ( int id ) {
char * suffix[] = { "_weights_pure.txt", "_weights_used.txt", "_direct_predecessor.txt", "_ergebnisse.txt", "_localMean.txt","_testvalues.txt", "_differential_predecessor.txt" }; char * suffix[] = { "_weights_pure.txt",
"_weights_used.txt",
"_direct_predecessor.txt",
"_ergebnisse.txt",
"_localMean.txt",
"_testvalues.txt",
"_differential_predecessor.txt"
};
return suffix[id]; return suffix[id];
} }
/* /*
====================================================================================================== ======================================================================================================
fileHeader
Contains and returns header for 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"
};
return header[id];
}
/*
======================================================================================================
myLogger myLogger
Logs x,y points to svg graph Logs x,y points to svg graph
====================================================================================================== ======================================================================================================
*/ */
void weightsLogger (double weights[WINDOWSIZE], int val ) { void weightsLogger (double *weights, int val ) {
char fileName[512]; char fileName[512];
int i; unsigned i;
mkFileName(fileName, sizeof(fileName), val); mkFileName(fileName, sizeof(fileName), val);
FILE* fp = fopen(fileName, "wa"); FILE* fp = fopen(fileName, "wa");
for (i = 0; i < WINDOWSIZE; i++) { for (i = 0; i < mlData->windowSize - 1; i++) {
// for (int k = 0; k < WINDOWSIZE; k++) { // for (int k = 0; k < WINDOWSIZE; k++) {
fprintf(fp, "[%d]%lf\n", i, weights[i]); fprintf(fp, "[%d]%lf\n", i, weights[i]);
// } // }
} }
fprintf(fp,"\n\n\n\n=====================NEXT=====================\n"); fprintf(fp,"\n\n\n\n===================== NEXT =====================\n");
fclose(fp); fclose(fp);
} }
@ -460,30 +516,37 @@ void weightsLogger (double weights[WINDOWSIZE], int val ) {
bufferLogger bufferLogger
formats output of mkSvgGraph -- Please open graphResults.html to see the output-- formats output of mkSvgGraph -- Please open graphResults.html to see the output--
[0] = xActual,
[1] = xPredicted from localMean,
[2] = xPredicted from directPredecessor,
[3] = xPredicted from differentialpredecessor,
[4] = xError from localMean,
[5] = xError from directPredecessor,
[6] = xError from differentialPredecessor
====================================================================================================== ======================================================================================================
*/ */
void bufferLogger(char *buffer, point_t points[]) { void bufferLogger(char *buffer, point_t points[]) {
int i; unsigned i;
char _buffer[512] = ""; char _buffer[512] = "";
for (i = 0; i < NUMBER_OF_SAMPLES - 1; i++) { // xActual for (i = 0; i < mlData->samplesCount - 1; i++) { // xActual
sprintf(_buffer, "L %f %f\n", points[i].xVal[0], points[i].yVal[0]); sprintf(_buffer, "L %f %f\n", points[i].xVal[0], points[i].yVal[0]);
strcat(buffer, _buffer); strcat(buffer, _buffer);
} }
strcat(buffer, "\" fill=\"none\" id=\"svg_1\" stroke=\"black\" stroke-width=\"0.4px\"/>\n<path d=\"M0 0\n"); strcat(buffer, "\" fill=\"none\" id=\"svg_1\" stroke=\"black\" stroke-width=\"0.4px\"/>\n<path d=\"M0 0\n");
for (i = 0; i < NUMBER_OF_SAMPLES - 1; i++) { // xPredicted from localMean for (i = 0; i < mlData->samplesCount - 1; i++) { // xPredicted from localMean
sprintf(_buffer, "L %f %f\n", points[i].xVal[1], points[i].yVal[1]); sprintf(_buffer, "L %f %f\n", points[i].xVal[1], points[i].yVal[1]);
strcat(buffer, _buffer); strcat(buffer, _buffer);
} }
strcat(buffer, "\" fill=\"none\" id=\"svg_2\" stroke=\"green\" stroke-width=\"0.4px\"/>\n<path d=\"M0 0\n"); strcat(buffer, "\" fill=\"none\" id=\"svg_2\" stroke=\"green\" stroke-width=\"0.4px\"/>\n<path d=\"M0 0\n");
for (i = 0; i <= NUMBER_OF_SAMPLES - 1; i++) { //xPreddicted from directPredecessor for (i = 0; i <= mlData->samplesCount - 1; i++) { //xPreddicted from directPredecessor
sprintf(_buffer, "L %f %f\n", points[i].xVal[2], points[i].yVal[2]); sprintf(_buffer, "L %f %f\n", points[i].xVal[2], points[i].yVal[2]);
strcat(buffer, _buffer); strcat(buffer, _buffer);
} }
strcat(buffer, "\" fill=\"none\" id=\"svg_3\" stroke=\"blue\" stroke-width=\"0.4px\"/>\n<path d=\"M0 0\n"); strcat(buffer, "\" fill=\"none\" id=\"svg_3\" stroke=\"blue\" stroke-width=\"0.4px\"/>\n<path d=\"M0 0\n");
for (i = 0; i < NUMBER_OF_SAMPLES - 1; i++) { //xPredicted from diff Pred for (i = 0; i < mlData->samplesCount - 1; i++) { //xPredicted from diff Pred
sprintf(_buffer, "L %f %f\n", points[i].xVal[3], points[i].yVal[3]); sprintf(_buffer, "L %f %f\n", points[i].xVal[3], points[i].yVal[3]);
strcat(buffer, _buffer); strcat(buffer, _buffer);
} }
@ -521,12 +584,12 @@ returns length of new array without NAN values
====================================================================================================== ======================================================================================================
*/ */
double *popNAN(double *xError) { double *popNAN(double *xError) {
int i, counter = 1; unsigned i, counter = 1;
double tmpLength = 0.0; double tmpLength = 0.0;
double *tmp = NULL; double *tmp = NULL;
double *more_tmp = NULL; double *more_tmp = NULL;
for ( i = 0; i < NUMBER_OF_SAMPLES; i++ ) { for ( i = 0; i < mlData->samplesCount - 1; i++ ) {
counter ++; counter ++;
more_tmp = (double *) realloc ( tmp, counter*(sizeof(double) )); more_tmp = (double *) realloc ( tmp, counter*(sizeof(double) ));
if ( !isnan(xError[i]) ) { if ( !isnan(xError[i]) ) {
@ -701,26 +764,26 @@ gets one of the rgb color channels and writes them to a file
====================================================================================================== ======================================================================================================
*/ */
int ppmColorChannel(FILE* fp, imagePixel_t *image, char *colorChannel) { int ppmColorChannel(FILE* fp, imagePixel_t *image, char *colorChannel, mldata_t *mlData) {
// int length = (image->x * image->y) / 3; // int length = (image->x * image->y) / 3;
int i = 0; unsigned i = 0;
printf("colorChannel in Function: %s", colorChannel); printf("colorChannel in Function: %s", colorChannel);
if (image) { if (image) {
if (strcmp(colorChannel, "green") == 0){ if (strcmp(colorChannel, "green") == 0){
for (i = 0; i < NUMBER_OF_SAMPLES - 1; i++) { for (i = 0; i < mlData->samplesCount - 1; i++) {
fprintf(fp, "%d\n", image->data[i].green); fprintf(fp, "%d\n", image->data[i].green);
printf("|"); printf("|");
} }
} else if (strcmp(colorChannel, "red") == 0){ } else if (strcmp(colorChannel, "red") == 0){
for (i = 0; i < NUMBER_OF_SAMPLES - 1; i++) { for (i = 0; i < mlData->samplesCount - 1; i++) {
fprintf(fp, "%d\n", image->data[i].red); fprintf(fp, "%d\n", image->data[i].red);
printf("."); printf(".");
} }
} else if (strcmp(colorChannel, "blue") == 0 ) { } else if (strcmp(colorChannel, "blue") == 0 ) {
for (i = 0; i < NUMBER_OF_SAMPLES - 1; i++ ) { for (i = 0; i < mlData->samplesCount - 1; i++ ) {
fprintf(fp, "%d\n", image->data[i].blue); fprintf(fp, "%d\n", image->data[i].blue);
printf("/"); printf("/");
} }
@ -730,7 +793,7 @@ int ppmColorChannel(FILE* fp, imagePixel_t *image, char *colorChannel) {
} }
} }
fclose(fp); fclose(fp);
return NUMBER_OF_SAMPLES; return mlData->samplesCount;
} }
/* /*
@ -743,12 +806,12 @@ creating the SVG graph
====================================================================================================== ======================================================================================================
*/ */
void colorSamples(FILE* fp) { void colorSamples ( FILE* fp, mldata_t *mlData ) {
int i = 0; int i = 0;
char buffer[NUMBER_OF_SAMPLES]; //char buffer[NUMBER_OF_SAMPLES];
char *buffer = (char *) malloc(sizeof(char) * mlData->samplesCount);
while (!feof(fp)) { while (!feof(fp)) {
if (fgets(buffer, NUMBER_OF_SAMPLES, fp) != NULL) { if (fgets(buffer, mlData->samplesCount, fp) != NULL) {
sscanf(buffer, "%lf", &xSamples[i]); sscanf(buffer, "%lf", &xSamples[i]);
//printf("%lf\n", xSamples[i] ); //printf("%lf\n", xSamples[i] );
points[i].yVal[0] = xSamples[i]; points[i].yVal[0] = xSamples[i];
@ -792,12 +855,31 @@ void usage ( void ) {
printf("POSIX options:\n"); printf("POSIX options:\n");
printf("\t-h\t\t\tDisplay this information.\n"); printf("\t-h\t\t\tDisplay this information.\n");
printf("\t-i <filename>\t\tName of inputfile. Must be PPM image.\n"); printf("\t-i <filename>\t\tName of inputfile. Must be PPM image.\n");
printf("\t-n <digit>\t\tAmount of input data used.\n");
printf("\t-c <color>\t\tUse this color channel from inputfile.\n"); printf("\t-c <color>\t\tUse this color channel from inputfile.\n");
printf("\t-w <digit>\t\tCount of used weights (windowSize).\n"); printf("\t-w <digit>\t\tCount of used weights (windowSize).\n");
printf("\t-l <digit>\t\tLearnrate, 0 < learnrate < 1.\n");
printf("\t-s <digit>\t\tDigit for random seed generator.\n\t\t\t\tSame Digits produce same random values. Default is srand by time."); printf("\t-s <digit>\t\tDigit for random seed generator.\n\t\t\t\tSame Digits produce same random values. Default is srand by time.");
printf("\n\n"); printf("\n\n");
printf("lms compares prediction methods of least mean square methods.\nBy default it reads ppm file format and return logfiles as well\nas an svg graphs as an output of said least mean square methods.\n\nExample:\n\tlms -i myimage.ppm -w 3 -c green -s 5\n"); printf("lms compares prediction methods of least mean square methods.\nBy default it reads ppm file format and return logfiles as well\nas an svg graphs as an output of said least mean square methods.\n\nExample:\n\tlms -i myimage.ppm -w 3 -c green -s 5\n");
exit(8); exit(8);
} }
/*
======================================================================================================
init_mldata_t
Contains meachine learning data
======================================================================================================
*/
mldata_t * init_mldata_t(unsigned windowSize, unsigned samplesCount, double learnrate) {
mlData = (mldata_t *) malloc( sizeof(mldata_t) );
mlData->windowSize = windowSize;
mlData->samplesCount = samplesCount;
mlData->learnrate = learnrate;
mlData->weights = (double *) malloc ( sizeof(double) * windowSize + 1 );
return mlData;
}

View File

@ -20,7 +20,15 @@ Use `$ ./lms -h` for help.
### Usage ### Usage
coming soon ... There are a bunch of options you can predefine but do not have to. The only parameter needed is __-i__ which is the inputfile.
| Parameter | Description | StdVal |
|----------:|:-----------------------------:|-------:|
| -i | The inputfile, has to be PPM | none |
| -n | Amount of input data used | 500 |
| -w | Size of M (window) | 5 |
| -c | Choose RGB color channel | green |
| -l | Learnrate of machine learning | 0.8 |
| -s | Reproducable seed randomizing weights. Choose for repoducability. | time(NULL)|
This code is ANSI compatible no POSIX, C99, C11 or GNU libs, because it had to be VS compatible . There are way easier methods like getline() or getopt(), I know ... This code is ANSI compatible no POSIX, C99, C11 or GNU libs, because it had to be VS compatible . There are way easier methods like getline() or getopt(), I know ...