|
Corrigé de la séance d'exercices 11, Programmation I |
|
Sciences et Technologies du Vivant, Semestre 1 |
#include <iostream>
#include <math.h>
using namespace std;
// ******* Structures *******
struct Matrice {
float *tab;
int nl, nc;
};
struct Vecteur {
float *tab;
int n;
};
// ******* Fonctions pour Matrice *******
float get(Matrice *mat, int ligne, int col) {
if (ligne >= 0 && ligne < mat->nl && col >= 0 && col < mat->nc)
return mat->tab[ligne * mat->nc + col];
else {
cout << "Erreur [get]: indice en dehors des bornes!" << endl;
cout << "Matrice: " << mat->nc << " colonnes, " << mat->nl << " lignes." << endl;
cout << "Requete: ligne " << ligne << ", colonne " << col << endl;
}
return 0;
}
void set(Matrice *mat, int ligne, int col, float val) {
if (ligne >= 0 && ligne < mat->nl && col >= 0 && col < mat->nc)
mat->tab[ligne * mat->nc + col] = val;
else {
cout << "Erreur [set]: indice en dehors des bornes!" << endl;
cout << "Matrice: " << mat->nc << " colonnes, " << mat->nl << " lignes." << endl;
cout << "Requete: ligne " << ligne << ", colonne " << col << endl;
}
}
Matrice *alloue_matrice(int nl, int nc) {
Matrice *res = new Matrice;
res->nl = nl;
res->nc = nc;
res->tab = new float[nc * nl];
return res;
}
void libere_matrice(Matrice *mat) {
delete[] mat->tab;
delete mat;
}
void affiche(Matrice *mat) {
for (int i=0; i<mat->nl; i++) {
for (int j=0; j<mat->nc; j++)
cout << get(mat, i, j) << " ";
cout << endl;
}
}
bool set_id(Matrice *mat) {
if (mat->nc == mat->nl) {
for (int i=0; i<mat->nl; i++)
for (int j=0; j<mat->nc; j++)
if (i == j)
set(mat, i, j, 1);
else
set(mat, i, j, 0);
return true;
}
else {
cout << "Erreur [set_id]: matrice non carree." << endl;
return false;
}
}
void set_0(Matrice *mat) {
for (int i=0; i<mat->nl; i++)
for (int j=0; j<mat->nc; j++)
set(mat, i, j, 0);
}
// pour matrices a 6 coefficients
void init(Matrice *mat, float c1, float c2, float c3, float c4, float c5,
float c6) {
if ((mat->nc == 3 && mat->nl == 2) || (mat->nc == 2 && mat->nl ==3)) {
mat->tab[0] = c1;
mat->tab[1] = c2;
mat->tab[2] = c3;
mat->tab[3] = c4;
mat->tab[4] = c5;
mat->tab[5] = c6;
}
else
cout << "Erreur [init]: matrice de taille incorrecte." << endl;
}
// pour matrices a 9 coefficients
void init(Matrice *mat, float c1, float c2, float c3, float c4, float c5,
float c6, float c7, float c8, float c9) {
if (mat->nc == 3 && mat->nl == 3) {
mat->tab[0] = c1;
mat->tab[1] = c2;
mat->tab[2] = c3;
mat->tab[3] = c4;
mat->tab[4] = c5;
mat->tab[5] = c6;
mat->tab[6] = c7;
mat->tab[7] = c8;
mat->tab[8] = c9;
}
else
cout << "Erreur [init]: matrice de taille incorrecte." << endl;
}
// pour matrices a 12 coefficients
void init(Matrice *mat, float c1, float c2, float c3, float c4, float c5,
float c6, float c7, float c8, float c9, float c10, float c11, float c12) {
if ((mat->nc == 2 && mat->nl == 6) || (mat->nc == 3 && mat->nl == 4) ||
(mat->nc == 4 && mat->nl == 3) || (mat->nc == 6 && mat->nl == 2)) {
mat->tab[0] = c1;
mat->tab[1] = c2;
mat->tab[2] = c3;
mat->tab[3] = c4;
mat->tab[4] = c5;
mat->tab[5] = c6;
mat->tab[6] = c7;
mat->tab[7] = c8;
mat->tab[8] = c9;
mat->tab[9] = c10;
mat->tab[10] = c11;
mat->tab[11] = c12;
}
else
cout << "Erreur [init]: matrice de taille incorrecte." << endl;
}
void copie(Matrice *mat, Matrice *res) {
if (mat->nl == res->nl && mat->nc == res->nc)
for (int i=0; i<mat->nl; i++)
for (int j=0; j<mat->nc; j++)
set(res, i, j, get(mat, i, j));
else
cout << "Erreur [copie]: la taille des matrices ne correspond pas." << endl;
}
void add_mat(Matrice *m1, Matrice *m2, Matrice *res) {
if (m1->nc == m2->nc && m1->nl == m2->nl && res->nc == m1->nc
&& res->nl == m1->nl)
for (int i=0; i<m1->nl; i++)
for (int j=0; j<m1->nc; j++)
set(res, i, j, get(m1, i, j) + get(m2, i, j));
else
cout << "Erreur [add_mat]: les matrices n'ont pas la meme taille." << endl;
}
float trace(Matrice *mat) {
float tr = 0;
if (mat->nl == mat->nc)
for (int i=0; i<mat->nl; i++)
tr += get(mat, i, i);
else
cout << "Erreur [trace]: matrice non carree." << endl;
return tr;
}
void mult(Matrice *m1, Matrice *m2, Matrice *res) {
if (m1->nc == m2->nl && res->nl == m1->nl && res->nc == m2->nc)
for (int i=0; i<m1->nl; i++)
for (int j=0; j<m2->nc; j++) {
res->tab[i * res->nc + j] = 0;
for (int k=0; k<m1->nc; k++)
res->tab[i * res->nc + j] += get(m1, i, k) * get(m2, k, j);
}
else
cout << "Erreur [mult_mat]: la taille des matrices ne correspondent pas." << endl;
}
void transpose_mat(Matrice *mat, Matrice *res) {
if (mat->nc == res->nl && mat->nl == res->nc)
for (int i=0; i<res->nl; i++)
for (int j=0; j<res->nc; j++)
set(res, i, j, get(mat, j, i));
else
cout << "Erreur [transpose_mat]: la taille des matrices ne correspondent pas." << endl;
}
// ******* Fonctions pour Vecteur *******
float get(Vecteur *vec, int n) {
if (n >= 0 && n < vec->n)
return vec->tab[n];
else {
cout << "Erreur [get]: indice en dehors des bornes!" << endl;
cout << "Vecteur: " << vec->n << " elements" << endl;
cout << "Requete: element " << n << endl;
}
return 0;
}
void set(Vecteur *vec, int n, float val) {
if (n >= 0 && n < vec->n)
vec->tab[n] = val;
else {
cout << "Erreur [set]: indice en dehors des bornes!" << endl;
cout << "Vecteur: " << vec->n << " elements" << endl;
cout << "Requete: element " << n << endl;
}
}
Vecteur *alloue_vecteur(int n) {
Vecteur *res = new Vecteur;
res->n = n;
res->tab = new float[n];
return res;
}
void libere_vecteur(Vecteur *vec) {
delete[] vec->tab;
delete vec;
}
void affiche(Vecteur *vec) {
for (int i=0; i<vec->n; i++)
cout << get(vec, i) << endl;
}
void init(Vecteur *vec, float c1, float c2, float c3, float c4) {
if (vec->n == 4) {
vec->tab[0] = c1;
vec->tab[1] = c2;
vec->tab[2] = c3;
vec->tab[3] = c4;
}
else
cout << "Erreur [init]: vecteur de taille incorrecte." << endl;
}
float norm_vect(Vecteur *vec) {
float somme = 0;
for (int i=0; i<vec->n; i++)
somme += get(vec, i) * get(vec, i);
return sqrt(somme);
}
float produit_scalaire(Vecteur *v1, Vecteur *v2) {
float produit = 0;
if (v1->n != v2->n)
cout << "Erreur [produit_scalaire]: les vecteurs n'ont pas la meme taille." << endl;
else {
for (int i=0; i<v1->n; i++)
produit += v1->tab[i] * v2->tab[i];
}
return produit;
}
void mult(Matrice *mat, Vecteur *vec, Vecteur *res) {
if (vec->n == mat->nc && res->n == mat->nl)
for (int i=0; i<mat->nl; i++) {
res->tab[i] = 0;
for (int j=0; j<mat->nc; j++)
res->tab[i] += get(mat, i, j) * get(vec, j);
}
else
cout << "Erreur [mult_mat_vec]: la taille des vecteurs et de la matrice ne correspondent pas." << endl;
}
// ******* Fonctions de l'exercice 3 *******
void decale_a_gauche(Matrice *mat, Matrice *res) {
if (mat->nl == res->nl && mat->nc == res->nc) {
for (int i=0; i<mat->nl; i++)
for (int j=0; j<mat->nc; j++)
set(res, i, (j+mat->nc-1) % mat->nc, get(mat, i, j));
}
else
cout << "Erreur [decale_a_gauche]: la taille des matrices ne correspond pas." << endl;
}
void decale_a_droite(Matrice *mat, Matrice *res) {
if (mat->nl == res->nl && mat->nc == res->nc) {
for (int i=0; i<mat->nl; i++)
for (int j=0; j<mat->nc; j++)
set(res, i, (j+1) % mat->nc, get(mat, i, j));
}
else
cout << "Erreur [decale_a_droite]: la taille des matrices ne correspond pas." << endl;
}
void tourne(Matrice *mat, Matrice *res) {
if (mat->nl == res->nl && mat->nc == res->nc) {
// ligne superieure
for (int i=1; i<mat->nc; i++)
set(res, 0, i, get(mat, 0, i-1));
// ligne inferieure
for (int i=0; i<mat->nc-1; i++)
set(res, mat->nl-1, i, get(mat, mat->nl-1, i+1));
// ligne de gauche
for (int i=0; i<mat->nl-1; i++)
set(res, i, 0, get(mat, i+1, 0));
// ligne de droite
for (int i=1; i<mat->nl; i++)
set(res, i, mat->nc-1, get(mat, i-1, mat->nc-1));
// autres lignes
for (int i=1; i<mat->nl-1; i++)
for (int j=1; j<mat->nc-1; j++)
set(res, i, j, get(mat, i, j));
}
else
cout << "Erreur [tourne]: la taille des matrices ne correspond pas." << endl;
}
void puissance_mat(Matrice *mat, int exposant, Matrice *res) {
Matrice *tmp = alloue_matrice(mat->nl, mat->nl);
set_id(res);
if (mat->nc == mat->nl && res->nc == mat->nc && res->nl == mat->nl) {
for (int i=0; i<exposant; i++) {
mult(mat, res, tmp);
copie(tmp, res);
}
}
else
cout << "Erreur [puissance_mat]: la taille des matrices ne correspond pas." << endl;
libere_matrice(tmp);
}
int main(int argc, char **argv) {
Matrice *M1 = alloue_matrice(2, 3);
Matrice *M2 = alloue_matrice(2, 3);
init(M1, 1, 3, -4, -5, 2, 0);
init(M2, 6, 2, -1, 1, -2, 5);
cout << "M1:" << endl;
affiche(M1);
cout << endl << "M2:" << endl;
affiche(M2);
Matrice *M3 = alloue_matrice(2, 3);
add_mat(M1, M2, M3);
cout << endl << "M3 = M1 + M2:" << endl;
affiche(M3);
cout << endl;
libere_matrice(M1);
libere_matrice(M2);
libere_matrice(M3);
Vecteur *V1 = alloue_vecteur(4);
Vecteur *V2 = alloue_vecteur(4);
init(V1, 2, 5, 3, 4);
init(V2, 3, 2, -3, 1);
cout << "V1:" << endl;
affiche(V1);
cout << endl << "V2:" << endl;
affiche(V2);
cout << endl << "Norme de V1: " << norm_vect(V1) << endl;
cout << "Norme de V2: " << norm_vect(V2) << endl << endl;
cout << "Produit scalaire <V1, V2> = " << produit_scalaire(V1, V2) << endl;
Matrice *P1 = alloue_matrice(3, 3);
Matrice *P2 = alloue_matrice(3, 4);
init(P1, 2, 1, -3, 5, 1, 5, 3, 2, 4);
init(P2, 3, -1, 3, 1, 2, 3, 5, 2, -3, 2, -4, 3);
cout << endl << "P1:" << endl;
affiche(P1);
cout << endl << "P2:" << endl;
affiche(P2);
cout << endl << "Trace de P1: " << trace(P1) << endl;
Vecteur *V3 = alloue_vecteur(3);
mult(P2, V1, V3);
cout << endl << "P2 * V1:" << endl;
affiche(V3);
cout << endl;
libere_vecteur(V1);
libere_vecteur(V2);
libere_vecteur(V3);
Matrice *P3 = alloue_matrice(3, 4);
mult(P1, P2, P3);
cout << endl << "P1 * P2:" << endl;
affiche(P3);
cout << endl;
Matrice *transpP1 = alloue_matrice(3, 3);
Matrice *transpP2 = alloue_matrice(4, 3);
transpose_mat(P1, transpP1);
transpose_mat(P2, transpP2);
cout << "P1 transposee:" << endl;
affiche(transpP1);
cout << endl << "P2 transposee:" << endl;
affiche(transpP2);
cout << endl;
libere_matrice(transpP1);
libere_matrice(transpP2);
cout << "Exercice 2:" << endl;
decale_a_gauche(P2, P3);
cout << endl << "P2 decalee a gauche:" << endl;
affiche(P3);
tourne(P2, P3);
cout << endl << "P2 tournee:" << endl;
affiche(P3);
Matrice *P4 = alloue_matrice(3, 3);
puissance_mat(P1, 4, P4);
cout << endl << "P1 a la puissance 4:" << endl;
affiche(P4);
libere_matrice(P1);
libere_matrice(P2);
libere_matrice(P3);
libere_matrice(P4);
return 0;
}
Retour