This commit is contained in:
kbecke23 2018-06-11 15:50:32 +02:00
parent aa84dad655
commit 8da6a017b2
1 changed files with 160 additions and 87 deletions

View File

@ -11,7 +11,7 @@ Created by Stefan Friese on 26.04.2018
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "nlms_types.h"
#include "nlms_types.h" // added types
#define RGB_COLOR 255
#if defined(_MSC_VER)
@ -19,24 +19,25 @@ Created by Stefan Friese on 26.04.2018
typedef SSIZE_T ssize_t;
#endif
double *xSamples; // Input color values from PPM
mldata_t *mlData = NULL; // Machine learning realted data
double *xSamples; // Input values
mldata_t *mlData = NULL; // Machine learning
point_t *points = NULL; // Graphing
/* *Graph building* */
/* *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* */
char * mkFileName(char* buffer, // Date+suffix as filename
/* *file handling* */
char * mkFileName(char* buffer,
size_t max_len, int suffixId);
char *fileSuffix(int id); // Filename ending of logs
char *fileSuffix(int id);
char *fileHeader(int id); // Header inside the logfiles
//void myLogger ( FILE* fp, point_t points[] );
void bufferLogger(char *buffer, point_t points[]); // Writes points to graph template
void mkSvgGraph(point_t points[], char *templatePath); // Parses graph template and calls bufferLogger()
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* */
@ -54,9 +55,11 @@ 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
double *popNAN(double *xError); // Returns array without NAN values, if any exist
double windowXMean(int _arraylength, int xCount); // Returns mean value of given window
int main(int argc, char **argv) {
char *colorChannel = (char *)malloc(sizeof(char) * 32);
char *inputfile = (char *)malloc(sizeof(char) * 32);
@ -64,12 +67,12 @@ int main(int argc, char **argv) {
unsigned k, include = 0;
unsigned windowSize = 5;
unsigned samplesCount = 512;
char *stdcolor = (char*)"green", xBuffer[512];
char *stdcolor = "green", xBuffer[512];
colorChannel = stdcolor;
unsigned int uint_buffer[1], windowBuffer[1];
double learnrate = 0.4;
char *istrue = (char*)"true";
char *templatePath = NULL;
char *istrue = "true";
while ((argc > 1) && (argv[1][0] == '-')) { // Parses parameters from stdin
switch (argv[1][1]) {
@ -114,10 +117,6 @@ int main(int argc, char **argv) {
if (strstr(xBuffer, istrue)) {
include = 1;
}
else if (xBuffer && !strstr(xBuffer, istrue)) {
templatePath = xBuffer;
include = 1;
}
else {
printf("Wrong Argruments: %s\n", argv[1]);
usage(argv);
@ -144,7 +143,8 @@ int main(int argc, char **argv) {
char fileName[50]; // Logfiles and their names
mkFileName(fileName, sizeof(fileName), TEST_VALUES);
FILE* fp5 = fopen(fileName, "w");
ppmColorChannel(fp5, image, colorChannel, mlData);
//xLength =
ppmColorChannel(fp5, image, colorChannel, mlData); // Returns length of ppm input values, debugging
FILE* fp6 = fopen(fileName, "r");
colorSamples(fp6, mlData);
@ -163,19 +163,22 @@ int main(int argc, char **argv) {
printf("[%d] %lf\n", k, mlData->weights[k]);
}
mkFileName(fileName, sizeof(fileName), PURE_WEIGHTS); // Logfile weights
FILE *fp0 = fopen(fileName, "w");
for (k = 0; k < mlData->windowSize; k++) {
fprintf(fp0, "[%d]%lf\n", k, mlData->weights[k]);
}
fclose(fp0);
localMean(mlData, points); // math magic functions
/* *math magic* */
localMean(mlData, points);
directPredecessor(mlData, points);
differentialPredecessor(mlData, points);
if (include == 1) {
mkSvgGraph(points, templatePath); // Graph building
mkSvgGraph(points); // Graph building
}
@ -197,14 +200,13 @@ Variant (1/3), substract local mean.
*/
void localMean(mldata_t *mlData, point_t points[]) {
double *localWeights = (double *)malloc(sizeof(double) * mlData->windowSize + 1);
localWeights = mlData->weights;
memcpy(localWeights, mlData->weights, sizeof(double) * mlData->windowSize + 1);
//localWeights = mlData->weights;
char fileName[50];
unsigned xErrorLength = mlData->samplesCount;
double *xError = (double *)malloc(sizeof(double) * xErrorLength+1);
memset(xError, 0.0, sizeof(double) * xErrorLength);
unsigned i, xCount = 0; // Runtime vars
double *xError = (double *)malloc(sizeof(double) * mlData->samplesCount + 1); // Includes e(n)
memset(xError, 0.0, mlData->samplesCount); // Initialize xError-array with Zero
unsigned i, xCount = 0; // Runtime vars
mkFileName(fileName, sizeof(fileName), LOCAL_MEAN); // Create Logfile and its filename
FILE* fp4 = fopen(fileName, "w");
@ -219,7 +221,7 @@ void localMean(mldata_t *mlData, point_t points[]) {
double xPredicted = 0.0;
double xActual = 0.0;
for (xCount = 1; xCount < mlData->samplesCount - 1; xCount++) { // First value will not get predicted
for (xCount = 1; xCount < mlData->samplesCount - 1; xCount++) { // First value will not get predicted
unsigned _arrayLength = (xCount > mlData->windowSize) ? mlData->windowSize + 1 : xCount; // Ensures corect length at start
xMean = (xCount > 0) ? windowXMean(_arrayLength, xCount) : 0;
xPredicted = 0.0;
@ -232,13 +234,14 @@ void localMean(mldata_t *mlData, point_t points[]) {
xError[xCount] = xActual - xPredicted; // Get error value
xSquared = 0.0;
for (i = 1; i < _arrayLength; i++) { // Get xSquared
xSquared += pow(xSamples[xCount - i] - xMean, 2);
double x = xSamples[xCount - i] - xMean;
xSquared += x * x;
}
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] = localWeights[i - 1] + mlData->learnrate * xError[xCount] // Substract localMean
localWeights[i-1] = localWeights[i - 1] + mlData->learnrate * xError[xCount] // Substract localMean
* ((xSamples[xCount - i] - xMean) / xSquared);
fprintf(fp9, "%lf\n", localWeights[i]);
}
@ -253,17 +256,27 @@ void localMean(mldata_t *mlData, point_t points[]) {
}
fclose(fp9);
double mean = sum_array(xError, xErrorLength) / xErrorLength; // Mean
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; // Mean
double deviation = 0.0;
for (i = 1; i < xErrorLength; i++) { // Mean square
deviation += pow(xError[i] - mean, 2);
double x = xError[i] - mean;
deviation += x*x;
}
deviation /= xErrorLength; // Deviation
printf("mean square err: %lf, variance: %lf\t\tlocal Mean\n", mean, deviation);
printf("mean:%lf, devitation:%lf\t\tlocal Mean\n", mean, deviation);
fprintf(fp4, "\nQuadratische Varianz(x_error): %f\nMittelwert:(x_error): %f\n\n", deviation, mean); // Write to logfile
//free(localWeights);
free(xErrorPtr);
free(xError);
fclose(fp4);
//weightsLogger( local_weights, USED_WEIGHTS );
}
/*
@ -278,24 +291,24 @@ substract direct predecessor
*/
void directPredecessor(mldata_t *mlData, point_t points[]) {
double *localWeights = (double *)malloc(sizeof(double) * mlData->windowSize + 1);
localWeights = mlData->weights;
memcpy(localWeights, mlData->weights, sizeof(double) * mlData->windowSize + 1);
//localWeights = mlData->weights;
char fileName[512];
const unsigned xErrorLength = mlData->samplesCount;
double *xError = (double *)malloc(sizeof(double) * xErrorLength);
memset(xError, 0.0, sizeof(double) * xErrorLength);
double *xError = (double *)malloc(sizeof(double) * mlData->samplesCount + 1);
memset(xError, 0.0, mlData->samplesCount);
unsigned xCount = 0, i;
double xActual = 0.0;
double xPredicted = 0.0;
mkFileName(fileName, sizeof(fileName), DIRECT_PREDECESSOR); // Logfile and name handling
mkFileName(fileName, sizeof(fileName), DIRECT_PREDECESSOR); // Logfile and name handling
FILE *fp3 = fopen(fileName, "w");
fprintf(fp3, fileHeader(DIRECT_PREDECESSOR_HEADER));
mkFileName(fileName, sizeof(fileName), USED_WEIGHTS_DIR_PRED);
FILE *fp9 = fopen(fileName, "w");
for (xCount = 1; xCount < mlData->samplesCount - 1; xCount++) { // first value will not get predicted
for (xCount = 1; xCount < mlData->samplesCount - 1; xCount++) { // first value will not get predicted
unsigned _arrayLength = (xCount > mlData->windowSize) ? mlData->windowSize + 1 : xCount;
xPredicted = 0.0;
xActual = xSamples[xCount];
@ -309,13 +322,14 @@ void directPredecessor(mldata_t *mlData, point_t points[]) {
double xSquared = 0.0;
for (i = 1; i < _arrayLength; i++) {
xSquared += pow(xSamples[xCount - 1] - xSamples[xCount - i - 1], 2); // substract direct predecessor
double x = xSamples[xCount - 1] - xSamples[xCount - i - 1];
xSquared += x*x; // substract direct predecessor
}
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] = localWeights[i - 1] + mlData->learnrate * xError[xCount]
localWeights[i-1] = localWeights[i - 1] + mlData->learnrate * xError[xCount]
* ((xSamples[xCount - 1] - xSamples[xCount - i - 1]) / xSquared);
fprintf(fp9, "%lf\n", localWeights[i]);
}
@ -325,20 +339,31 @@ void directPredecessor(mldata_t *mlData, point_t points[]) {
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 xErrorLength = *xErrorPtr; // Watch popNAN()!
xErrorPtr[0] = 0.0; // Stored length in [0] , won't be used anyway. Bit dirty
//printf("Xerrorl:%lf", xErrorLength);
double mean = sum_array(xError, xErrorLength) / xErrorLength; // Mean
double mean = sum_array(xErrorPtr, xErrorLength) / xErrorLength; // Mean
double deviation = 0.0;
for (i = 1; i < xErrorLength; i++) {
deviation += pow(xError[i] - mean, 2); // Mean square
double x = xError[i] - mean;
deviation += x*x; // Mean square
}
deviation /= xErrorLength; // Deviation
printf("mean square err: %lf, variance: %lf\t\t\tdirect Predecessor\n", mean, deviation);
printf("mean:%lf, devitation:%lf\t\tdirect Predecessor\n", mean, deviation);
fprintf(fp3, "\nQuadratische Varianz(x_error): %f\nMittelwert:(x_error): %f\n\n", deviation, mean);
fclose(fp3);
//free(localWeights);
free(xErrorPtr);
free(xError);
}
/*
@ -353,11 +378,12 @@ differential predecessor.
*/
void differentialPredecessor(mldata_t *mlData, point_t points[]) {
double *localWeights = (double *)malloc(sizeof(double) * mlData->windowSize + 1);
localWeights = mlData->weights;
const unsigned xErrorLength = mlData->samplesCount;
memcpy(localWeights, mlData->weights, sizeof(double) * mlData->windowSize + 1);
//localWeights = mlData->weights;
char fileName[512];
double *xError = (double *)malloc(sizeof(double) * xErrorLength);
memset(xError, 0.0, sizeof(double) * xErrorLength);
double *xError = (double *)malloc(sizeof(double) * mlData->samplesCount + 1);
memset(xError, 0.0, mlData->samplesCount);
unsigned xCount = 0, i;
double xPredicted = 0.0;
@ -384,19 +410,20 @@ void differentialPredecessor(mldata_t *mlData, point_t points[]) {
double xSquared = 0.0;
for (i = 1; i < _arrayLength; i++) {
xSquared += pow(xSamples[xCount - i] - xSamples[xCount - i - 1], 2); // Substract direct predecessor
double x = xSamples[xCount - i] - xSamples[xCount - i - 1];
xSquared += x*x; // Substract direct predecessor
}
if (xSquared == 0.0) { // Otherwise returns Pred: -1.#IND00 in some occassions
xSquared = 1.0;
}
for (i = 1; i < _arrayLength; i++) {
localWeights[i] = localWeights[i - 1] + mlData->learnrate * xError[xCount]
localWeights[i-1] = localWeights[i - 1] + mlData->learnrate * xError[xCount]
* ((xSamples[xCount - i] - xSamples[xCount - i - 1]) / xSquared);
fprintf(fp9, "%lf\n", localWeights[i]);
}
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;
@ -405,17 +432,29 @@ void differentialPredecessor(mldata_t *mlData, point_t points[]) {
}
fclose(fp9);
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(xError, xErrorLength) / xErrorLength;
double mean = sum_array(xErrorPtr, xErrorLength) / xErrorLength;
double deviation = 0.0;
for (i = 1; i < xErrorLength; i++) { // Mean square
deviation += pow(xError[i] - mean, 2);
double x = xError[i] - mean;
deviation += x*x;
}
deviation /= xErrorLength;
printf("mean square err: %lf, variance: %lf\t\t\tdifferential Predecessor\n", mean, deviation);
printf("mean:%lf, devitation:%lf\t\tdifferential Predecessor\n", mean, deviation);
fprintf(fp6, "\nQuadratische Varianz(x_error): %f\nMittelwert:(x_error): %f\n\n", deviation, mean);
fclose(fp6);
//free(localWeights);
free(xErrorPtr);
free(xError);
// weightsLogger( localWeights, USED_WEIGHTS );
}
/*
@ -451,15 +490,15 @@ Contains and returns every suffix for all existing filenames
======================================================================================================
*/
char * fileSuffix(int id) {
char * suffix[] = { (char*)"_weights_pure.txt",
(char*)"_weights_used_dir_pred_.txt",
(char*)"_direct_predecessor.txt",
(char*)"_ergebnisse.txt",
(char*)"_localMean.txt",
(char*)"_testvalues.txt",
(char*)"_differential_predecessor.txt",
(char*)"_weights_used_local_mean.txt",
(char*)"_weights_used_diff_pred.txt",
char * suffix[] = { "_weights_pure.txt",
"_weights_used_dir_pred_.txt",
"_direct_predecessor.txt",
"_ergebnisse.txt",
"_localMean.txt",
"_testvalues.txt",
"_differential_predecessor.txt",
"_weights_used_local_mean.txt",
"_weights_used_diff_pred.txt",
};
return suffix[id];
}
@ -474,9 +513,9 @@ Contains and returns header from logfiles
======================================================================================================
*/
char * fileHeader(int id) {
char * header[] = { (char*)"\n=========================== Local Mean ===========================\nNo.\txPredicted\txAcutal\t\txError\n",
(char*)"\n=========================== Direct Predecessor ===========================\nNo.\txPredicted\txAcutal\t\txError\n",
(char*)"\n=========================== Differential Predecessor ===========================\nNo.\txPredicted\txAcutal\t\txError\n"
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];
}
@ -486,7 +525,7 @@ char * fileHeader(int id) {
weightsLogger
Logs used weights to logfile - not used right now
Logs used weights to logfile
======================================================================================================
*/
@ -519,7 +558,8 @@ formats output of mkSvgGraph -- Please open graphResults.html to see the output-
*/
void bufferLogger(char *buffer, point_t points[]) {
unsigned i;
char _buffer[512] = "";
char _buffer[512] = ""; // TODO: resize buffer and _buffer so greater sampleval can be choosen
// char *_buffer = (char *) malloc ( sizeof(char) * 512 + 1);
for (i = 1; i < mlData->samplesCount - 1; i++) { // xActual
sprintf(_buffer, "L %f %f\n", points[i].xVal[0], points[i].yVal[0]);
strcat(buffer, _buffer);
@ -530,7 +570,7 @@ void bufferLogger(char *buffer, point_t points[]) {
strcat(buffer, _buffer);
}
strcat(buffer, "\" fill=\"none\" id=\"svg_2\" stroke=\"green\" stroke-width=\"0.4px\"/>\n<path d=\"M0 0\n");
for (i = 1; i <= mlData->samplesCount - 2; i++) { //xPredicted from directPredecessor
for (i = 1; i <= mlData->samplesCount - 1; i++) { //xPredicted from directPredecessor
sprintf(_buffer, "L %f %f\n", points[i].xVal[2], points[i].yVal[2]);
strcat(buffer, _buffer);
}
@ -566,6 +606,40 @@ double sum_array(double x[], int xlength) {
/*
======================================================================================================
popNan
returns new array without NAN values
======================================================================================================
*/
double *popNAN(double *xError) {
unsigned i, counter = 1;
double tmpLength = 0.0;
double *tmp = NULL;
double *more_tmp = NULL;
for (i = 0; i < mlData->samplesCount - 1; 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 is stored inside tmp[0]. tmp[0] is never used anyways
return tmp;
}
/*
======================================================================================================
r2
returns a random double value between 0 and 1
@ -599,26 +673,24 @@ parses template.svg and writes results in said template
======================================================================================================
*/
void mkSvgGraph(point_t points[], char *templatePath) {
FILE* input = NULL;
void mkSvgGraph(point_t points[]) {
FILE *input = fopen("graphResults_template.html", "r");
FILE *target = fopen("graphResults.html", "w");
if (templatePath) {
printf("\ngraph template src at: %s\n", templatePath);
input = fopen(templatePath, "r");
}
else {
input = fopen("graphResults_template.html", "r");
}
char line[512];
char firstGraph[15] = { "<path d=\"M0 0" }; // Position where points will be written after
if (input == NULL) {
printf("\nNo inputfile at mkSvgGraph()\n");
printf("No inputfile at mkSvgGraph()");
exit(EXIT_FAILURE);
}
char buffer[131072] = ""; // Really really dirty
fseek(input, 0, SEEK_END);
long fpLength = ftell(input);
fseek(input, 0, SEEK_SET);
char buffer[131072] = ""; // Bit dirty
// char *buffer = (char *) malloc ( sizeof(char) * ( ( 3 * mlData->samplesCount ) + fpLength + 1 ) );
memset(buffer, '\0', sizeof(buffer));
while (!feof(input)) { // parses file until "firstGraph" has been found
@ -656,7 +728,7 @@ static imagePixel_t *rdPPM(char *fileName) {
perror(fileName);
exit(EXIT_FAILURE);
}
if (buffer[0] != 'P' || buffer[1] != '6') { // PPM files start with P6
if (buffer[0] != 'P' || buffer[1] != '6') {
fprintf(stderr, "No PPM file format\n");
exit(EXIT_FAILURE);
}
@ -665,7 +737,7 @@ static imagePixel_t *rdPPM(char *fileName) {
fprintf(stderr, "malloc() failed");
}
c = getc(fp);
while (c == '#') { // PPM Comments start with #
while (c == '#') {
while (getc(fp) != '\n');
c = getc(fp);
}
@ -691,7 +763,7 @@ static imagePixel_t *rdPPM(char *fileName) {
printf("Changing \"-n\" to %d, image max data size\n", (image->x * image->y));
tmp = (double *)realloc(xSamples, sizeof(double) * (image->x * image->y));
xSamples = tmp;
mlData->samplesCount = (image->x * image->y);
mlData->samplesCount = (image->x * image->y) / sizeof(double);
}
if (fread(image->data, 3 * image->x, image->y, fp) != image->y) {
fprintf(stderr, "Loading image failed");
@ -780,6 +852,7 @@ void colorSamples(FILE* fp, mldata_t *mlData) {
while (!feof(fp)) {
if (fgets(buffer, mlData->samplesCount, fp) != NULL) {
sscanf(buffer, "%lf", &xSamples[i]);
//printf("%lf\n", xSamples[i] );
points[i].yVal[0] = xSamples[i]; // Fills points so actual input values can be seen as a graph
points[i].xVal[0] = i;
++i;
@ -801,7 +874,7 @@ 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 and iterate through array
for (ptr = &xSamples[xCount - _arraylength]; ptr != &xSamples[xCount]; ptr++) { // Set ptr to beginning of window
sum += *ptr;
}
return sum / (double)_arraylength;
@ -825,10 +898,10 @@ void usage(char **argv) {
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-l <digit>\t\tLearnrate, 0 < learnrate < 1.\n");
printf("\t-g <path>\t\t\tGraph building. If template is located in another folder use path, otherwise true.\n\t\t\t\tChoose for n < 1200.\n");
printf("\t-x true\t\t\tLogfiles only, no graph building.\n\t\t\t\tChoose for intense amount of input data.\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.\n");
printf("\n\n");
printf("%s compares prediction methods of least mean square filters.\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\t%s -i myimage.ppm -w 3 -c green -s 5 -g true\n", &argv[0][0], &argv[0][0]);
printf("%s compares prediction methods of least mean square filters.\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\t%s -i myimage.ppm -w 3 -c green -s 5 -x true\n", &argv[0][0], &argv[0][0]);
exit(8);
}
@ -838,7 +911,7 @@ void usage(char **argv) {
init_mldata_t
Init meachine learning data
Contains meachine learning data
======================================================================================================
*/