DOUBLE calc_fuzzy(DOUBLE** dataMatrix, int data_col_n) { // Assume we always have one row of data in this version // i.e., dataMatrix is a type DOUBLE[data_col_n][1] const int data_row_n = 1; const bool debug = false; FIS *fis; DOUBLE **fisMatrix, **outputMatrix; char *fis_file; int fis_row_n, fis_col_n; // NOTE: We need to store this with the GUI exe somehow... fis_file = "bin/fismain.fis"; /* obtain FIS matrix */ fisMatrix = returnFismatrix(fis_file, &fis_row_n, &fis_col_n); /* build FIS data structure */ fis = (FIS *)fisCalloc(1, sizeof(FIS)); fisBuildFisNode(fis, fisMatrix, fis_col_n, MF_POINT_N); /* error checking */ if (data_col_n < fis->in_n) { PRINTF("Given FIS is a %d-input %d-output system.\n", fis->in_n, fis->out_n); PRINTF("Given data file does not have enough input entries.\n"); fisFreeMatrix((void **)dataMatrix, data_row_n); fisFreeMatrix((void **)fisMatrix, fis_row_n); fisFreeFisNode(fis); fisError("Exiting ..."); return -1.0; } /* debugging */ if (debug) fisPrintData(fis); /* create output matrix */ outputMatrix = (DOUBLE **)fisCreateMatrix(data_row_n, fis->out_n, sizeof(DOUBLE)); /* evaluate FIS on each input vector */ for (int i = 0; i < data_row_n; i++) getFisOutput(dataMatrix[i], fis, outputMatrix[i]); /* print output vector */ if(debug) { for (int i = 0; i < data_row_n; i++) { for (int j = 0; j < fis->out_n; j++) PRINTF("%.12f ", outputMatrix[i][j]); PRINTF("\n"); } } DOUBLE fuzzyVal = outputMatrix[0][0]; /* clean up memory */ fisFreeFisNode(fis); fisFreeMatrix((void **)dataMatrix, data_row_n); fisFreeMatrix((void **)fisMatrix, fis_row_n); fisFreeMatrix((void **)outputMatrix, data_row_n); return fuzzyVal; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *output, *input; unsigned int m ,n; int i, j, handle, data_n; FIS *p, *fis; char action[STR_LEN], fisName[STR_LEN]; static FIS *head = NULL, *curr_fis = NULL; static int initialized = 0; /* for mexAtExit() */ if (initialized == 0) { mexAtExit(fisAtExit); initialized = 1; } if (nrhs != 3) mexErrMsgTxt("Needs 3 arguments."); if (mxGetM(HANDLE) != 1 || mxGetN(HANDLE)!= 1) mexErrMsgTxt("The first argument must be a scalar."); if (!mxIsChar(ACTION)) mexErrMsgTxt("The second argument must be an action string."); mxGetString(ACTION, action, mxGetN(ACTION)+1); handle = mxGetScalar(HANDLE); /* Evaluate the output of the FIS with the given handle*/ /* If handle <= 0, use current FIS */ if (strcmp(action, "evaluate") == 0) { fis = handle > 0 ? fisMatchHandle(head, handle): curr_fis; if (curr_fis == NULL) mexErrMsgTxt("No FIS in memory!"); /* Check the dimensions of input vector */ /* This is permissive - granted as long as enough inputs are there. So the user can pass the original training data directly */ m = mxGetM(DATA); n = mxGetN(DATA); if (!((n >= fis->in_n) || ((n == 1) && (m >= fis->in_n)))) { mexPrintf("Input vector is of size %d by %d.\n", m, n); mexPrintf("Number of input variables should be %d.\n", fis->in_n); mexErrMsgTxt("Input vector has a wrong size!"); } if ((n == 1) && (m == fis->in_n)) data_n = 1; else data_n = m; /* Create a matrix for the return argument */ OUTPUT = mxCreateDoubleMatrix(data_n, fis->out_n, mxREAL); for (i = 0; i < data_n; i++) { /* Assign pointers to the various parameters */ output = mxGetPr(OUTPUT); input = mxGetPr(DATA); /* Dispatch the inputs */ for (j = 0; j < fis->in_n; j++) fis->input[j]->value = input[j*data_n+i]; /* Compute the output */ fisEvaluate(fis); /* Collect the output */ for (j = 0; j < fis->out_n; j++) output[j*data_n+i] = fis->output[j]->value; } } /* Load parameters (from another fismat) to FIS */ else if (strcmp(action, "load_param") == 0) { double **fismatrix; int m, n; if (!mxIsNumeric(DATA)) mexErrMsgTxt("The second argument must be a numeric data."); /* put fismatrix into proper format */ m = mxGetM(DATA); n = mxGetN(DATA); fismatrix = (double **)fisCreateMatrix(m, n, sizeof(double)); for (i = 0; i < m; i++) for (j = 0; j < n; j++) fismatrix[i][j] = mxGetPr(DATA)[j*m + i]; /* Set FIS if handle > 0, otherwise use the original curr. FIS */ fis = handle > 0 ? fisMatchHandle(head, handle): curr_fis; fisLoadParameter(fis, fismatrix); /* Free fismatrix */ fisFreeMatrix((void **)fismatrix, m); } /* Load parameters (from an array) to FIS */ else if (strcmp(action, "load_param1") == 0) { if (!mxIsNumeric(DATA)) mexErrMsgTxt("The second argument must be a numeric data."); /* Set FIS if handle > 0, otherwise use the original curr. FIS */ fis = handle > 0 ? fisMatchHandle(head, handle): curr_fis; fisLoadParameter1(fis, mxGetPr(DATA)); } /* Build a new FIS node, add it to the end, and make it current */ /* Build a new FIS node, add it to the end, and make it current */ /* Name clash is not checked */ else if (strcmp(action, "build") == 0) { double **fismatrix; int m, n; if (!mxIsNumeric(DATA)) mexErrMsgTxt("The second argument must be a numeric data."); /* put fismatrix into proper format */ m = mxGetM(DATA); n = mxGetN(DATA); fismatrix = (double **)fisCreateMatrix(m, n, sizeof(double)); for (i = 0; i < m; i++) for (j = 0; j < n; j++) fismatrix[i][j] = mxGetPr(DATA)[j*m + i]; /* Create FIS node */ fis = (FIS *)calloc(1, sizeof(FIS)); fisBuildFisNode(fis, fismatrix, n); fis->handle = fisFindMaxHandle(head) + 1; fis->next = NULL; /* Free fismatrix */ fisFreeMatrix((void **)fismatrix, m); /* Create a matrix for the return argument */ OUTPUT = mxCreateDoubleMatrix(1, 1, mxREAL); /* output[0] is equal to the handle of newly created FIS */ output = mxGetPr(OUTPUT); if (head == NULL) { head = fis; } else { /* Find p as the tail of the FIS list */ /* Also find the handle for this new node */ for (p = head; p->next != NULL; p = p->next); p->next = fis; } /* curr_fis is the newly created fis */ curr_fis = fis; output[0] = fis->handle; } /* Delete the current FIS, change the current FIS to head */ /* If there is a valid handle, delete the FIS with that handle */ else if (strcmp(action, "delete") == 0) { if (head == NULL) { mexPrintf("No FIS in memory!\n"); return; } /* Delete FIS with given valid handle. */ /* If given handle is unvalid, delete the curretn FIS */ fis = handle > 0 ? fisMatchHandle(head, handle): curr_fis; if (fis == head) head = head->next; else { /* find p such p->next == fis */ for (p = head; p->next != fis; p = p->next); p->next = fis->next; } /* Change current FIS to head if it is deleted */ if (fis == curr_fis) curr_fis = head; fisFreeFisNode(fis); } /* Delete all data structure */ /* This is used in mexAtExit only */ else if (strcmp(action, "at_exit") == 0) { FIS *next, *now = head; /* if (head != NULL) mexPrintf("Destroying FIS data structures ...\n"); */ while (now != NULL) { mexPrintf("Deleting %s FIS data structure...\n", now->name); next = now->next; fisFreeFisNode(now); now = next; } } /* Print the FIS with given handle. DATA is not used. */ else if (strcmp(action, "print_fis_data") == 0) { fis = fisMatchHandle(head, handle); fisPrintData(fis); } /* Set current FIS by handle if handle > 0, otherwise by name */ else if (strcmp(action, "set_current") == 0) { if (head == NULL) mexErrMsgTxt("No FIS is in memory!\n"); if (handle <= 0) { /* by namee */ if (!mxIsChar(DATA)) mexErrMsgTxt("The third argument must be a string."); /* Create the fisName string */ mxGetString(DATA, fisName, mxGetN(DATA)+1); fis = fisMatchName(head, fisName); if (fis == NULL) mexErrMsgTxt("Cannot find an FIS with the given name!"); } else /* by handle */ fis = fisMatchHandle(head, handle); curr_fis = fis; } /* Return the handle of the current FIS if DATA == [] */ /* (Return 0 if the current FIS is NULL) */ /* If DATA is not [], return handle with that name. */ else if (strcmp(action, "return_handle") == 0) { OUTPUT = mxCreateDoubleMatrix(1, 1, mxREAL); if (mxIsNumeric(DATA) && (mxGetM(DATA) == 0) && (mxGetN(DATA) == 0)) *(mxGetPr(OUTPUT)) = curr_fis == NULL ? 0:curr_fis->handle; else { /* return handle with given name */ if (!mxIsChar(DATA)) mexErrMsgTxt("The third argument must be a string."); /* Create the fisName string */ mxGetString(DATA, fisName, mxGetN(DATA)+1); fis = fisMatchName(head, fisName); if (fis == NULL) mexErrMsgTxt("Cannot find an FIS with the given name!"); *(mxGetPr(OUTPUT)) = fis == NULL ? 0:fis->handle; } } else if (strcmp(action, "print_name") == 0) { /* print name of FIS with given handle */ if (head == NULL) mexErrMsgTxt("No FIS is in memory."); fis = handle > 0 ? fisMatchHandle(head, handle): curr_fis; mexPrintf("%s\n", fis->name); } else if (strcmp(action, "list_all") == 0) { if (head == NULL) { mexPrintf("No FIS is in memory.\n"); return; } for (p = head; p != NULL; p = p->next) { /* mexPrintf("p = %d\t", p); mexPrintf("p->next = %d\n", p->next); */ mexPrintf("\t%d\t%s\n", p->handle, p->name); } mexPrintf("\n"); } /* Unrecognized action string */ else { mexPrintf("The action string %s is not recognized!\n", action); return; } }