diff --git a/bin/ANSI_C_Implementation/.DS_Store b/bin/ANSI_C_Implementation/.DS_Store new file mode 100644 index 0000000..4c8fc57 Binary files /dev/null and b/bin/ANSI_C_Implementation/.DS_Store differ diff --git a/bin/ANSI_C_Implementation/Makefile b/bin/ANSI_C_Implementation/Makefile new file mode 100644 index 0000000..7023380 --- /dev/null +++ b/bin/ANSI_C_Implementation/Makefile @@ -0,0 +1,6 @@ +all: NLMSvariants.c + gcc -o lms NLMSvariants.c + +clean: + $(RM) lms + diff --git a/bin/ANSI_C_Implementation/NLMSvariants.c b/bin/ANSI_C_Implementation/NLMSvariants.c new file mode 100644 index 0000000..36d3a10 --- /dev/null +++ b/bin/ANSI_C_Implementation/NLMSvariants.c @@ -0,0 +1,789 @@ +// +// +// NLMSvariants.c +// +// Created by FBRDNLMS on 26.04.18. +// +// +#include +#include +#include +#include +#include +#include // DBL_MAX + +#define NUMBER_OF_SAMPLES 500 +#define WINDOWSIZE 5 +#define learnrate 0.8 +#define RGB_COLOR 255 +#if defined(_MSC_VER) +#include +typedef SSIZE_T ssize_t; +#endif + +enum fileSuffix_t{ // used in conjunction with mkFileName() + PURE_WEIGHTS, + USED_WEIGHTS, + DIRECT_PREDECESSOR, + RESULTS, + LOCAL_MEAN, + TEST_VALUES, + DIFFERENTIAL_PREDECESSOR +}; + +double xSamples[NUMBER_OF_SAMPLES] = { 0.0 }; + +/* *svg graph building* */ +typedef struct { + double xVal[7]; + double yVal[7]; +}point_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 + +/* *ppm read, copy, write* */ +typedef struct { + unsigned char red, green, blue; +}colorChannel_t; + +typedef struct { + int x, y; + colorChannel_t *data; +}imagePixel_t; + +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 +void colorSamples(FILE* fp); // stores color channel values in xSamples[] + +/* *file handling* */ +char * mkFileName(char* buffer, size_t max_len, int suffixId); +char *fileSuffix(int id); +void myLogger(FILE* fp, point_t points[]); +void mkSvgGraph(point_t points[]); +//void weightsLogger(double *weights, int var); +/* *rand seed* */ +double r2(void); +double rndm(void); + +/* *math* */ +double sum_array(double x[], int length); +void directPredecessor(double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]); +void localMean(double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]); +void differentialPredecessor(double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]); +//void differentialPredecessor(double *weights); +double *popNAN(double *xError); //return new array without NAN values +double windowXMean(int _arraylength, int xCount); + + +//int main(int argc, char **argv) { +int main( void ) { + double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]; // = { { 0.0 }, {0.0} }; +// double local_weights[WINDOWSIZE][NUMBER_OF_SAMPLES]; + char fileName[50]; + int i,k, xLength; + imagePixel_t *image; + + image = rdPPM("cow.ppm"); + mkFileName(fileName, sizeof(fileName), TEST_VALUES); + FILE* fp5 = fopen(fileName, "w"); + xLength = ppmColorChannel(fp5, image); + printf("%d\n", xLength); + FILE* fp6 = fopen(fileName, "r"); + colorSamples(fp6); + + srand( (unsigned int)time(NULL) ); + for (i = 0; i < NUMBER_OF_SAMPLES; i++) { + for (int k = 0; k < WINDOWSIZE; k++) { + weights[k][i] = rndm(); // Init weights + } + } + mkFileName(fileName, sizeof(fileName), PURE_WEIGHTS); + // save plain test_array before math magic happens + FILE *fp0 = fopen(fileName, "w"); + for (i = 0; i < NUMBER_OF_SAMPLES; i++) { + for (k = 0; k < WINDOWSIZE; k++) { + fprintf(fp0, "[%d][%d]%lf\n", k, i, weights[k][i]); + } + } + fclose(fp0); + // math magic + localMean(weights); + directPredecessor(weights); + differentialPredecessor(weights); + mkSvgGraph(points); + // save test_array after math magic happened + // memset( fileName, '\0', sizeof(fileName) ); +/* mkFileName(fileName, sizeof(fileName), USED_WEIGHTS); + FILE *fp1 = fopen(fileName, "w"); + for (i = 0; i < tracking; i++) { + for (int k = 0; k < WINDOWSIZE; k++) { + fprintf(fp1, "[%d][%d] %lf\n", k, i, w[k][i]); + } + + } + fclose(fp1); +*/ + printf("\nDONE!\n"); +} + + +/* +====================================================================================================== + +localMean + +Variant (1/3), substract local mean. + +====================================================================================================== +*/ + +void localMean(double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]) { + //double local_weights[WINDOWSIZE][NUMBER_OF_SAMPLES]; + double (*local_weights)[WINDOWSIZE] = malloc(sizeof(double) * (WINDOWSIZE+1) * (NUMBER_OF_SAMPLES+1)); +// double *local_weights[WINDOWSIZE]; + memcpy(local_weights, weights, sizeof(double) * WINDOWSIZE * NUMBER_OF_SAMPLES); + char fileName[50]; + double xError[2048]; // includes e(n) + memset(xError, 0.0, NUMBER_OF_SAMPLES);// initialize xError-array with Zero + int xCount = 0, i; // runtime var; + mkFileName(fileName, sizeof(fileName), LOCAL_MEAN); + FILE* fp4 = fopen(fileName, "w"); + fprintf(fp4, "\n=====================================LocalMean=====================================\nNo.\txPredicted\txActual\t\txError\n"); + + double xMean = xSamples[0]; + double xSquared = 0.0; + double xPredicted = 0.0; + double xActual = 0.0; + + for (xCount = 1; xCount < NUMBER_OF_SAMPLES; xCount++) { // first value will not get predicted + + int _arrayLength = ( xCount > WINDOWSIZE ) ? WINDOWSIZE + 1 : xCount; + xMean = (xCount > 0) ? windowXMean(_arrayLength, xCount) : 0; + xPredicted = 0.0; + xActual = xSamples[xCount + 1]; + // weightedSum += _x[ xCount-1 ] * w[xCount][0]; + + for (i = 1; i < _arrayLength; i++) { //get predicted value + xPredicted += (local_weights[i][xCount] * (xSamples[xCount - i] - xMean)); + } + xPredicted += xMean; + xError[xCount] = xActual - xPredicted; + points[xCount].xVal[1] = xCount; + points[xCount].yVal[1] = xPredicted; + points[xCount].xVal[4] = 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 xErrorLength = *xErrorPtr; // Watch popNAN()! + xErrorPtr[0] = 0.0; + printf("Xerrorl:%lf", xErrorLength); + double mean = sum_array(xErrorPtr, xErrorLength) / xErrorLength; + double deviation = 0.0; + + // Mean square + for (i = 1; i < xErrorLength; i++) { + deviation += pow(xError[i] - mean, 2); + } + deviation /= xErrorLength; + printf("mean:%lf, devitation:%lf", mean, deviation); + + // write in file + //mkFileName(fileName, sizeof(fileName), RESULTS); + //FILE *fp2 = fopen(fileName, "w"); + fprintf(fp4, "\nQuadratische Varianz(x_error): %f\nMittelwert:(x_error): %f\n\n", deviation, mean); + //fclose(fp2); + free(local_weights); + fclose(fp4); + + //weightsLogger( local_weights, USED_WEIGHTS ); +} + +/* +====================================================================================================== + +directPredecessor + +Variant (2/3), +substract direct predecessor + +====================================================================================================== +*/ + +void directPredecessor(double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]) { + double (*local_weights)[WINDOWSIZE] = malloc(sizeof(double) * (WINDOWSIZE+1) * (NUMBER_OF_SAMPLES+1)); + +// double local_weights[WINDOWSIZE][NUMBER_OF_SAMPLES]; + memcpy(local_weights, weights, sizeof(double) * WINDOWSIZE * NUMBER_OF_SAMPLES ); + char fileName[512]; + double xError[2048]; + int xCount = 0, i; + double xActual = 0.0; + double xPredicted = 0.0; + // File handling + mkFileName(fileName, sizeof(fileName), DIRECT_PREDECESSOR); + FILE *fp3 = fopen(fileName, "w"); + fprintf(fp3, "\n=====================================DirectPredecessor=====================================\nNo.\txPredicted\txAcutal\t\txError\n"); + + + for (xCount = 1; xCount < NUMBER_OF_SAMPLES; xCount++) { // first value will not get predicted + //double xPartArray[1000]; //includes all values at the size of runtime var + //int _sourceIndex = (xCount > WINDOWSIZE) ? xCount - WINDOWSIZE : xCount; + int _arrayLength = (xCount > WINDOWSIZE) ? WINDOWSIZE + 1 : xCount; + //printf("xCount:%d, length:%d\n", xCount, _arrayLength); + // printf("WINDOWSIZE:%f\n", windowXMean(_arrayLength, xCount)); + xPredicted = 0.0; + xActual = xSamples[xCount + 1]; + // weightedSum += _x[ xCount-1 ] * w[xCount][0]; + + for (i = 1; i < _arrayLength; i++) { + xPredicted += (local_weights[i][xCount] * (xSamples[xCount - 1] - xSamples[xCount - i - 1])); + } + xPredicted += xSamples[xCount - 1]; + xError[xCount] = xActual - xPredicted; + + //fprintf(fp3, "{%d}.\txPredicted{%f}\txActual{%f}\txError{%f}\n", xCount, xPredicted, xActual, xError[xCount]); + points[xCount].xVal[2] = xCount; + points[xCount].yVal[2] = xPredicted; + points[xCount].xVal[5] = xCount; + points[xCount].yVal[5] = xError[xCount]; + + double xSquared = 0.0; + + for (i = 1; i < _arrayLength; i++) { + xSquared += pow(xSamples[xCount - 1] - xSamples[xCount - i - 1], 2); // substract direct predecessor + } + 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); + } + fprintf(fp3, "%d\t%f\t%f\t%f\n", xCount, xPredicted, xActual, xError[xCount]); + } + + double *xErrorPtr = popNAN(xError); // delete NAN values from xError[] + //printf("%lf", xErrorPtr[499]); + double xErrorLength = *xErrorPtr; // Watch popNAN()! + xErrorPtr[0] = 0.0; + printf("Xerrorl:%lf", xErrorLength); + + double mean = sum_array(xErrorPtr, xErrorLength) / xErrorLength; + double deviation = 0.0; + + // Mean square + for (i = 1; i < xErrorLength; i++) { + deviation += pow(xError[i] - mean, 2); + } + deviation /= xErrorLength; + printf("mean:%lf, devitation:%lf", mean, deviation); + + // write in file + //mkFileName(fileName, sizeof(fileName), RESULTS); + //FILE *fp2 = fopen(fileName, "wa"); + fprintf(fp3, "\nQuadratische Varianz(x_error): %f\nMittelwert:(x_error): %f\n\n", deviation, mean); + fclose(fp3); + //fclose(fp2); + free(local_weights); + + //weightsLogger( local_weights, USED_WEIGHTS ); +} + + +/* +====================================================================================================== + +differentialPredecessor + +variant (3/3), +differential predecessor. + +====================================================================================================== +*/ +void differentialPredecessor(double weights[WINDOWSIZE][NUMBER_OF_SAMPLES]) { +// double local_weights[WINDOWSIZE][NUMBER_OF_SAMPLES]; + double (*local_weights)[WINDOWSIZE] = malloc(sizeof(double) * (WINDOWSIZE+1) * (NUMBER_OF_SAMPLES+1)); + + memcpy(local_weights, weights, sizeof(double) * WINDOWSIZE * NUMBER_OF_SAMPLES ); + char fileName[512]; + double xError[2048]; + int xCount = 0, i; + double xPredicted = 0.0; + double xActual = 0.0; + + // File handling + mkFileName(fileName, sizeof(fileName), DIFFERENTIAL_PREDECESSOR); + FILE *fp6 = fopen(fileName, "w"); + fprintf(fp6, "\n=====================================DifferentialPredecessor=====================================\nNo.\txPredicted\txAcutal\t\txError\n"); + + for (xCount = 1; xCount < NUMBER_OF_SAMPLES; xCount++) { // first value will not get predicted + + int _arrayLength = (xCount > WINDOWSIZE) ? WINDOWSIZE + 1 : xCount; + xPredicted = 0.0; + xActual = xSamples[xCount + 1]; + + for (i = 1; i < _arrayLength; i++) { + xPredicted += (local_weights[i][xCount] * (xSamples[xCount - i] - xSamples[xCount - i - 1])); + } + xPredicted += xSamples[xCount - 1]; + xError[xCount] = xActual - xPredicted; + + //fprintf(fp6, "{%d}.\txPredicted{%f}\txActual{%f}\txError{%f}\n", xCount, xPredicted, xActual, xError[xCount]); + 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; + + for (i = 1; i < _arrayLength; i++) { + xSquared += pow(xSamples[xCount - i] - xSamples[xCount - i - 1], 2); // substract direct predecessor + } + 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); + } + fprintf(fp6, "%d\t%f\t%f\t%f\n", xCount, xPredicted, xActual, xError[xCount]); + } + +/* int xErrorLength = sizeof(xError) / sizeof(xError[0]); + printf("vor:%d", xErrorLength); + popNAN(xError); + printf("nach:%d", xErrorLength); + xErrorLength = sizeof(xError) / sizeof(xError[0]); + double mean = sum_array(xError, xErrorLength) / xErrorLength; + double deviation = 0.0; + + for (i = 0; i < xErrorLength - 1; i++) { + deviation += pow(xError[i] - mean, 2); + } + deviation /= xErrorLength; + + //mkSvgGraph(points); + fprintf(fp6, "{%d}.\tLeast Mean Squared{%f}\tMean{%f}\n\n", xCount, deviation, mean); +*/ + double *xErrorPtr = popNAN(xError); // delete NAN values from xError[] + //printf("%lf", xErrorPtr[499]); + double xErrorLength = *xErrorPtr; // Watch popNAN()! + xErrorPtr[0] = 0.0; + printf("Xerrorl:%lf", xErrorLength); + + double mean = sum_array(xErrorPtr, xErrorLength) / xErrorLength; + double deviation = 0.0; + + // Mean square + for (i = 1; i < xErrorLength; i++) { + deviation += pow(xError[i] - mean, 2); + } + deviation /= xErrorLength; + printf("mean:%lf, devitation:%lf", mean, deviation); + + // write in file + //mkFileName(fileName, sizeof(fileName), RESULTS); + //FILE *fp2 = fopen(fileName, "wa"); + fprintf(fp6, "\nQuadratische Varianz(x_error): %f\nMittelwert:(x_error): %f\n\n", deviation, mean); + //fclose(fp2); + fclose(fp6); + free(local_weights); + + //weightsLogger( local_weights, USED_WEIGHTS ); +} + + +/* +====================================================================================================== + +mkFileName + +Writes the current date plus the suffix with index suffixId +into the given buffer. If the total length is longer than max_len, +only max_len characters will be written. + +====================================================================================================== + +*/ + +char *mkFileName(char* buffer, size_t max_len, int suffixId) { + const char * format_str = "%Y-%m-%d_%H_%M_%S"; + size_t date_len; + const char * suffix = fileSuffix(suffixId); + time_t now = time(NULL); + + strftime(buffer, max_len, format_str, localtime(&now)); + date_len = strlen(buffer); + strncat(buffer, suffix, max_len - date_len); + return buffer; +} + + +/* +====================================================================================================== + +fileSuffix + +Contains and returns every suffix for all existing filenames + +====================================================================================================== +*/ + +char * fileSuffix(int id) { + char * suffix[] = { "_weights_pure.txt", "_weights_used.txt", "_direct_predecessor.txt", "_ergebnisse.txt", "_localMean.txt","_testvalues.txt", "_differential_predecessor.txt" }; + return suffix[id]; +} + + +/* +====================================================================================================== + +myLogger + +Logs x,y points to svg graph + +====================================================================================================== +*/ + +void weightsLogger (double weights[WINDOWSIZE], int val ) { + char fileName[512]; + int i; + mkFileName(fileName, sizeof(fileName), val); + FILE* fp = fopen(fileName, "wa"); + for (i = 0; i < WINDOWSIZE; i++) { + // for (int k = 0; k < WINDOWSIZE; k++) { + fprintf(fp, "[%d]%lf\n", i, weights[i]); + // } + } + fprintf(fp,"\n\n\n\n=====================NEXT=====================\n"); + fclose(fp); +} + + +/* +====================================================================================================== + +bufferLogger + +formats output of mkSvgGraph -- Please open graphResults.html to see the output-- + +====================================================================================================== +*/ + +void bufferLogger(char *buffer, point_t points[]) { + int i; + char _buffer[512] = ""; + + for (i = 0; i < NUMBER_OF_SAMPLES - 1; i++) { // xActual + sprintf(_buffer, "L %f %f\n", points[i].xVal[0], points[i].yVal[0]); + strcat(buffer, _buffer); + } + strcat(buffer, "\" fill=\"none\" id=\"svg_1\" stroke=\"black\" stroke-width=\"0.4px\"/>\n\n\n\n"); +} + + +/* +====================================================================================================== + +sum_array + +Sum of all elements in x within a defined length + +====================================================================================================== +*/ + +double sum_array(double x[], int xlength) { + int i = 0; + double sum = 0.0; + + if (xlength != 0) { + for (i = 0; i < xlength; i++) { + sum += x[i]; + } + } + return sum; +} + + +/* +====================================================================================================== + +popNanLength + +returns length of new array without NAN values + +====================================================================================================== +*/ + +double *popNAN(double *xError) { + int i, counter = 1; + double tmpLength = 0.0; + double *tmp = NULL; + double *more_tmp = NULL; + + for ( i = 0; i < NUMBER_OF_SAMPLES; i++ ) { + counter ++; + more_tmp = (double *) realloc ( tmp, counter*(sizeof(double) )); + if ( !isnan(xError[i]) ) { + tmp = more_tmp; + tmp[counter - 1] = xError[i]; + printf("xERROR:%lf\n", tmp[counter - 1]); + tmpLength++; + } + } + counter += 1; + more_tmp = (double *) realloc ( tmp, counter * sizeof(double) ); + tmp = more_tmp; + *tmp = tmpLength; // Length of array has to be stored in tmp[0], + // Cause length is needed later on in the math functions. + // xError counting has to begin with 1 in the other functions ! + printf("tmpLength in tmp:%lf, %lf\n", tmp[counter-2], *tmp); + return tmp; + +} +/* +====================================================================================================== + +r2 + +returns a random double value between 0 and 1 + +====================================================================================================== +*/ + +double r2(void) { + return((rand() % 10000) / 10000.0); +} + + +/* +====================================================================================================== + +rndm + +fills a double variable with random value and returns it + +====================================================================================================== +*/ + +double rndm(void) { + double rndmval = r2(); + return rndmval; +} + + +/* +====================================================================================================== + +mkSvgGraph + +parses template.svg and writes results in said template + +====================================================================================================== +*/ + +void mkSvgGraph(point_t points[]) { + FILE *input = fopen("graphResults_template.html", "r"); + FILE *target = fopen("graphResults.html", "w"); + char line[512]; + char firstGraph[15] = { "x, &image->y) != 2) { + fprintf(stderr, "Invalid image size in %s\n", fileName); + exit(EXIT_FAILURE); + } + if (fscanf(fp, "%d", &rgbColor) != 1) { + fprintf(stderr, "Invalid rgb component in %s\n", fileName); + } + if (rgbColor != RGB_COLOR) { + fprintf(stderr, "Invalid image color range in %s\n", fileName); + exit(EXIT_FAILURE); + } + while (fgetc(fp) != '\n'); + image->data = (colorChannel_t *)malloc(image->x * image->y * sizeof(imagePixel_t)); + if (!image) { + fprintf(stderr, "malloc() failed"); + exit(EXIT_FAILURE); + } + if (fread(image->data, 3 * image->x, image->y, fp) != image->y) { + fprintf(stderr, "Loading image failed"); + exit(EXIT_FAILURE); + } + fclose(fp); + return image; +} + + +/* +====================================================================================================== + +mkPpmFile + +gets output from the result of rdPpmFile and writes a new PPM file. Best Case is a +carbon copy of the source image. Build for debugging + +====================================================================================================== +*/ + +void mkPpmFile(char *fileName, imagePixel_t *image) { + FILE* fp = fopen(fileName, "wb"); + if (!fp) { + fprintf(stderr, "Opening file failed."); + exit(EXIT_FAILURE); + } + fprintf(fp, "P6\n"); + fprintf(fp, "%d %d\n", image->x, image->y); + fprintf(fp, "%d\n", RGB_COLOR); + fwrite(image->data, 3 * image->x, image->y, fp); + fclose(fp); +} + + +/* +====================================================================================================== + +ppmColorChannel + +gets one of the rgb color channels and writes them to a file + +====================================================================================================== +*/ + +int ppmColorChannel(FILE* fp, imagePixel_t *image) { + // int length = (image->x * image->y) / 3; + int i = 0; + + if (image) { + for (i = 0; i < NUMBER_OF_SAMPLES - 1; i++) { + fprintf(fp, "%d\n", image->data[i].green); + } + } + fclose(fp); + return NUMBER_OF_SAMPLES; +} + + +/* +====================================================================================================== + +colorSamples + +reads colorChannel values from file and stores them in xSamples as well as points datatype for +creating the SVG graph + +====================================================================================================== +*/ +void colorSamples(FILE* fp) { + int i = 0; + char buffer[NUMBER_OF_SAMPLES]; + + while (!feof(fp)) { + if (fgets(buffer, NUMBER_OF_SAMPLES, fp) != NULL) { + sscanf(buffer, "%lf", &xSamples[i]); + //printf("%lf\n", xSamples[i] ); + points[i].yVal[0] = xSamples[i]; + points[i].xVal[0] = i; + ++i; + } + } + fclose(fp); +} + + +/* +====================================================================================================== + +windowXMean + +returns mean value of given input, which has a length of WINDOWSIZE + +====================================================================================================== +*/ + +double windowXMean(int _arraylength, int xCount) { + double sum = 0.0; + double *ptr; + + for (ptr = &xSamples[xCount - _arraylength]; ptr != &xSamples[xCount]; ptr++) { //set ptr to beginning of window + sum += *ptr; + } + return sum / (double)_arraylength; +} + + diff --git a/bin/ANSI_C_Implementation/graphResults_template.html b/bin/ANSI_C_Implementation/graphResults_template.html new file mode 100644 index 0000000..5205a76 --- /dev/null +++ b/bin/ANSI_C_Implementation/graphResults_template.html @@ -0,0 +1,62 @@ + + + + + NLMSvariants | Graphical Output || + Eingangswert | + direkter Vorgaenger | + letzter Mittelwert + + + + + NLMSvariants output graph + + + + + + + + + + + + + + + + + + + + + - + + + - + - - + + + + + + + + + +
+

+ Eingangswert | + direkter Vorgaenger | + letzter Mittelwert +

+