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); }
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; }
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; }