#include #include #include "matrice.h" #define ELEM(mat,i,j) ((mat)->elements + (i) * (mat)->dim2 + (j)) static matrice mat_creer_matrice (indice dim1, indice dim2, anneau a); static void libere_element (anneau a, void *elt); static void *duplique_element (anneau a, void *elt); struct matrice_prive { indice dim1; indice dim2; void ***elements; anneau a; }; struct anneau { void *element_nul; binaire somme; binaire produit; unaire dupliquer; free_function liberer_element; }; anneau anneau_creer (constante element_nul, binaire somme, binaire produit, unaire dupliquer, free_function liberer_element) { anneau a = (anneau) malloc (sizeof (struct anneau)); assert (a != NULL); *a = (struct anneau) {element_nul, somme, produit, dupliquer, liberer_element}; return a; } static matrice mat_creer_matrice (indice dim1, indice dim2, anneau a) { struct matrice_prive *m; size_t i; m = (matrice) malloc (sizeof (struct matrice_prive)); m->dim1 = dim1; m->dim2 = dim2; m->a = a; m->elements = malloc (dim2 * sizeof (void *)); m->elements[0] = calloc (dim1 * dim2 * sizeof (void *)); assert (m->elements[0] != NULL); for(i=1; i < dim2; i++) m->elements[i] = m->elements[0] + dim1 * i; return (matrice) m; } matrice mat_creer_matrice_nulle (indice dim1, indice dim2, anneau a) { indice i; matrice m = mat_creer_matrice (dim1, dim2, a); for (i = 0; i < dim1 * dim2; i++) m->elements[i] = a->zero; return m; } static void * duplique_element (anneau a, void *elt) { return (elt != a->zero) ? a->dupliquer (elt) : elt; } void mat_liberer (matrice m) { indice i; for (i = 0; i < m->dim1 * m->dim2; i++) libere_element (m->a, m->elements[i]); free (m->elements); free (m); } matrice mat_creer_copie (matrice source) { indice i; matrice copie; copie = mat_creer_matrice (source->dim1, source->dim2, source->a); for (i = 0; i < source->dim1 * source->dim2; i++) copie->elements[i] = duplique_element (source->a, source->elements[i]); return copie; } void mat_affecter_element (matrice m, indice i, indice j, void *valeur) { assert (valeur); VERIFIER_INDICES (m, i, j); libere_element (m->a, *ELEM (m, i, j)); *ELEM (m, i, j) = valeur; /* dupliquer ou pas ??? */ } void * mat_valeur_element (matrice m, indice i, indice j) { VERIFIER_INDICES (m, i, j); return *ELEM (m, i, j); } matrice mat_somme (matrice a, matrice b) { matrice m; indice i, j; /* verifier la compatibilite des dimensions */ assert (a->dim1 == b->dim1 && a->dim2 == b->dim2 && a->a == b->a); m = mat_creer_matrice (a->dim1, a->dim2, a->a); for (i = 0; i < a->dim1; i++) for (j = 0; j < a->dim2; j++) { assert (*ELEM (a, i, j) && *ELEM (b, i, j)); *ELEM (m, i, j) = a->a->somme (*ELEM (a, i, j), *ELEM (b, i, j)); } return m; } matrice mat_produit (matrice a, matrice b) { matrice m; assert (a->dim2 == b->dim1 && a->a == b->a); /* verifier la compatibilite */ m = mat_creer_matrice (a->dim1, b->dim2, a->a); { indice i, j; for (i = 0; i < a->dim1; i++) for (j = 0; j < b->dim2; j++) { indice k; void *sigma = a->a->zero; for (k = 0; k < b->dim1; k++) { void *prod, *tmp; prod = a->a->produit (*ELEM (a, i, j), *ELEM (b, j, k)); tmp = a->a->somme (prod, sigma); libere_element (a->a, prod); libere_element (a->a, sigma); sigma = tmp; } *ELEM (m, i, j) = sigma; } return m; } } matrice mat_transposee (matrice m) { matrice transposee; indice i, j; transposee = mat_creer_matrice (m->dim2, m->dim1, m->a); for (i = 0; i < m->dim1; i++) for (j = 0; j < m->dim2; j++) *ELEM (transposee, j, i) = duplique_element (m->a, *ELEM (m, i, j)); return transposee; }