/* void */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { DOUBLE *input, *output, *irr, *orr, *arr; int i, j, m, n, data_n, numofpoints; FIS *fis; DOUBLE *numofpointPt; int which_rule, which_output, which_mf; DOUBLE tmp, tmp_vec[2], mf_value; if (nrhs != 3) mexErrMsgTxt("Needs 3 input arguments."); if (!mxIsDouble(INPUT)) mexErrMsgTxt("The first input must be a defined DOUBLE matrix"); if (!mxIsStruct(FISMATRIX)) mexErrMsgTxt("The Second input must be a structure."); /* 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 = (int) mxGetM(NUMOFPOINT); numofpointPt=mxGetPr(NUMOFPOINT); if (m > 0 && numofpointPt[0] > 101) numofpoints=(int)numofpointPt[0]; else numofpoints=101; m = (int) mxGetM(INPUT); n = (int) mxGetN(INPUT); /*=====================*/ fis=matlab2cStr(prhs[1], numofpoints); /*=====================*/ if (!((n >= fis->in_n) || ((n == 1) && (m >= fis->in_n)))) { mexPrintf("The input vector is of size %dx%d,", m, n); mexPrintf("while expected input vector size is %d.\n", fis->in_n); mexErrMsgTxt("Exiting ..."); } if ((n == 1) && (m == fis->in_n)) data_n = 1; else data_n = m; /* signal error if multiple input vectors and mutiple output arguments */ /* if ((data_n > 1) && (nlhs > 1)) mexErrMsgTxt("Multiple output arguments can only be used with a single input vector."); */ /* Create matrices for returned arguments */ 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(INPUT); /* 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, numofpoints); /* Collect the output */ for (j = 0; j < fis->out_n; j++) output[j*data_n+i] = fis->output[j]->value; } /* take care of additonal output arguments */ if (nlhs >= 2) { IRR = mxCreateDoubleMatrix(fis->rule_n, fis->in_n, mxREAL); irr = mxGetPr(IRR); for (i = 0; i < fis->rule_n; i++) for (j = 0; j < fis->in_n; j++) { which_mf = fis->rule_list[i][j]; if (which_mf > 0) mf_value = fis->input[j]->mf[which_mf-1]->value; else if (which_mf == 0) { /* Don't care; mf_value depends on AND or OR */ if (fis->and_or[i] == 1) /* AND */ mf_value = 1; else mf_value = 0; } else /* Linguistic hedge NOT */ mf_value = 1 - fis->input[j]->mf[-which_mf-1]->value; irr[j*fis->rule_n+i] = mf_value; } } if (nlhs >= 3) { if (strcmp(fis->type, "mamdani") == 0) { ORR = mxCreateDoubleMatrix(numofpoints, (fis->rule_n)*(fis->out_n), mxREAL); orr = mxGetPr(ORR); for (i = 0; i < numofpoints; i++) for (j = 0; j < (fis->rule_n)*(fis->out_n); j++) { which_rule = j%(fis->rule_n); /* zero offset */ which_output = j/(fis->rule_n); /* zero offset */ which_mf = fis->rule_list[which_rule][fis->in_n+which_output]; if (which_mf > 0) tmp = fis->output[which_output]->mf[which_mf-1]->value_array[i]; else if (which_mf == 0) tmp = 0; else tmp = 1-fis->output[which_output]->mf[-which_mf-1]->value_array[i]; /* mexPrintf("rule = %d, output = %d, mf = %d\n", which_rule, which_output, which_mf); */ if (!fis->userDefinedImp) orr[j*numofpoints+i] = (*fis->impFcn)(tmp, fis->firing_strength[which_rule]); else { tmp_vec[0] = tmp; tmp_vec[1] = fis->firing_strength[which_rule]; orr[j*numofpoints+i] = fisCallMatlabFcn(tmp_vec, 2, fis->impMethod); } } } if (strcmp(fis->type, "sugeno") == 0) { ORR = mxCreateDoubleMatrix(fis->rule_n, fis->out_n, mxREAL); orr = mxGetPr(ORR); for (i = 0; i < fis->rule_n; i++) for (j = 0; j < fis->out_n; j++) { which_mf = fis->rule_list[i][fis->in_n+j]-1; /* mexPrintf("mf = %d\n", which_mf); */ if (which_mf == -1) /* don't_care consequent */ orr[j*fis->rule_n+i] = 0; else orr[j*fis->rule_n+i] = fis->output[j]->mf[which_mf]->value; } } } if (nlhs >= 4) { if (strcmp(fis->type, "mamdani") == 0) { ARR = mxCreateDoubleMatrix(numofpoints, fis->out_n, mxREAL); arr = mxGetPr(ARR); for (i = 0; i < numofpoints; i++) for (j = 0; j < fis->out_n; j++) arr[j*numofpoints+i] = fisFinalOutputMf(fis, j, i); } if (strcmp(fis->type, "sugeno") == 0) { ARR = mxCreateDoubleMatrix(fis->rule_n, fis->out_n, mxREAL); arr = mxGetPr(ARR); for (i = 0; i < fis->rule_n; i++) for (j = 0; j < fis->out_n; j++) arr[j*fis->rule_n+i] = fis->firing_strength[i]; } } /* destroy FIS data structure */ fisFreeFisNode(fis); }
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; } }