Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

OPÉRATION SUR MATRICE


Information sur la source

Catégorie :Maths & Algorithmes Niveau : Débutant Date de création : 07/06/2004 Date de mise à jour : 07/06/2004 12:39:09 Vu : 9 935

Note :
10 / 10 - par 2 personnes
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (10)
Ajouter un commentaire et/ou une note

Description

quelques fonctions et une structure simple permettant de calculer des opérations courantes sur les matrices: transposée, multiplication, addition, déterminant, inversion, comatrice, moindre carré...
 

Source

  • #include <stdio.h>
  • #include <stdlib.h>
  • #include <math.h>
  • typedef struct{
  • int n, m; /*n->lignes, m->colonnes*/
  • double **P;/*Matrice*/
  • } *Matrice, structMatrice;
  • Matrice allouerMatrice(int l,int c){/*allouer une matrice de l lignes et c colonnes*/
  • Matrice A;
  • int i;
  • A=(Matrice)malloc(sizeof(structMatrice));
  • A->n=l;A->m=c;
  • A->P=(double**)malloc(l*sizeof(double*));
  • for(i=0;i<l;i++) {
  • A->P[i]=(double *)malloc(c*sizeof(double ));
  • }
  • return A;
  • }
  • void libererMatrice(Matrice A){/*libÃ&#168;re l'espace mémoire occupé par la matrice*/
  • int i;
  • for(i=0;i<A->n;i++)free(A->P[i]);
  • }
  • int deMemeDim(Matrice A, Matrice B){/*teste si les matrices A et B sont de même dimension*/
  • if(A->n == B->n && A->m == B->m)return 1;
  • return 0;
  • }
  • Matrice Mat_add(Matrice A, Matrice B){/*renvoie la matrice issue de l'addition de A et de B*/
  • int i,j;
  • Matrice C;
  • if(!deMemeDim(A,B))return NULL;
  • C=allouerMatrice(A->n,A->m);
  • for(i=0;i<A->n;i++){
  • for(j=0;j<A->m;j++){
  • C->P[i][j]=A->P[i][j]+B->P[i][j];
  • }
  • }
  • return C;
  • }
  • Matrice Mat_Id(int n){/*renvoie la matrice identité de dimension n x n */
  • int i,j;
  • Matrice C;
  • C=allouerMatrice(n,n);
  • for(i=0;i<n;i++){
  • for(j=0;j<n;j++){
  • if(i!=j)C->P[i][j]=0;
  • else C->P[i][j]=1;
  • }
  • }
  • return C;
  • }
  • Matrice Mat_nulle(int n){/*renvoie une matrice nulle*/
  • int i,j;
  • Matrice C;
  • C=allouerMatrice(n,n);
  • for(i=0;i<n;i++){
  • for(j=0;j<n;j++){
  • C->P[i][j]=0;
  • }
  • }
  • return C;
  • }
  • Matrice Mat_mul(Matrice A, double c){/*renvoie le produit de A par le scalaire c*/
  • int i,j;
  • Matrice C;
  • C=allouerMatrice(A->n,A->m);
  • for(i=0;i<A->n;i++){
  • for(j=0;j<A->m;j++){
  • C->P[i][j]=c*A->P[i][j];
  • }
  • }
  • return C;
  • }
  • Matrice Mat_dot(Matrice A, Matrice B){/*renvoie le produit de A et B,
  • renvoie NULL si l'opération n'est pas possible*/
  • int i,j,k;
  • Matrice C;
  • if(A->m!=B->n)return NULL;
  • C=allouerMatrice(A->n,B->m);
  • for(i=0;i<C->n;i++){
  • for(j=0;j<C->m;j++){
  • for(k=0;k<A->m;k++){
  • C->P[i][j]+= A->P[i][k]*B->P[k][j];
  • }
  • }
  • }
  • return C;
  • }
  • Matrice Mat_transpose(Matrice A){/*renvoie la transposée de la matrice A*/
  • int i,j;
  • Matrice C;
  • C=allouerMatrice(A->m,A->n);
  • for(i=0;i<C->n;i++){
  • for(j=0;j<C->m;j++){
  • C->P[i][j]=A->P[j][i];
  • }
  • }
  • return C;
  • }
  • Matrice Mat_sousMat(Matrice A,int ib,int jb){/*renvoie la matrice A à laquelle à été supprimé
  • la ib°ligne et la jb° colonne*/
  • int i,j;
  • int is=0,js=0;
  • Matrice B;
  • B=allouerMatrice(A->n-1,A->m-1);
  • for(i=0;i<A->n;i++){
  • for(j=0;j<A->m;j++){
  • if(i!=ib && j!=jb){
  • B->P[is][js]=A->P[i][j];
  • if(js<B->n-1)js++;
  • else{js=0;is++;}
  • }
  • }
  • }
  • return B;
  • }
  • double Mat_determinant(Matrice A){/*renvoie le déterminant de la matrice A*/
  • int i,j;
  • double det=0;
  • Matrice B;
  • //condition d'arret
  • if(A->n==1)return A->P[0][0];
  • if(A->n==2)return A->P[0][0]*A->P[1][1]-A->P[0][1]*A->P[1][0];
  • //condition de descente dans la récurrence
  • else{
  • for(j=0;j<A->m;j++){
  • B=Mat_sousMat(A,0,j);
  • if(j%2==0){det+=A->P[0][j]*Mat_determinant(B);}
  • else{det+=(-1)*A->P[0][j]*Mat_determinant(B);}
  • libererMatrice(B);
  • }
  • }
  • return det;
  • }
  • void Mat_afficherMat(Matrice A){/*affiche la matrice A*/
  • int i,j;
  • printf("\n Matrice %dx%d :\n",A->n,A->m);
  • for(i=0;i<A->n;i++){
  • for(j=0;j<A->m;j++){
  • printf("%f\t",A->P[i][j]);
  • }
  • printf("\n");
  • }
  • }
  • void Mat_remplirMatrice(Matrice A){/*remplie la matrice A par saisie au clavier*/
  • int i,j;
  • printf("\nRemplissage de matrice %dx%d\n",A->n,A->m);
  • for(i=0;i<A->n;i++){
  • for(j=0;j<A->m;j++){
  • printf("element (%d,%d)?",i,j);
  • scanf("%lf",&(A->P[i][j]));
  • }
  • }
  • }
  • Matrice Mat_coMat(Matrice A){/*renvoie la comatrice de A*/
  • int i,j;
  • Matrice B;
  • Matrice S;
  • B=allouerMatrice(A->n,A->m);
  • //S=allouerMatrice(A->n-1,A->m-1);
  • for(i=0;i<B->n;i++){
  • for(j=0;j<B->m;j++){
  • S=Mat_sousMat(A,i,j);
  • if((i+j)%2==0){B->P[i][j]=Mat_determinant(S);}
  • else{B->P[i][j]=-1*Mat_determinant(S);}
  • libererMatrice(S);
  • }
  • }
  • return B;
  • }
  • Matrice Mat_invMat(Matrice A){/*renvoie la matrice inverse de A*/
  • double det;
  • Matrice coA,t_coA,inv_A;
  • det=Mat_determinant(A);
  • if(det==0)return NULL;
  • coA=Mat_coMat(A);
  • t_coA=Mat_transpose(coA);
  • inv_A=Mat_mul(t_coA,1/det);
  • libererMatrice(coA);
  • libererMatrice(t_coA);
  • libererMatrice(inv_A);
  • return inv_A;
  • }
  • int Mat_moindreCarre(Matrice A,Matrice *U,Matrice B){/*résout A.U=B par la méthode de moindre carré
  • renvoie 1 si le calcul est possible, 0 sinon*/
  • Matrice At,AtA,AtA_inv,AtA_inv_At;
  • At=Mat_transpose(A);
  • AtA=Mat_dot(At,A);
  • AtA_inv=Mat_invMat(AtA);
  • if(AtA_inv==NULL)return 0;
  • AtA_inv_At=Mat_dot(AtA_inv,At);
  • *U=Mat_dot(AtA_inv_At,B);
  • libererMatrice(At);
  • libererMatrice(AtA);
  • libererMatrice(AtA_inv);
  • libererMatrice(AtA_inv_At);
  • return 1;
  • }
  • int main(){
  • Matrice A,B,C,D,U;
  • double det;
  • int i,j;
  • /*A=allouerMatrice(3,3);
  • Mat_remplirMatrice(A);
  • Mat_afficherMat(A);
  • getchar();
  • B=Mat_mul(A,3.2);
  • Mat_afficherMat(B);
  • getchar();
  • libererMatrice(B);
  • B=Mat_Id(3);
  • C=Mat_dot(A,B);
  • Mat_afficherMat(C);
  • getchar();
  • det=Mat_determinant(A);
  • printf("det(A)=%lf\n",det);
  • getchar();
  • A=Mat_mul(A,2);
  • Mat_afficherMat(A);
  • getchar();
  • D=allouerMatrice(2,2);
  • Mat_remplirMatrice(D);
  • Mat_afficherMat(D);
  • det=Mat_determinant(D);
  • printf("det=%lf\n",det);
  • D=Mat_invMat(D);
  • D=Mat_mul(D,det);
  • Mat_afficherMat(D);*/
  • //Test Méthode de moindre carré
  • A=allouerMatrice(10,4);
  • B=allouerMatrice(10,1);
  • for(i=0;i<A->n;i++){
  • B->P[i][0]=(double)rand()*10/RAND_MAX;
  • for(j=0;j<A->m;j++){
  • A->P[i][j]=(double)rand()*10/RAND_MAX;
  • }
  • }
  • Mat_afficherMat(A);
  • Mat_afficherMat(B);
  • Mat_moindreCarre(A,&U,B);
  • Mat_afficherMat(U);
  • libererMatrice(A);
  • libererMatrice(B);
  • libererMatrice(U);
  • }
#include <stdio.h>
#include <stdlib.h>
#include <math.h>


typedef struct{
	int n, m; /*n->lignes, m->colonnes*/
  	double **P;/*Matrice*/
} *Matrice, structMatrice;


Matrice allouerMatrice(int l,int c){/*allouer une matrice de l lignes et c colonnes*/
	Matrice A;
	int i;
	A=(Matrice)malloc(sizeof(structMatrice));
	A->n=l;A->m=c;
	A->P=(double**)malloc(l*sizeof(double*));
	for(i=0;i<l;i++) {
		A->P[i]=(double *)malloc(c*sizeof(double ));
	}
	return A;
}

void libererMatrice(Matrice A){/*libÃ&#168;re l'espace mémoire occupé par la matrice*/
	int i;
	for(i=0;i<A->n;i++)free(A->P[i]);
}
int deMemeDim(Matrice A, Matrice B){/*teste si les matrices A et B sont de même dimension*/
	if(A->n == B->n && A->m == B->m)return 1;
	return 0;
}

Matrice Mat_add(Matrice A, Matrice B){/*renvoie la matrice issue de l'addition de A et de B*/
	int i,j;
	Matrice C;
	if(!deMemeDim(A,B))return NULL;
	C=allouerMatrice(A->n,A->m);
	for(i=0;i<A->n;i++){
		for(j=0;j<A->m;j++){
			C->P[i][j]=A->P[i][j]+B->P[i][j];
		}
	}
	return C;
}

Matrice Mat_Id(int n){/*renvoie la matrice identité de dimension n x n */
	int i,j;
	Matrice C;
	C=allouerMatrice(n,n);
	for(i=0;i<n;i++){
		for(j=0;j<n;j++){
			if(i!=j)C->P[i][j]=0;
			else C->P[i][j]=1;
		}
	}
	return C;
}

Matrice Mat_nulle(int n){/*renvoie une matrice nulle*/
	int i,j;
	Matrice C;
	C=allouerMatrice(n,n);
	for(i=0;i<n;i++){
		for(j=0;j<n;j++){
			C->P[i][j]=0;
		}
	}
	return C;
}
Matrice Mat_mul(Matrice A, double c){/*renvoie le produit de A par le scalaire c*/
	int i,j;
	Matrice C;
	C=allouerMatrice(A->n,A->m);
	for(i=0;i<A->n;i++){
		for(j=0;j<A->m;j++){
			C->P[i][j]=c*A->P[i][j];
		}
	}
	return C;
}



Matrice Mat_dot(Matrice A, Matrice B){/*renvoie le produit de A et B,
	renvoie NULL si l'opération n'est pas possible*/
	int i,j,k;
	Matrice C;
	if(A->m!=B->n)return NULL;
	C=allouerMatrice(A->n,B->m);
	for(i=0;i<C->n;i++){
		for(j=0;j<C->m;j++){
			for(k=0;k<A->m;k++){
			C->P[i][j]+= A->P[i][k]*B->P[k][j];
			}
		}
	}
	
	return C;
}

Matrice Mat_transpose(Matrice A){/*renvoie la transposée de la matrice A*/
	int i,j;
	Matrice C;
	C=allouerMatrice(A->m,A->n);
	for(i=0;i<C->n;i++){
		for(j=0;j<C->m;j++){
			C->P[i][j]=A->P[j][i];
		}
	}
	return C;
}



Matrice Mat_sousMat(Matrice A,int ib,int jb){/*renvoie la matrice A à laquelle à été supprimé
	la ib°ligne et la jb° colonne*/
	int i,j;
	int is=0,js=0;
	Matrice B;
	B=allouerMatrice(A->n-1,A->m-1);
	for(i=0;i<A->n;i++){
		for(j=0;j<A->m;j++){
			if(i!=ib && j!=jb){
			B->P[is][js]=A->P[i][j];
			if(js<B->n-1)js++;
			else{js=0;is++;}	
			}
		}
	}
	return B;
}
double Mat_determinant(Matrice A){/*renvoie le déterminant de la matrice A*/
	int i,j;
	double det=0;
	Matrice B;
	//condition d'arret
	if(A->n==1)return A->P[0][0];
	if(A->n==2)return A->P[0][0]*A->P[1][1]-A->P[0][1]*A->P[1][0];
	//condition de descente dans la récurrence
	else{
		for(j=0;j<A->m;j++){
		B=Mat_sousMat(A,0,j);
		if(j%2==0){det+=A->P[0][j]*Mat_determinant(B);}
		else{det+=(-1)*A->P[0][j]*Mat_determinant(B);}
		libererMatrice(B);
		}
	}
	return det;
}
void Mat_afficherMat(Matrice A){/*affiche la matrice A*/
	int i,j;
	printf("\n Matrice %dx%d :\n",A->n,A->m);
	for(i=0;i<A->n;i++){
		for(j=0;j<A->m;j++){
			printf("%f\t",A->P[i][j]);
		}
		printf("\n");
	}
}
void Mat_remplirMatrice(Matrice A){/*remplie la matrice A par saisie au clavier*/
	int i,j;
	printf("\nRemplissage de matrice %dx%d\n",A->n,A->m);
	for(i=0;i<A->n;i++){
		for(j=0;j<A->m;j++){
			printf("element (%d,%d)?",i,j);
			scanf("%lf",&(A->P[i][j]));
		}
	}
}

Matrice Mat_coMat(Matrice A){/*renvoie la comatrice de A*/
	int i,j;
	Matrice B;
	Matrice S;
	B=allouerMatrice(A->n,A->m);
	//S=allouerMatrice(A->n-1,A->m-1);
	for(i=0;i<B->n;i++){
		for(j=0;j<B->m;j++){
			S=Mat_sousMat(A,i,j);
			if((i+j)%2==0){B->P[i][j]=Mat_determinant(S);}
			else{B->P[i][j]=-1*Mat_determinant(S);}
			libererMatrice(S);
		}
	}
	return B;
}
Matrice Mat_invMat(Matrice A){/*renvoie la matrice inverse de A*/
	double det;
	Matrice coA,t_coA,inv_A;
	det=Mat_determinant(A);
	if(det==0)return NULL;
	coA=Mat_coMat(A);
	t_coA=Mat_transpose(coA);
	inv_A=Mat_mul(t_coA,1/det);
	libererMatrice(coA);
	libererMatrice(t_coA);
	libererMatrice(inv_A);
	return inv_A;
}

int Mat_moindreCarre(Matrice A,Matrice *U,Matrice B){/*résout A.U=B par la méthode de moindre carré
	renvoie 1 si le calcul est possible, 0 sinon*/
	Matrice At,AtA,AtA_inv,AtA_inv_At;
	At=Mat_transpose(A);
	AtA=Mat_dot(At,A);
	AtA_inv=Mat_invMat(AtA);
	if(AtA_inv==NULL)return 0;
	AtA_inv_At=Mat_dot(AtA_inv,At);
	*U=Mat_dot(AtA_inv_At,B);
	libererMatrice(At);
	libererMatrice(AtA);
	libererMatrice(AtA_inv);
	libererMatrice(AtA_inv_At);
	return 1;
}
int main(){
	Matrice A,B,C,D,U;
	double det;
	int i,j;
	/*A=allouerMatrice(3,3);
	Mat_remplirMatrice(A);
	Mat_afficherMat(A);
	getchar();
	B=Mat_mul(A,3.2);
	Mat_afficherMat(B);
	getchar();
	libererMatrice(B);
	B=Mat_Id(3);
	C=Mat_dot(A,B);
	Mat_afficherMat(C);
	getchar();
	det=Mat_determinant(A);
	printf("det(A)=%lf\n",det);
	getchar();
	A=Mat_mul(A,2);
	Mat_afficherMat(A);
	getchar();	
	D=allouerMatrice(2,2);
	Mat_remplirMatrice(D);
	Mat_afficherMat(D);
	det=Mat_determinant(D);
	printf("det=%lf\n",det);
	D=Mat_invMat(D);
	D=Mat_mul(D,det);
	Mat_afficherMat(D);*/
	//Test Méthode de moindre carré
	A=allouerMatrice(10,4);
	B=allouerMatrice(10,1);
	for(i=0;i<A->n;i++){
		B->P[i][0]=(double)rand()*10/RAND_MAX;
		for(j=0;j<A->m;j++){
			A->P[i][j]=(double)rand()*10/RAND_MAX;
		}
	}
	
	Mat_afficherMat(A);
	Mat_afficherMat(B);
	Mat_moindreCarre(A,&U,B);
	Mat_afficherMat(U);
	libererMatrice(A);
	libererMatrice(B);
	libererMatrice(U);
}

Commentaires et avis

signaler à un administrateur
Commentaire de Kornferki le 16/06/2004 14:44:21

Je ne suis pas sur que la dimension des matrices soit vraiment de n et m. Si dans tes boucles tu vas de 0 a n ou m, les dimensions seraient plutot de n+1 a m+1, isnt it ???

Que se passe t il si ta matrice n est pas carree et que tu calcules le determinant ?

signaler à un administrateur
Commentaire de bonac le 06/07/2004 16:04:50

J'ai pour abitude de travaillé à partir de l'indexe 0, mes boucles for s'arrètes à n-1. Il y a donc bien n valeur dans [0; n-1]. En d'autres termes pour une matrice n,m avec les paramètre n,m fournie en entrée les boucle parcourirons [0,n-1](n éléments) et [0,m-1] (m éléments), ont aura bine une matrice n,m.

signaler à un administrateur
Commentaire de Cyber_steph le 30/07/2004 10:59:27

bonjour,

j'ai voulut utiliser cette source mais apparement la multiplication et l'inverssion ne marche pas.

C bien dommage car ce code m'interessait bc.

bye

signaler à un administrateur
Commentaire de zbigzo le 19/01/2005 18:06:41

c bien ce que t'as fai je te souhai 1 bon continuat°

signaler à un administrateur
Commentaire de Byron202 le 06/06/2005 09:54:38

Je confirme un bug dans la partie inversion de matrice.
Multiplication, j'ai pas encore vérifié.

signaler à un administrateur
Commentaire de Byron202 le 06/06/2005 16:30:40

Il suffit en fait de mettre le libererMatrice  "APRES" le return detA.
En effet, dans le code, on libère la mémoire avant de retourner la valeur d'où le bug et donc le calcul du determinant déconne.

signaler à un administrateur
Commentaire de regisbeg le 09/11/2005 18:23:44

Pour la multiplication, remplacer dans la fonction de multiplication des matrices C->P[i][j] += A->P[i][k] * B->P[k][j]; en mettant un espace de chaque coté de la multiplication sans quoi le compilateur considère B->P[k][j] comme un pointeur.

signaler à un administrateur
Commentaire de Amanobuo le 02/04/2007 23:31:40

Merci ! c'est exactement ce que je cherchais !
J'était frustre de pas y arriver pour la multiplications ! Mais je me suis trop embrouillé avec ces math !

signaler à un administrateur
Commentaire de Gaston0510 le 20/03/2008 16:53:54

merci Bonac c un enorme travail !!
enfet c presque notr sujet mai seulement avec les bibliotheque stdio.h, string.h, conio.h ..
et dans mon projet on ns demande de faire un quadrillage double lor d l'affichage des matrices ..
Alors peut tu m'aider ou m montrer comment faire ce quadrillage ?

signaler à un administrateur
Commentaire de didou4545 le 30/04/2009 14:43:53

Il y a une faute dans cette fonction
[code]

# Matrice Mat_invMat(Matrice A){/*renvoie la matrice inverse de A*/
# double det;
# Matrice coA,t_coA,inv_A;
# det=Mat_determinant(A);
# if(det==0)return NULL;
# coA=Mat_coMat(A);
# t_coA=Mat_transpose(coA);
# inv_A=Mat_mul(t_coA,1/det);
# libererMatrice(coA);
# libererMatrice(t_coA);
# libererMatrice(inv_A);    // ici vous libérer la matrice " inv_A " puis vous la retourné tout de suite !!
# return inv_A;
# }  


[/code]

Ajouter un commentaire



Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,265 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.