예제 #1
0
파일: calc.c 프로젝트: marvelliu/lilacsrc
void inverse(struct var_struct * s, struct var_struct * A)
{
    int i,j;
    double ration;
    struct var_struct temp,tempA;
    makesure(A->height==A->width,8);
    temp.p = 0; tempA.p = 0;
    makesize(&temp, A->height, A->height);
    setunit(&temp);
    copy_var(A, &tempA);
    makesure(1,0);
    for (i=0;i<temp.height;i++) {
        if (tempA.p[i][i]==0) {
            for (j=i+1;j<temp.height;j++) {
                if (tempA.p[j][i]!=0) {
                    swaprow(&tempA,i,j);
                    swaprow(&temp,i,j);
                    break;
                }
            }
        }
        if(fabs(tempA.p[i][i])<MINIMUM) {
            del(&temp);
            del(&tempA);
            calcerr=13;
            return;
        }
        //保证对角线元素不为零
        ration=1/tempA.p[i][i];
        multrow(&tempA,i,ration);
        multrow(&temp,i,ration);
        for (j=i+1;j<temp.height;j++) {
            ration=-tempA.p[j][i];
            plusrow(&tempA,i,j,ration);
            plusrow(&temp,i,j,ration);
        }
    }
    //现已变成对角线元素为1的上三角阵
    for (i=0;i<temp.height;i++) {
        for (j=0;j<i;j++) {
            ration=-tempA.p[j][i];
            plusrow(&tempA,i,j,ration);
            plusrow(&temp,i,j,ration);
        }
    }
    copy_var(&temp,s);
    del(&temp);
    del(&tempA);
}
예제 #2
0
il_mat il_mat_invert(il_mat a)
{
    il_mat res = il_mat_identity();

    // for every column ..
    for (int col = 0; col < 4; ++col) {
        float diagonalfield = a.data[col*4+col];
        // if we have a weird matrix with zero on the diagonal ..
        float eps = 0.0001;
        if (fabs(diagonalfield) < eps) {
            // SIIIGH.
            // Okay, let's go hunting for a row with a better diagonal to use
            // keep in mind, row swapping is also a linear operation!
            for (int row = 0; row < 4; ++row) if (row != col) if (fabs(a.data[row*4+col]) >= eps) {
                swaprow(&a, row, col);
                swaprow(&res,row, col);
            }
            diagonalfield = a.data[col*4+col]; // recompute
            // if it still fails, we probably have a denatured matrix and are proper f****d.
            assert(fabs(diagonalfield) >= eps);
        }
        // for every row ..
        for (int row = 0; row < 4; ++row) {
            // if it's not on the diagonal ..
            if (row != col) {
                float field = a.data[row*4+col];
                // bring this field to 0 by subtracting the row that's on the diagonal for this column
                addrow(&a,  /* src */ col, /* dst */ row, /* factor */ -field/diagonalfield);
                // do the same to identity
                addrow(&res,/* src */ col, /* dst */ row, /* factor */ -field/diagonalfield);
            }
        }
        // and finally, bring the diagonal to 1
        mulrow(&a,  col, 1/diagonalfield);
        mulrow(&res,col, 1/diagonalfield);
    }
    // Success! Because a is now id, res is now a^-1. Math is fun!
    return res;
}
예제 #3
0
파일: calc.c 프로젝트: marvelliu/lilacsrc
double envalue(struct var_struct * s)
{
    int i,j,flag;
    double result,ration;
    struct var_struct temp;
    if(calcerr) return 0;
    if(s->height!=s->width) {
        calcerr=8;
        return 0;
    }
    temp.p = 0;  
    copy_var(s, &temp);
    if(calcerr) return 0;
    result=1;
    for (i=0;i<temp.height;i++) {
        if (temp.p[i][i]==0) {
            flag=0;
            for (j=i+1;j<temp.height;j++) {
                if (temp.p[j][i]!=0) {
                    swaprow(&temp,i,j);
                    result*=-1;
                    flag=1;
                    break;
                }
            }
        }
        if (fabs(temp.p[i][i])<MINIMUM) {
            del(&temp);
            return 0;
        }
        //保证对角线元素不为零
        for (j=i+1;j<temp.height;j++) {
            ration=-temp.p[j][i]/temp.p[i][i];
            plusrow(&temp,i,j,ration);
        }
        result*=temp.p[i][i];
    }
    del(&temp);
    return result;
}