Пример #1
0
/* layer 6 */
static DOUBLE anfisDivisionNode(FIS *fis, int index, char *action, int index2)
{
	DOUBLE total_wf, total_w;

	anfisSetupInputArray(fis, index);
	total_wf = fis->node[index]->input[0];
	total_w = fis->node[index]->input[1];

	if (total_w == 0)
	{
		if (fis->isbias) 
		{
			fis->skipdatapoint = 1;			
			return 0;
		}
		else
			fisError("Total of firing strength is zero! Type HELP FUZZYZEROFIRING for more information.\n");  
	}

	if (strcmp(action, "forward") == 0)
		return(total_wf/total_w);
	if (strcmp(action, "backward") == 0) {
		if (index2 == 0)
			return(1/total_w);
		if (index2 == 1)
			return(-total_wf/(total_w*total_w));
		fisError("Wrong index2!\n");
	}
	if (strcmp(action, "parameter") == 0)
		return(0.0);
	fisError("Unknown action!\n");
	return(0);      /* for suppressing compiler's warning only */
}
Пример #2
0
/* apply given function to an array */
static DOUBLE fisArrayOperation(DOUBLE *array, int size, DOUBLE (*fcn)())
{
	int i;
	DOUBLE out;

	if (size == 0)
		fisError("Given size is zero!");

	out = array[0];
	for (i = 1; i < size; i++)
		out = (*fcn)(out, array[i]);
	return(out);
}
Пример #3
0
/* layer 1 */
static DOUBLE anfisMfNode(FIS *fis, int index, char *action, int index2)
{
	int which_input = fis->node[index]->fanin->index;
	int which_mf = fis->node[index]->ll_index;
	DOUBLE input_value = fis->node[which_input]->value;
	DOUBLE (*mfFcn)() = fis->input[which_input]->mf[which_mf]->mfFcn;
	DOUBLE *para = fis->node[index]->para;

	if (strcmp(action, "forward") == 0) {
		/* temperary storage for future use */
		fis->node[index]->tmp = (*mfFcn)(input_value, para);
		return(fis->node[index]->tmp);
	}
	if (strcmp(action, "backward") == 0)
		fisError("MF derivatives w.r.t. inputs should not be called!");
	if (strcmp(action, "parameter") == 0) {
		/* temperary storage for future use */
		return(fisMfDerivative(mfFcn, input_value, para, index2));
	}
	fisError("Unknown action!\n");
	return(0);	/* for suppressing compiler's warning only */
}
Пример #4
0
/* layer 2 */
static DOUBLE anfisInvNode(FIS *fis, int index, char *action, int index2)
{
	int fanin_node_index = fis->node[index]->fanin->index;
	DOUBLE in_mf_value = fis->node[fanin_node_index]->value;

	if (strcmp(action, "forward") == 0)
		return(1.0 - in_mf_value);
	if (strcmp(action, "backward") == 0)
		return(-1.0);
	if (strcmp(action, "parameter") == 0)
		return(0.0);
	fisError("Unknown action!\n");
	return(0);	/* for suppressing compiler's warning only */
}
Пример #5
0
/* layer 3 */
static DOUBLE anfisAndOrNode(FIS *fis, int index, char *action, int index2)
{
	DOUBLE *input = fis->node[index]->input;
	int which_rule = fis->node[index]->l_index;
	int and_or = fis->and_or[which_rule];
	DOUBLE (*AndOrFcn)() = and_or == 1? fis->andFcn:fis->orFcn;
	int i;

	anfisSetupInputArray(fis, index);

	if (strcmp(action, "forward") == 0) {
		fis->node[index]->tmp =
			fisArrayOperation(input, fis->node[index]->fanin_n,
			AndOrFcn);
		return(fis->node[index]->tmp);
	}
	if (strcmp(action, "backward") == 0) {
		if ((AndOrFcn == fisMin) || (AndOrFcn == fisMax)) {
			for (i = 0; i < fis->node[index]->fanin_n; i++)
				if (fis->node[index]->tmp == input[i])
					break;
			return(index2 == i? 1.0:0.0);
		}
		if (AndOrFcn == fisProduct) {
			DOUBLE product = 1.0;
			for (i = 0; i < fis->node[index]->fanin_n; i++) {
				if (i == index2)
					continue;
				product *= input[i];
			}
			return(product);
		}
		if (AndOrFcn == fisProbOr) {
			DOUBLE product = 1.0;
			for (i = 0; i < fis->node[index]->fanin_n; i++) {
				if (i == index2)
					continue;
				product *= (1 - input[i]);
			}
			return(product);
		}
	}
	if (strcmp(action, "parameter") == 0)
		return(0.0);
	fisError("Unknown action!\n");
	return(0);	/* for suppressing compiler's warning only */
}
Пример #6
0
/* layer 5 */
static DOUBLE anfisSummationNode(FIS *fis, int index, char *action, int index2)
{
	FAN *p, *fanin = fis->node[index]->fanin;
	DOUBLE sum = 0;

	for (p = fanin; p != NULL; p = p->next)
		sum += fis->node[p->index]->value;

	if (strcmp(action, "forward") == 0)
		return(sum);
	if (strcmp(action, "backward") == 0)
		return(1.0);
	if (strcmp(action, "parameter") == 0)
		return(0.0);
	fisError("Unknown action!\n");
	return(0);      /* for suppressing compiler's warning only */
}
Пример #7
0
/* layer 4 */
static DOUBLE anfisRuleOutputNode(FIS *fis, int index, char *action, int index2)
{
	DOUBLE *input;
	DOUBLE firing_strength;
	DOUBLE *para = fis->node[index]->para;
	int i;
	DOUBLE sum = 0;

	anfisSetupInputArray(fis, index);
	input = fis->node[index]->input;

	/* ========== */
	if (fis->order==1) {
		for (i = 0; i < fis->in_n; i++)
			sum += input[i]*para[i];
		sum += para[fis->in_n];
	} else
		sum = para[0];
	firing_strength = input[fis->in_n];

	if (strcmp(action, "forward") == 0)
		return(firing_strength*sum);

	/* ========== */
	if (strcmp(action, "backward") == 0)
		return(index2 != fis->in_n?
			fis->order*(firing_strength*para[index2]):sum);
	/* ========== */
	if (strcmp(action, "parameter") == 0) {
		if (fis->order == 1)
			return(index2 != fis->in_n?
			firing_strength*input[index2]:firing_strength);
		else
			return(firing_strength);
	}
	fisError("Unknown action!\n");
	return(0);      /* for suppressing compiler's warning only */
}
Пример #8
0
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;
}
Пример #9
0
/* layer 0 */
static DOUBLE anfisInputNode(FIS *fis, int index, char *action, int index2)
{
	fisError("anfisInputNode should not be called at all!");
	return(0);	/* for suppressing compiler's warning only */
}