Skip to content
Snippets Groups Projects
Commit 26d9a3f6 authored by orestis.malaspin's avatar orestis.malaspin
Browse files

update

parent 17750c51
No related branches found
No related tags found
No related merge requests found
......@@ -27,108 +27,153 @@ Utilisation de pointeurs sur des pointeurs en `C`.
## Énoncé
Écrire des fichiers `matrix.h` et `matrix.c` pour manipuler des matrices de nombres à virgule flottantes.
Écrire des fichiers `matrix.h` et `matrix.c` pour manipuler des matrices de nombres à virgule flottante.
Le contenu de la matrice devra être alloué dans une zone contiguë de la mémoire, tout en restant accessible par l'opérateur `[]`.
## Cahier des charges
Pour manipuler des matrices, vous devrez implémenter les fonctions suivantes
* création d'une nouvelle matrice de `row` lignes et `col` colonnes
1. Fonctions pour la création de nouvelles matrices et leur destruction
* création d'une nouvelle matrice de `m` lignes et `n` colonnes
```language-c
matrix* matrix_alloc(int m, int n);
```
* libération de mémoire la matrice en argument et
```language-c
m_double* matrix_alloc(unsigned int row, unsigned int col);
void matrix_free(matrix* mat);
```
* initilialisation d'une instance de matrice de taille `m` et `n` et allocation la mémoire associée
* calcul de la transposée de la matrice en paramètre
```language-c
void matrix_init(int m, int n, matrix *mat);
```
* Allocation d'une matrice, et initialisation de ses valeurs à partir d'un tableau de taille `m` et `n`
```language-c
m_double* matrix_transpose(m_double* m);
matrix *matrix_from_array(int m, int n, double data[]);
```
* addition des 2 matrices en paramètre (retourne `NULL`{.language-c} si l'opération est impossible)
* affichange d'une matrice, très utile pour le débogage
```language-c
m_double* matrix_add(m_double* m1, m_double* m2);
void matrix_print(matrix mat);
```
2. Fonctions pour les manipulations de matrices **en place** (on modifie les matrices passées en argument dans les fonctions)
* multiplication des 2 matrices en paramètre (retourne `NULL`{.language-c} si l'opération est impossible)
* addition de deux matrices, la première matrice est modifiée, la fonction retourne `1` si tout s'est bien passé, `0` sinon
```language-c
m_double* matrix_mult(m_double* m1, m_double* m2);
int matrix_add_in_place(matrix *mat1, matrix mat2);
```
* soustraction de deux matrices, la première matrice est modifiée, la fonction retourne `1` si tout s'est bien passé, `0` sinon
* libération de la matrice en paramètre
```language-c
int matrix_sub_in_place(matrix *mat1, matrix mat2);
```
* multiplication de deux matrices, la première matrice est modifiée, la fonction retourne `1` si tout s'est bien passé, `0` sinon
```language-c
void matrix_free(m_double* m);
int matrix_mult_in_place(matrix *mat1, matrix mat2);
```
* addition d'une matrice avec un scalaire, la matrice est modifiée, la fonction retourne `1` si tout s'est bien passé, `0` sinon
Le type matrice sera défini en `C` de la manière suivante
```language-c
int matrix_add_scalar_in_place(matrix *mat1, double scalar);
```
* multiplication d'une matrice avec un scalaire, la matrice est modifiée, la fonction retourne `1` si tout s'est bien passé, `0` sinon
```language-c
typedef struct m_double {
unsigned int row, col;
double** content;
} m_double;
int matrix_mult_scalar_in_place(matrix *mat1, double scalar);
```
* calcul de la transposée d'une matrice, la matrice est modifiée, la fonction retourne `1` si tout s'est bien passé, `0` sinon
Voici une illustration d'une matrice avec `row=5` et `col=4`.
Il faut d'abord allouer la zone mémoire des éléments et le tableau de pointeurs content,
puis faire pointer chaque pointeur de content au bon endroit dans la zone mémoire des éléments
(c'est-à-dire sur chaque élément de début de ligne, voir @fig:matrix).
```language-c
int matrix_transpose(matrix* mat);
```
3. Fonctions pour les manipulations de matrices, nécessitant une nouvelle allocation (il faut réutiliser les fonctions définies en 1 et 2)
![Les éléments de `content` pointent sur l'élément de début des lignes de la matrice.](figs/matrix.svg){#fig:matrix width=100%}
* addition de deux matrices, et stockage du résultat dans une troisième matrice, retourne `1` si tout s'est bien passé, `0` sinon
Écrire un programme de test `matrix_compute.c` utilisant vos fichiers de manipulation de matrices.
Les matrices avec lesquelles on effectuera les opérations doivent être stockées dans des fichiers
structurés en un format spécifique (voir plus bas). Le programme lit donc les matrices depuis des
fichiers et écrit le résultat de l'opération à l'écran dans le même format.
```language-c
int matrix_add_in_place(matrix mat1, matrix mat2, matrix *res);
```
* soustraction de deux matrices, et stockage du résultat dans une troisième matrice, retourne `1` si tout s'est bien passé, `0` sinon
## Format d’un fichier matrices
```language-c
int matrix_sub_in_place(matrix mat1, matrix mat2, matrix *res);
```
* multiplication de deux matrices, et stockage du résultat dans une troisième matrice, retourne `1` si tout s'est bien passé, `0` sinon
* La première ligne du fichier indique la dimension de la matrice. Le format est
```language-c
int matrix_mult_in_place(matrix mat1, matrix mat2, matrix *res);
* addition d'un scalaire avec une matrice, et stockage du résultat dans une troisième matrice, retourne `1` si tout s'est bien passé, `0` sinon
```language-c
<nombre de ligne> <un espace> <nombre de colonne>
int matrix_sub_in_place(matrix mat1, matrix mat2, matrix *res);
* mutliplication d'un scalaire avec une matrice, la matrice est modifiée, la fonction retourne `1` si tout s'est bien passé, `0` sinon
```language-c
int matrix_mult_scalar_in_place(matrix *mat1, double scalar);
```
* calcul de la transposée d'une matrice, la matrice est modifiée, la fonction retourne `1` si tout s'est bien passé, `0` sinon
```language-c
int matrix_transpose(matrix* mat);
```
* Les lignes suivantes définissent les lignes de la matrice. Le format est
Le type matrice sera défini en `C` de la manière suivante
```language-c
<valeur1> <un espace> <valeur2> <un espace> … <valeurN>
typedef struct matrix {
int m, n;
double** content;
} matrix;
```
* Aucune valeur ne doit contenir de zéros terminaux (sauf la valeur `0`); par exemple la valeur `1.0` doit être écrite 1, la valeur `7.450` doit être écrite `7.45`, la valeur `0.000` doit être écrite `0`, etc. (cf. plus bas pour voir comment réaliser ceci en `C`).
Voici une illustration d'une matrice avec `row=5` et `col=4`.
Il faut d'abord allouer la zone mémoire des éléments et le tableau de pointeurs content,
puis faire pointer chaque pointeur de content au bon endroit dans la zone mémoire des éléments
(c'est-à-dire sur chaque élément de début de ligne, voir @fig:matrix).
A titre d’exemple, soit la matrice A ci-dessous
<!-- ![Les éléments de `content` pointent sur l'élément de début des lignes de la matrice.](figs/matrix.svg){#fig:matrix width=100%} -->
Écrire un programme de test `matrix_compute.c` utilisant vos fichiers de manipulation de matrices.
Les matrices avec lesquelles on effectuera les opérations doivent être stockées dans des fichiers
structurés en un format spécifique (voir plus bas). Le programme lit donc les matrices depuis des
fichiers et écrit le résultat de l'opération à l'écran dans le même format.
## Rapide introductions aux matrice
Une matrice est un **tableau de nombres** et a un nombre de lignes noté, $m$, et un nombre de colonne noté $n$. Pour simplifier, on dit que c'est une matrice $m\times n$. La matrice $\underline{\underline{A}}$ ci-dessous, a 3 lignes et
4 colonnes
\begin{equation}
\underline{\underline{A}} =
\begin{pmatrix}
2.2 & 1.3 & -1.2 & -2.2 \\
3.0 & 1.2 & 1.3 & 3.3 \\
1.0 & 4.0 & -1.3 & -1.0 \\
\end{pmatrix}.
\end{pmatrix},
\end{equation}
on dit que c'est une matrice $3\times 4$.
sera représentée par le contenu du fichier suivant
```
3 4
2.2 1.3 -1.2 -2.2
3 1.2 1.3 3.3
1 4 -1.3 -1
```
La fonction `printf` du langage `C` permet d’afficher des nombres de type double dans le format correct avec le formatteur `%g`.
Par exemple, pour afficher le double `x=9.230` dans le bon format (sans zéros terminaux), on écrira
Chaque élément d'une matrice peut être accédé par une paire d'indices, $i$, $j$ ($i$ étant le numéro de la ligne, $j$ le numéro de la colonne), et est noté par $A_{ij}$. Dans le cas
ci-dessus, l'élément $A_{14}=-2.2$.
```language-c
printf("%g", x);
```
Voici maintenant un exemple plus complet d’addition de matrices
Si on considère deux matrices, $\underline{\underline{A}}$, $\underline{\underline{B}}$ de tailes identiques, $m\times n$.
Ces matrices peuvent s'additionner et se soustraire élément par élément. Dans le cas de l'addition (la soustraction se fait de façon similaire), on a
\begin{equation}
\underline{\underline{C}}=\underline{\underline{A}}+\underline{\underline{B}},
\end{equation}
\begin{equation}
C_{ij}=A_{ij}+B_{ij}.
\end{equation}
Pour les matrices $\underline{\underline{A}}$, $\underline{\underline{B}}$
\begin{equation}
\underline{\underline{A}} =
\begin{pmatrix}
......@@ -144,7 +189,7 @@ Voici maintenant un exemple plus complet d’addition de matrices
1.0 & 3.2 & 1.3 & -1.0 \\
\end{pmatrix}.
\end{equation}
donne comme résultat
on aura comme résultat
\begin{equation}
\underline{\underline{A}}+\underline{\underline{B}} =
\begin{pmatrix}
......@@ -154,35 +199,48 @@ donne comme résultat
\end{pmatrix}.
\end{equation}
Les éléments des matrices `A` et `B` doivent être stockés selon le format décrit auparavant dans des fichiers nommés par exemple `matA.dat` et `matB.dat`.
Voici le contenu du fichier `matA.dat` correspondant à la matrice `A` ci-dessus
```
3 4
2.2 1.3 -1.2 -2.2
3 1.2 1.3 3.3
1 4 -1.3 -1
```
Le calcul doit pouvoir être lancé avec la commande
```
./matrix_compute add matA.dat matB.dat
```
De façon similaire, on peut définir multiplication (ou l'addition) par un scalaire, $\alpha$
\begin{equation}
\underline{\underline{B}}=\alpha\cdot\underline{\underline{A}},
\end{equation}
\begin{equation}
B_{ij} = \alpha\cdot A_{ij}.
\end{equation}
On peut procéder de façon similaire pour l'addition, où on multiplie tous les éléments de la matrice par $\alpha$.
et le résultat s'affiche à l'écran suivant le même format que décrit auparavant
Pour la multiplication de deux matrices, cela est un peu plus compliqué. Supposons que la matrice $\underline{\underline{A}}$ soit de taille $m\times l$, et la matrice $\underline{\underline{B}}$ de taille $l\times n$, la multiplication
\begin{equation}
\underline{\underline{C}}=\underline{\underline{A}}\cdot\underline{\underline{B}},
\end{equation}
se définit comme
\begin{equation}
C_{ij} = \sum_{k=1}^lA_{ik}B_{kj},
\end{equation}
et la matrice $\underline{\underline{C}}$ est de taille $m\times n$.
```
3 4
3.4 3.6 2 -3.4
5 1.4 3.6 6.3
2 7.2 0 -2
```
Finalement, on définit également la matrice *transposée* de la matrice $\underline{\underline{A}}$, notée $\underline{\underline{A}}^\mathrm{T}$, comme la matrice obtenue en
inversant tous les indices de $\underline{\underline{A}}$.
On a que $A^\mathrm{T}_{ij}=A_{ji}$. Si $\underline{\underline{A}}$ est une matrice $m\times n$, alors $\underline{\underline{A}}^\mathrm{T}$ est une matrice de taille $n\times m$.
Si le calcul est impossible, rien n'est affiché.
De même, on effectuera respectivement multiplication et transposition avec les commandes
Pour la matrice
\begin{equation}
\underline{\underline{A}} =
\begin{pmatrix}
2.2 & 1.3 & -1.2 & -2.2 \\
3.0 & 1.2 & 1.3 & 3.3 \\
1.0 & 4.0 & -1.3 & -1.0 \\
\end{pmatrix},
\end{equation}
la matrice transposée $\underline{\underline{A}}^\mathrm{T}$ sera
\begin{equation}
\underline{\underline{A}}^\mathrm{T} =
\begin{pmatrix}
2.2 & 3.0 & 1.0 \\
1.3 & 1.2 & 4.0 \\
-1.2 & 1.3 & -1.3 \\
-2.2 & 3.3 & -1.0
\end{pmatrix}.
\end{equation}
```
./matrix_compute mult matA.dat matB.dat
./matrix_compute transpose matA.dat
```
\ No newline at end of file
Finalement, pour que deux matrices soient égales, il faut que tous leurs éléments soient égaux et que leurs tailles soient les mêmes évidemment.
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment