Inversion de masortingce carrée en C

J’ai écrit une fonction d’inversion pour une masortingce carrée n * n.

void inverseMasortingx(int n, float **masortingx) { float ratio,a; int i, j, k; for(i = 0; i < n; i++) { for(j = n; j < 2*n; j++) { if(i==(jn)) matrix[i][j] = 1.0; else matrix[i][j] = 0.0; } } for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { if(i!=j) { ratio = matrix[j][i]/matrix[i][i]; for(k = 0; k < 2*n; k++) { matrix[j][k] -= ratio * matrix[i][k]; } } } } for(i = 0; i < n; i++) { a = matrix[i][i]; for(j = 0; j < 2*n; j++) { matrix[i][j] /= a; } } //return matrix; } 

Cela fonctionne bien dans presque tous les cas, mais échoue dans certains cas, comme ceux présentés ci-dessous:

 1 1 1 0 1 1 1 0 1 1 2 0 1 1 2 0 1 2 0 1 1 2 1 0 1 2 0 2 1 2 0 2 

Quel pourrait être le cas que je néglige?

Merci!

voir http://www.sourcecodesworld.com/source/show.asp?ScriptID=1086 .

utilise l’algorithme de Gauss Jordan

 #include #include int main() { float **A,**I,temp; int i,j,k,matsize; printf("Enter the size of the masortingx(ie value of 'n' as size is nXn):"); scanf("%d",&matsize); A=(float **)malloc(matsize*sizeof(float *)); //allocate memory dynamically for masortingx A(matsize X matsize) for(i=0;i 

Les elems diagonaux doivent d’abord être mis à l’échelle sur 1 avant de mettre à zéro les élems du sortingangle inférieur (votre deuxième boucle nestede). Il se trouve que la diagonale contient 0 => il n’existe pas d’inverse OU on obtient une forme d’échelon de ligne. Avec une itération inversée sur la diagonale, nous pouvons la réduire et obtenir l’inverse. Le code est loin d’être optimal. Lorsque vous avez FPU, double pourrait être un meilleur choix que float pour de tels calculs numériques.

Notez que les sous-masortingces de remise à zéro, les échanges de rangées, etc. peuvent être remplacés par des solutions beaucoup plus optimales. Masortingx est un type personnalisé et IsFloat0 est une fonction personnalisée, mais toutes doivent être dépourvues de nom et de contexte. Profitez du code:

 const uint sz = 4; Masortingx< double > mx; mx.Resize( 2 * sz, sz ); mx.Zero(); for( uint rdx = 0; rdx < mx.NumRow(); ++rdx ) { mx( rdx, rdx + mx.NumRow() ) = 1.0; // eye } mx( 0, 0 ) = 1.0; mx( 0, 1 ) = 1.0; mx( 0, 2 ) = 1.0; mx( 0, 3 ) = 0.0; mx( 1, 0 ) = 1.0; mx( 1, 1 ) = 1.0; mx( 1, 2 ) = 2.0; mx( 1, 3 ) = 0.0; mx( 2, 0 ) = 1.0; mx( 2, 1 ) = 2.0; mx( 2, 2 ) = 0.0; mx( 2, 3 ) = 1.0; mx( 3, 0 ) = 1.0; mx( 3, 1 ) = 2.0; mx( 3, 2 ) = 0.0; mx( 3, 3 ) = 2.0; // pivot iteration uint idx; for( idx = 0; idx < sz; ++idx ) { // search for non-0 pivot uint sdx = sz; for( uint rdx = idx; rdx < sz; ++rdx ) { if( !Util::IsFloat0( mx( rdx, idx ) ) ) { sdx = rdx; rdx = sz - 1; } } if( sdx < sz ) { // swap rows if( idx != sdx ) { for( uint cdx = 0; cdx < ( sz << 1 ); ++cdx ) { double swp; swp = mx( idx, cdx ); mx( idx, cdx ) = mx( sdx, cdx ); mx( sdx, cdx ) = swp; } } // 1 pivot and 0 col { double sc = 1.0 / mx( idx, idx ); for( uint cdx = 0; cdx < ( sz << 1 ); ++cdx ) { mx( idx, cdx ) *= sc; // 1 } for( uint rdx = 1 + idx; rdx < sz; ++rdx ) { double sd = mx( rdx, idx ); for( uint cdx = 0; cdx < ( sz << 1 ); ++cdx ) { mx( rdx, cdx ) -= sd * mx( idx, cdx ); // 0 } } } } else { idx = sz; } } if( sz < idx ) { mx.Zero(); } else { for( idx = 0; idx < sz; ++idx ) { uint ydx = sz - 1 - idx; for( uint rdx = 0; rdx < ydx; ++rdx ) { double sc = mx( rdx, ydx ); for( uint cdx = 0; cdx < ( sz << 1 ); ++cdx ) { mx( rdx, cdx ) -= sc * mx( ydx, cdx ); // 0 } } } }