Ejemplo n.º 1
0
void leastEntryAlgo(float A[][M][maxDegree+1], float P[][N][maxDegree+1], float Pinv[][N][maxDegree+1], float Q[][M][maxDegree+1], float Qinv[][M][maxDegree+1]) {
	int n, m; // used in for loops over rows, columns respectively
	int p; // used in for loops over polynomial array
	int tempN, tempM, tempMin; //used to store temporary locations in A
	int finished = 0; // bool to decide if while loop is over
	int tempRowEntry, tempColEntry, tempMult, tempEntry;
	int diag = 0;
	float q[maxDegree+1];
	
	// for finishedRows and finishedColumns,
	// set entry i to -1 if row/col i is not finished, or
	// set entry i to i if row/col i is finished
	int finishedRows[N];
	int finishedColumns[M];

	//initializes finishedRows and finishedColumns
	for(n = 0; n < N; ++n) {
		finishedRows[n] = -1;
	}
	for(m = 0; m < M; ++m) {
		finishedColumns[m] = -1;
	}

	// begin the least entry algorithm
	while (finished == 0) {

		// resets tempM and tempN to -1
		tempM = -1;
		tempN = -1;

		// finds least non-zero entry, stores it in tempN, tempM
		findLeastEntry(A, finishedRows, finishedColumns, &tempN, &tempM, &finished);
		
		/* the loop should never break here; this if statement 
		is more or less a "just in case" used when developing */
		if(finished == 1) { break; }
		
		// resets tempRowEntry and tempColEntry to -1
		tempRowEntry = -1;
		tempColEntry = -1;

		/* checks if we can do row operations. by convention established
		   (arbitrarily) in this program, we do row oeprations when we can */
		if(contains(finishedColumns, M, tempM) == 0) {

			// finds an entry for the least entry to reduce
			for(n = 0; n < N; ++n) {
				if(equalsZero(A[n][tempM]) == 0 && n != tempN) {
					tempRowEntry = n;
					break;
				}
			}

			/* if there is no good entry to operate on, break the loop
			   in practice this would never happen, but convienient for dev. */
			if (tempRowEntry == -1) { break; }
			
			/* sets the vector q (in the sense of a = b*q + r)
			   so we can use it to do row operations */
			eucDiv(A[tempRowEntry][tempM], A[tempN][tempM], q);
			rowOperations2(A, P, Pinv, tempRowEntry, tempN, q);
		}

		// if we cannot do row operations, we do column operations
		else {
			for(m = 0; m < M; ++m) {
				if(equalsZero(A[tempN][m]) == 0 && m != tempM) {
					tempColEntry = m;
					break;
				}
			}
			if (tempColEntry == -1) { break; }
			
			eucDiv(A[tempN][tempColEntry], A[tempN][tempM], q);
			columnOperations2(A, Q, Qinv, tempColEntry, tempM, q);
		}

		// updates rows and colums that are finished
		updateFinishedRows(A, finishedRows);
		updateFinishedColumns(A, finishedColumns);
		finished = done(finishedRows, finishedColumns, N, M);
	}

	// now we can compute the rank
	rank = getRank(A);

	/* perform type 3 operations to order the 
	   non-zero elements onto the diagonals
	*/
	orderDiagonals(A, P, Pinv, Q, Qinv);
	
	// make all polynomials monic
	makeAllMonic(A, P, Pinv);

	// computation trick: transpose Q and Pinv so they are correct
	transposeM(Qinv);
	transposeN(Pinv);
}
Ejemplo n.º 2
0
/* reset != 0 --> reset matrices S and P */
static void anfisKalman(FIS *fis, int reset, DOUBLE alpha)
{
    DOUBLE **S, **P, **a, **b, **a_t, **b_t;
    DOUBLE **tmp1, **tmp2, **tmp3, **tmp4;
    DOUBLE **tmp5, **tmp6, **tmp7;

    /* ========== */
    int in_n;
    int out_n = fis->out_n;

    int i, j;
    DOUBLE denom;

    if (fis->method==1)
        in_n = ((fis->order)*(fis->in_n)+1)*fis->rule_n;
    else
        in_n = fis->para_n;

    S = fis->S;
    P = fis->P;
    a = fis->a;
    b = fis->b;
    a_t = fis->a_t;
    b_t = fis->b_t;
    tmp1 = fis->tmp1;
    tmp2 = fis->tmp2;
    tmp3 = fis->tmp3;
    tmp4 = fis->tmp4;
    tmp5 = fis->tmp5;
    tmp6 = fis->tmp6;
    tmp7 = fis->tmp7;

    /* reset S[][] and P[][] */
    if (reset != 0) {
        /*======  already defined in param passed in
        		double alpha;

                        if (fis->method==1)
                             alpha = 1e6;
                        else
                             alpha = 1e-1;           =======*/
        for (i = 0; i < in_n; i++)
            for (j = 0; j < out_n; j++)
                P[i][j] = 0;
        for (i = 0; i < in_n; i++)
            for (j = 0; j < in_n; j++)
                if (i == j)
                    S[i][j] = alpha;
                else
                    S[i][j] = 0;
        return;
    }

    /* reset == 0, normal operation */
    for (i = 0; i < in_n; i++)
        a[i][0] = fis->kalman_io_pair[i];
    for (i = 0; i < out_n; i++)
        b[i][0] = fis->kalman_io_pair[i+in_n];

    transposeM(a, in_n, 1, a_t);
    transposeM(b, out_n, 1, b_t);

    /* recursive formulas for S, covariance matrix */
    anfisMtimesM(S, a, in_n, in_n, 1, tmp1);
    anfisMtimesM(a_t, tmp1, 1, in_n, 1, tmp2);
    denom = fis->lambda + tmp2[0][0];
    anfisMtimesM(a_t, S, 1, in_n, in_n, tmp3);
    anfisMtimesM(tmp1, tmp3, in_n, 1, in_n, tmp4);
    anfisStimesM(1/denom, tmp4, in_n, in_n, tmp4);
    anfisMminusM(S, tmp4, in_n, in_n, S);
    anfisStimesM(1/fis->lambda, S, in_n, in_n, S);

    /* recursive formulas for P, the estimated parameter matrix */
    anfisMtimesM(a_t, P, 1, in_n, out_n, tmp5);
    anfisMminusM(b_t, tmp5, 1, out_n, tmp5);
    anfisMtimesM(a, tmp5, in_n, 1, out_n, tmp6);
    anfisMtimesM(S, tmp6, in_n, in_n, out_n, tmp7);
    anfisMplusM(P, tmp7, in_n, out_n, P);

    for (i = 0; i < in_n; i++)
        for (j = 0; j < out_n; j++)
            fis->kalman_para[i][j] = P[i][j];
}