Voir la version complète : Inverser une matrice 4x4
remram44
24/09/2005, 22h11
J'ai une matrice 4x4, et que je veux calculer son inverse... C'est quoi la formule ? :00000005:
!google inversion de matrice
Au pire, postes ton algo (si t'en as un...).
remram44
25/09/2005, 12h34
J'ai déja cherché, sinon je ne posterais pas ici.
Je précise que je suis en première S, et que les matrices ne sont hélas pas au programme :00000025:.
Atréides
25/09/2005, 13h19
Attend un moment...
Tu peux toujours lire ça (http://home.earthlink.net/~jimlux/radio/math/matinv.htm), ou alors regarder parmi ces liens (http://www.google.fr/search?hl=fr&c2coff=1&q=invert+matrix+algorithm+OR+formula+4x4&btnG=Rechercher&meta=) ...
remram44
25/09/2005, 14h18
J'avoue avoir du mal à comprendre ces algorithmes, mais ils me semblent néanmoins assez lents (en tout cas le premier, "inversion by elimination").
Je vais quand même expliquer pourquoi je demande ça :
J'essaye de développer un jeu (je commence par le plus dur, si j'y arrive pas j'aurais pas trop perdu de temps) de combat spacial en C++ et OpenGL. Je ne pense pas viser trop haut, mais néanmoins l'orientation de mes vaisseaux se feront avec des matrices et non des angles d'Euler (pas de haut ni de bas dans l'espace).
Je cherche à tourner un vaisseau vers un point. Pour cela, je pensais à calculer les coordonnées du point par rapport au vaisseau, puis normaliser le vecteur et calculer les coordonnées sphériques (j'ai déja la formule). Je peux ainsi tourner le vaisseau. :00000013:
Atréides
25/09/2005, 14h18
Bon... bah heu ... Je suis persuadé que c'est bourré d'erreurs : 11 semaines d'armée, ça fait un lavage de cerveau... Mais ça devrait aussi te donner une direction à suivre :)
http://img394.imageshack.us/img394/631/p92503433bs.th.jpg (http://img394.imageshack.us/my.php?image=p92503433bs.jpg)
remram44
25/09/2005, 14h23
| 2 14 5 |
| 12 4 16 |
| 9 15 10 |
C'est le cofacteur de l'élément en haut à gauche, c'est ça ?
Sinon, merci, mais il me manque encore quelques éléments...
Notament, comment passes-tu de ce que j'ai recopié ci-dessus à 656 ? Je cherche aussi la formule du déterminant.
Atréides
25/09/2005, 15h06
En simplifiant, pour un déterminant 3x3, on réécris après les deux premières colonnes puis on additionne le produit des diagonales partant du haut et on soustrait celui de celles partant du bas :
| 2 14 5 | 2 14
| 12 4 16 | 12 4 = (2*4*10) + (14*16*9) + (5*12*15) - (9*4*5) - (15*16*2) - (10*12*14)
| 9 15 10 | 9 15
Les autres éléments ? Bah ... il faut calculer un déterminant de 4x4 et transposer la matrice, c'est tout
Si tu veux inverser une matrice tu as deux méthodes, soit la méthode des déterminants (avec des calculs de cofacteurs, celle exposée par Atréides), soit tu peux utiliser un pivot de Gauss (méthode des combinaisons linéaires).
* Avec les déterminants :
1)
Le but est de revenir à des matrices 2x2 pour lesquelles on peut trouver facilement le déterminant :
A=|a b|
|c d|
det(A) = |A| = ad-bc
2)
La matrice adjointe (même si tu sais surement ce que c'est je rapelle) :
M(Aij)
M'=(A'ij)=(-1)^i+j
en gros avec la matrice A plus haut, la matrice adjointe ce serait
A=|d -b|
|-c a|
Donc, pour obtenir ta matrice inverse, il faut
1) calculer le déterminant
2) calculer la matrice adjointe
3) multiplier la matrice adjointe par l'inverse du déterminant
Après si ta matrice est >2 c'est le meme principe, tu calcules le déterminant (comme te l'a expliqué Atréides), tu calcules ta transposée, puis l'adjointe grace aux cofacteurs, et tu multiplies ta matrice adjointe par l'inverse de ton déterminant.
* Avec les combinaisons linéaires :
Je m'étends moins sur cette méthode parcequ'elle est beaucoup plus chiante que l'autre.
le but c'est de prémultiplier ta matrice de départ d'autres matrices pour faire apparaitre une matrice triangulaire.
Donc tu devrais te retrouver au bout d'un moment avec un truc genre :
D x C2 x C1 x M = I
soit
M^-1 = D x C2 x C1
Arrivé la tu as compris pourquoi c'est lent... 3 matrices à multiplier, ca prend des heures à faire. Et encore la c'est un exemple, tu peux tomber sur 4, 5 ...
remram44
25/09/2005, 16h59
Moi en l'occurrence, c'est pas pour faire à la main lol... Mais la dernière méthode a quand même l'air très lente.
tu calcules ta transposée
Tu en avais pas parlé de ça avant... :00000005:
La matrice adjointe (même si tu sais surement ce que c'est je rapelle)
Non pas vraiment... C'est pas celle qui est à droite sur la photo de Atreides ?
tu calcules ta transposée
Tu en avais pas parlé de ça avant... images/smilies/Emotion%20Mix/00000005.gif En fait c'est parceque la matrice adjointe est calculée en calculant la transposée de la comatrice :)
La matrice adjointe (même si tu sais surement ce que c'est je rapelle)
Non pas vraiment... C'est pas celle qui est à droite sur la photo de Atreides ? Oui c'est la grosse matrice au milieu de la photo d'Atréides. En l'occurence sur son exemple il n'a mit que le premier degré de cofacteurs, vu que sa matrice de départ est très grosse.
remram44
25/09/2005, 19h16
Alors je récapitule :
- Le déterminant, noté det(A), est égal à la somme des produits des diagonales moins la somme des produits des diagonales dans l'autre sens.
- La transposée c'est une matrice qu'on retourne : Bij = Aji. Elle est notée avec un t en haut à gauche.
- Le cofacteur est la matrice de départ à laquelle on enlève la ligne et la colonne de l'élément.
- La comatrice c'est une matrice remplie de cofacteurs.
- La matrice adjointe c'est la transposée de la comatrice.
- L'inverse M' d'une matrice M est, si son déterminant est différent de zéro, égal à 1/det(M) * adjointe de M
Questions :
- Pourquoi ya une colonne avec des + / une colonne avec des - dans la grosse matrice au milieu de la photo d'Atréides.
- Où est-ce que je me suis planté.
Atréides
26/09/2005, 10h10
Alors, pour ce qui est de mes + et -, il faut les alterner dans chaque case. Exemples :
|+ -|
|+ -|
|+ - +|
|- + -|
|+ - +|
|+ - + -|
|+ - + -|
|+ - + -|
|+ - + -|
Mais bon, comme je l'ai dit, l'armée, c'est lavage de cerveau, donc il est possible que j'aie oublié deux-trois détails. Bah tient, un détail que j'ai oublié, c'est comment calculer des déterminants autres que 2x2 et 3x3.
"Le déterminant, noté det(A), est égal à la somme des produits des diagonales moins la somme des produits des diagonales dans l'autre sens." est vrai pour les déterminants 2x2 (ou 3x3 si on réécris à côté les deux premières colonnes), mais je ne crois pas que ça soit le cas pour tous.
N'oubliez pas la FAQ des matrices et quaternions, il y a toutes les formules dont vous aurez besoin.
http://membres.lycos.fr/javamus/articles/mqfaq.html
remram44
26/09/2005, 17h57
C'est horrible... Personne n'a pensé à corriger les fautes d'orthographes lol ?
Bon, je regarde ça, mais à priori j'aurais encore des questions... on peut pas progresser de 3 ans en maths aussi facilement http://forum.games-creators.org/images/icons/icon10.gif
[edit] Je crois que j'ai compris, je vais quand même faire quelques "exercices" pour vérifier. Une dernière question : la matrice adjointe c'est la transposée de la comatrice, avec ou sans les + et - alternés ? :00000010:
Fait des recherches sur la Méthode de Jordan c'est celle qu'on apprend au DUT pour inverser les matrices car c'est l'une des plus rapides au niveau algoritmique même si ce n'est pas la plus efficace quand on inverse une matrice sur le papier.
je sais bien que c'est ralant quand on tient la solution et qu'on vous dit qu'il ne faut pas l'appliquer, mais...
Je crois que classiquement quand on empile les multiplications de matrice, parallement on empile aussi les multiplication de l'inv matrice pour ne pas avoir a la calculer a partir de la matrice.
si les modeleurs exportent l'inverse en meme temps que la matrice, ce n'est pas parce qu'elle est "calculable mais lourde a calculer" ?
donc je crois que si ce n'est pas a des fins de debug il ne faut pas le faire.
TrizoLakai
02/10/2005, 21h40
Alors, pour ce qui est de mes + et -, il faut les alterner dans chaque case. Exemples :
|+ -|
|+ -|
|+ - +|
|- + -|
|+ - +|
|+ - + -|
|+ - + -|
|+ - + -|
|+ - + -|
J'ai essayé sur ma calculette et ce serai plutôt
|- +|
|+ -|
:00000020:
yapaa237
05/10/2005, 10h30
- +
+ -
Ce doit être un coup de bol.
En théorie, c'est de la (-1)puissance (ieme ligne+ jème colonne)
(-1)^(1+1) (-1)^(1+2)
(-1)^(2+1) (-1)^(2+2)
ce qui fait + -
- +
Salut,
il y a plein de librairies C++ qui font l'inversion de matrices 4x4. Elles font ça très bien et c'est déjà optimisé.
Par exemple, la librairie mathématique de INTEL est une belle réussite: tout est optimisé en assembleur SSE1 et SSE2.
Sinon, tu peux toujours télécharger EaseWrapper sur www.ease-production.com. Dedans, tu trouveras un projet nommé EaseCore qui contient plein de petites classes utiles (vecteurs, matrices, quaternions, plans, rayons, etc) ; les sources de EaseCore sont open-source.
Pacôme
yapaa237
06/10/2005, 17h49
Sinon mathlab doit pouvoir te faire ça avec de tres grandes matrices !
TrizoLakai
06/10/2005, 21h20
Et en fait ça te sert à quoi? :00000020: Parce que a cause de toi, grace a toi, je me suis tapé des matrices à inverser pour voir comment ça fonctionne :00000005:
;)
maleaume
24/10/2005, 17h32
je te rajouterai des que j'ai un peu de tmeps un petit source pour te montrer comment utiliser les matrice .. j'ia fias ç_a y a kk temps.. mais ça le merite de marcher et tres rapide pour des matrices 4x4
Le HEader
/*BONNIN Maleaume 2003,2004
mail: maleaume@msn.com
*/
#ifndef __MATRICE_H__
#define __MATRICE_H__
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define DIM 2
#ifndef __PI__
#define __PI__
#define PI 3.14159265358979
#endif
typedef struct Matrice{
int n;
int m;
double ** mat;
}matrice;
void mineur_matrice(matrice * min_A,matrice* A, int n,int m);
void inverse_matrice(matrice * A_1, matrice * A);
void trans_comatrice(matrice * CoA, matrice *A);
double determinant_matrice (matrice *m);
matrice * mineur_matrice(matrice* A, int n,int m);
void affiche_matrice(matrice* A);
void trans_matrice(matrice * C,matrice* A);
void mult_matrice(matrice * C,matrice* A, matrice *B);
void soust_matrice(matrice* C,matrice* A, matrice* B);
matrice* add_matrice(matrice* A, matrice* B);
matrice* alloc_matrice (int n,int m);
matrice* identite_matrice(int n);
matrice * mult_by_scal_matrice(matrice * A, double k);
void free_matrice(matrice *);
#endif
le source
/* BONNIN Maleaume 2003,2004
mail: maleaume@msn.com
*/
#include "matrice.h"
//--------------------------------------------------------------
// Fonction d'allocation d'une matrice (n,n)
// Remarque : on désalloue en cas d’échec en cours !
//--------------------------------------------------------------
matrice* alloc_matrice (int n,int m)
{
matrice * M = (matrice *)calloc(1,sizeof(matrice));
M->n = n;
M->m = m;
double **a;
a=(double **)calloc(n,sizeof(double *));
if (a!=NULL) {
for (int i=0; i<n; i++) {
a[i]=(double *)calloc(m,sizeof(double));
if (a[i]==NULL) {
for (int j=0; j<i; j++) free((void *)a[j]);
free((void *)a);
return NULL;
}
}
}
M->mat= a;
return M;
}
//--------------------------------------------------------------
// Fonction de désallocation d'une matrice (n,n)
//--------------------------------------------------------------
void free_matrice (matrice *M)
{
if (M->mat!=NULL) {
for (int i=0; i<M->n; i++) if (M->mat[i]!=NULL) free((void *)M->mat[i]);
free((void *)M->mat);
}
}
matrice* identite_matrice(int n){
matrice * C = alloc_matrice(n,n);
for(int i =0; i<n;i++)
C->mat[i][i] = 1;
return C;
}
matrice* add_matrice(matrice* A, matrice* B)
{
if(A->n != B->n || A->m!= B->m){
printf("erreur dans la dimension des matrices");
return NULL;
}
matrice* C= alloc_matrice(A->n,A->m);
for(int i = 0; i < C->n; i++)
for(int j = 0; j < C->m; j++)
C->mat[i][j] = A->mat[i][j] + B->mat[i][j];
return C;
}
void soust_matrice(matrice * C, matrice* A, matrice* B)
{
if(A->n != B->n || A->m!= B->m){
printf("erreur dans la dimension des matrices");
exit(0);
}
//matrice* C= alloc_matrice(A->n,A->m);
for(int i = 0; i < C->n; i++)
for(int j = 0; j < C->m; j++)
C->mat[i][j] = A->mat[i][j] - B->mat[i][j];
//return C;
}
matrice * mult_by_scal_matrice(matrice * A, double k){
if(k == 0.0){
matrice * C = alloc_matrice(A->n, A->m);
return C;
}
for(int i = 0; i<A->n;i++)
for(int j = 0; j < A->m;j++)
if(A->mat[i][j]!=0) A->mat[i][j]*=k;
return A;
}
void mult_matrice(matrice* C,matrice* A, matrice *B)
{
if(A->m != B->n)
{ printf("Erreur dans ladimensoin des matrices\n");
}
double somme;
// matrice * C = alloc_matrice(A->n,B->m);
for(int i = 0; i < A->n; i++)
for(int j = 0; j < B->m; j++){
somme = 0;
for(int k=0; k < A->m; k++)
somme += A->mat[i][k]*B->mat[k][j];
C->mat[i][j] = somme;
}
}
void trans_matrice(matrice * C,matrice* A)
{
//matrice* C= alloc_matrice(A->m,A->n);
for(int i = 0; i < A->n; i++)
for(int j = 0; j < A->m; j++)
C->mat[j][i] = A->mat[i][j];
//return C;
}
void affiche_matrice(matrice* A)
{
for(int i = 0; i < A->n; i++){
printf("\n");
for(int j = 0; j < A->m; j++)
printf("%f\t",A->mat[i][j]);
}
printf("\n\n");
}
double determinant_matrice (matrice *m)
{
if(m->n != m->n){
printf("La matrice n'est pas une matrice carrée\n");
return NULL;
}
matrice * sous_m = alloc_matrice(m->n-1, m->m-1);;
int signe=1;
double det=0;
if (m->n==1) return (m->mat[0][0]);
if(m->n==2)
return m->mat[0][0]*m->mat[1][1]-m->mat[1][0]*m->mat[0][1];
for (int j=0;j<m->n;j++){
// for(int j=0;j< m->m; j++){
mineur_matrice(sous_m,m,0,j);
signe=((j)%2 == 0)?1:-1;
det+=signe*m->mat[0][j]*determinant_matrice(sous_m);
}
free_matrice(sous_m);
free(sous_m);
return(det);
}
void mineur_matrice(matrice * min_A, matrice* A, int n,int m)
{
int ii = 0;
int jj = 0;
if(A->n == 1)
min_A->mat[0][0] = A->mat[0][0];
for(int i = 0; i < A->n; i++){
for(int j = 0; j < A->m; j++){
if(i != n && j!=m){
min_A->mat[ii][jj] = A->mat[i][j];
jj++;
}
}
if(i!=n) {ii++; jj=0;}
}
}
void trans_comatrice(matrice * CoA_t, matrice *A)
{
char signe = 1;
matrice* CoA = alloc_matrice(A->n,A->m);
matrice* min_A = alloc_matrice(A->n-1, A->m-1);
if(determinant_matrice(A)==0){
printf("La matrice est non inversible,sont déterminant est nul\n");
exit(0);
}
for(int i = 0; i < CoA->n; i++)
for(int j = 0; j < CoA->m; j++){
signe = ((i+j)%2 ==0)?1:-1;
mineur_matrice(min_A, A, i, j);
CoA->mat[i][j] = signe*determinant_matrice(min_A);
}
trans_matrice(CoA_t, CoA);
free_matrice(CoA);free(CoA);
free_matrice(min_A);free(min_A);
}
void inverse_matrice(matrice * A_1, matrice * A)
{
if(A->n != A->m){
printf("La matrice n'estpas une matrice carée, et ne peux donc etre inversée\n");
exit(0);
}
double det = determinant_matrice(A);
if(det == 0){
printf("Votre matrice est non inversible car de déterminant nul\n");
exit(0);
}
trans_comatrice(A_1,A);
for(int i = 0; i< A_1->n; i++)
for(int j = 0; j< A_1->m;j++)
A_1->mat[i][j]/=det;
}
bonjour
permettez moi d entre a ce forum , mais je veux savoir une définition d'une matrice inverse , et surtout comment on peux avoir une matrice inverse B d'une mztrice donnée A juste en utilisant la méthode de gauss qui se base sur le faite d'utliser les formules de triangularisations , merci :00000025:
je vous rappelle stp juste avec la méthode de GAUSS merci
maleaume
27/10/2005, 14h53
ben d'abord demande toi ce qu'est une matrice de transformation...??
bon ben c'est une façon de representer les transformation du plan ou de l'espace.. que peut bien etre la matrice inverse...??
surement la transformation inverse representer par la matrice..
et qu'elle est la particulariuté de cette matrice inverse?
soit A la matrice et A_1 la matrice inverse
alors AxA_1 = A_1xA = Identité ou x est la multiplication matricielle
gros so modo . cette matrie te donne la transformation inverse qui te permettra de revenir à l'état initiale.. ou de revenir d nas le referentiel que tu desir. tres pratique donc ..
apres la méthode de gauss est une autre façon de resoudre le probleme en l'utilisant comme un systme lineaire.. dont une methode qui permette de les resoudre s'appuye sur la pyramide de gauss.
Voici un site qui m'a beaucoup aidé :
http://jeux.developpez.com/faq/matquat/?page=determinants_inverses
vBulletin® v.3.6.5, Copyright ©2000-2009, Jelsoft Enterprises Ltd. Tous droits réservés - Version française vbulletin-fr.org