rendered paste body#include <stdio.h>#include <stdlib.h>#define max(a,b) ((a)>(b) ? (a) : (b))#define INDEX 1#define ADR(l,c,nbc) (((l)-INDEX)*(nbc)+(c)-INDEX)#define MATI mat.i#define MATF mat.f#define MATD mat.d#define MATL mat.l#define ELEM(MATR,i) (MATR->composante == FLOAT ? (MATR->MATF[(i)]) : (MATR->composante == LONG ? (MATR->MATL[(i)]) : (MATR->composante == DOUBLE ? (MATR->MATD[(i)]) : (MATR->MATI[(i)]))))typedef int * mat_int; /* Tableau d'entiers */typedef float * mat_float; /* Tableau de flottants */typedef double * mat_double; /* Tableau de flottants double précision */typedef long * mat_long; /* Tableau d'entiers double précision */typedef enum {INT, LONG, FLOAT, DOUBLE} type; /* Type de tableau */typedef struct { type composante; /* Type de composantes */ union { mat_int i; mat_float f; mat_double d; mat_long l; } mat; /* Le tableau en lui-même */ int nbc; /* Nombre de colonnes */ int nbl; /* Nombre de lignes */} mat_dyn;/*****************************************************************************//* *//* alloc_mrd *//* *//* But : Initialisation d'une Matrice dynamique *//* *//* Interface : A : pointeur vers une mat_dyn *//* nbl : entier nombre de lignes *//* nbc : entier nombre de colonnes *//* composante : type de la composante *//* *//*****************************************************************************/void alloc_mrd(mat_dyn * A,int nbl, int nbc, type composante) { A->composante = composante; if(composante == INT) A->MATI = (mat_int)malloc((nbl*nbc)*sizeof(int)); else if(composante == FLOAT) A->MATF = (mat_float)malloc((nbl*nbc)*sizeof(float)); else if(composante == DOUBLE) A->MATD = (mat_double)malloc((nbc*nbl)*sizeof(double)); else if(composante == LONG) A->MATL = (mat_long)malloc((nbc*nbl)*sizeof(long)); A->nbl = nbl; A->nbc = nbc; printf("Allocation d'une matrice (%d,%d)\n",A->nbl,A->nbc); }/*****************************************************************************//* *//* print_mrd *//* *//* But : Sortie formatée d'une matrice dynamique *//* *//* Interface : A : pointeur vers une mat_dyn *//* *//*****************************************************************************/void print_mrd(mat_dyn *M) { int i,j; int nbl = M->nbl; int nbc = M->nbc; if(nbc == 0 && nbl == 0) printf("\nMatrice fausse\n"); else { printf("\n"); for(i=1; i<= nbl; i++) { printf("|"); for(j=1; j<= nbc; j++) if(M->composante == INT) printf(" %10d ",M->MATI[ADR(i,j,nbc)]); else if(M->composante == FLOAT) printf(" %10f ",M->MATF[ADR(i,j,nbc)]); else if(M->composante == LONG) printf(" %10ld ",M->MATL[ADR(i,j,nbc)]); else if(M->composante == DOUBLE) printf(" %10.5f ",M->MATF[ADR(i,j,nbc)]); printf("|\n"); } printf("\n"); } }/*****************************************************************************//* *//* assign_mrd *//* *//* But : Insertion d'une valeur à la position i,j d'une matrice dynamique *//* *//* Interface : A : pointeur vers une mat_dyn *//* i : ligne *//* j : colonne *//* value : double à assigner (transtypée au type *//* de destination) *//* *//*****************************************************************************/void assign_mrd(mat_dyn *A, int i, int j, double value) { if(A->composante == INT) A->MATI[ADR(i,j,A->nbc)] = (int)value ; else if(A->composante == FLOAT) A->MATF[ADR(i,j,A->nbc)] = (float)value ; else if(A->composante == LONG) A->MATL[ADR(i,j,A->nbc)] = (long)value ; else if(A->composante == DOUBLE) A->MATD[ADR(i,j,A->nbc)] = (double)value; }/*****************************************************************************//* *//* multiply_mrd *//* *//* But : calcul de C=A*B *//* *//* Interface : C : pointeur vers la mat_dyn de destination *//* A : pointeur vers une mat_dyn *//* B : pointeur vers une mat_dyn *//* *//*****************************************************************************/void multiply_mrd(mat_dyn *C,mat_dyn *A, mat_dyn *B) { if(A->nbc != B->nbl) alloc_mrd(C,0,0,max(A->composante,B->composante)); else { int i,j,k; double l; alloc_mrd(C,A->nbl,B->nbc,max(A->composante,B->composante)); for(i=1; i <= C->nbl; i++) for(j=1; j <= C->nbc; j++) { l = 0; for(k=1; k <= A->nbc; k++) l += ELEM(A,ADR(i,k,A->nbc))*ELEM(B,ADR(k,j,B->nbc)) ; assign_mrd(C,i,j,l); } } }/*****************************************************************************//* *//* identity_mrd *//* *//* But : Initialisation de la matrice identité d'ordre n *//* *//* Interface : A : pointeur vers une mat_dyn *//* n : entier dimension de la matrice *//* *//*****************************************************************************/void identity_mrd(mat_dyn *A,int n) { alloc_mrd(A,n,n,INT); int i,j; for(i=1; i <= n; i++) for(j=1; j <= n; j++) assign_mrd(A,i,j, (i==j) ? 1 : 0); }/*****************************************************************************//* *//* row_swap_mrd *//* *//* But : Echange les lignes i et j de A *//* *//* Interface : A : pointeur vers une mat_dyn *//* i : Numéro de ligne *//* j : Numéro de l'autre ligne *//* *//*****************************************************************************/void row_swap_mrd(mat_dyn *A,int i, int j) { int k; if(i <= A->nbl && j <= A->nbl) { double tmp ; for(k = 1; k<= A->nbc; k++) { tmp = ELEM(A,ADR(i,k,A->nbc)); assign_mrd(A,i,k,ELEM(A,ADR(j,k,A->nbc))); assign_mrd(A,j,k,tmp); } } }/*****************************************************************************//* *//* row_add_k_row_mrd *//* *//* But : Remplace la ligne i de A par A[i]+k*A[j] *//* *//* Interface : A : pointeur vers une mat_dyn *//* i : Numéro de la ligne recevant la somme *//* j : Numéro de la ligne ajoutée *//* k : Facteur de multiplication *//* NOTA : La matrice est transtypée en double avant *//* d'effectuer les opérations *//* *//*****************************************************************************/void row_add_k_row_mrd(mat_dyn *A, int i, int j, double k) { int l,m,n; if(i <= A->nbl && j <= A->nbl) { if(A->composante != DOUBLE) { A->MATD = (mat_double)malloc((A->nbc*A->nbl)*sizeof(double)); for(m = 1; m<= A->nbl; m++) for(n = 1; n<= A->nbc; n++) A->MATD[ADR(m,n,A->nbc)] = (double)ELEM(A,ADR(m,n,A->nbc)); A->composante = DOUBLE; } print_mrd(A); for(l = 1; l<= A->nbc; l++) A->MATD[ADR(i,l,A->nbc)] += k * (A->MATD[ADR(j,l,A->nbc)]); } }/*****************************************************************************//* *//* main *//* */ /*****************************************************************************/int main(int argc, char * argv[]) { int i,j; mat_dyn *A,*B,*C ; A = malloc(sizeof(mat_dyn)); B = malloc(sizeof(mat_dyn)); C = malloc(sizeof(mat_dyn)); alloc_mrd(A,4,3,INT); alloc_mrd(B,3,4,FLOAT); for(i=1; i <= 4; i++) for(j=1; j <= 3; j++) A->MATI[ADR(i,j,A->nbc)] = (i>j) ? 2 : 1; for(i=1; i <= 3; i++) for(j=1; j <= 4; j++) B->MATF[ADR(i,j,B->nbc)] = (i>j) ? 1.4 : 2.3; multiply_mrd(C,A,B); print_mrd(A); row_swap_mrd(A,1,2); print_mrd(A); row_add_k_row_mrd(A, 2, 1, -0.5); print_mrd(A); print_mrd(B); print_mrd(C); free(A),A=NULL; free(B),B=NULL; free(C),C=NULL; printf("Libération de 3 matrices\n"); return(EXIT_SUCCESS); }