Beispiel #1
0
/* 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);
}
Beispiel #2
0
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;
	}
}