From d00d0745d0855284ca7902646057142a4ae4aabc Mon Sep 17 00:00:00 2001 From: Geoffrey Frogeye Date: Wed, 18 May 2016 11:21:03 +0200 Subject: [PATCH] DS2 --- DS2/E1.1.in | 17 +++++ DS2/E1.2.in | 26 +++++++ DS2/E1.c | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++ DS2/E2.c | 93 +++++++++++++++++++++++ DS2/E2.in | 3 + DS2/Makefile | 9 +++ 6 files changed, 354 insertions(+) create mode 100644 DS2/E1.1.in create mode 100644 DS2/E1.2.in create mode 100644 DS2/E1.c create mode 100644 DS2/E2.c create mode 100644 DS2/E2.in create mode 100644 DS2/Makefile diff --git a/DS2/E1.1.in b/DS2/E1.1.in new file mode 100644 index 0000000..e1b63c2 --- /dev/null +++ b/DS2/E1.1.in @@ -0,0 +1,17 @@ +3 +3 +1 +1 +1 +-3 +2 +-1 +2 +4 +-2 +1 +5 +1 +1 +1 +0.0000001 diff --git a/DS2/E1.2.in b/DS2/E1.2.in new file mode 100644 index 0000000..b870d8c --- /dev/null +++ b/DS2/E1.2.in @@ -0,0 +1,26 @@ +4 +2 +-1 +0 +0 +-1 +2 +-1 +0 +0 +-1 +2 +-1 +0 +0 +-1 +2 +-3 +1 +4 +-4 +1 +1 +1 +1 +0.0000001 diff --git a/DS2/E1.c b/DS2/E1.c new file mode 100644 index 0000000..bd36cad --- /dev/null +++ b/DS2/E1.c @@ -0,0 +1,206 @@ +/* Résolution du système par la méthode de Gauss-Seidel */ + +#include +#include +#include + +// 1) + +int diagdom(int n, double A[n][n]) { + int i, j; + double S; // La somme de l'équation (2) + for (i = 0; i <= n-1; i++) { + // Pour tout i + S = 0; + for (j = 0; j <= n-1; j++) { + if (j != i) { + S += fabs(A[i][j]); + } + } + if (fabs(A[i][i]) < S) { + return 0; + } + } + return 1; +} + +// 2) a) + +double norm(int n, double *x) { + double carre = 0; // Carré de la norme + double *xi; // Pointeur qui se déplacera sur les composantes du vecteur + for (xi = x; xi < x + n; xi++) { + carre += pow(*xi, 2); + } + return sqrt(carre); +} + +int main(int argc, char *argv[]) { + // 2) b) + + int n; + printf("Saisissez l'ordre n du système : "); + scanf("%d", &n); + + // Saisie de la matrice + double A[n][n]; + int i, j; + for (i = 0; i <= n-1; i++) { + for (j = 0; j <= n-1; j++) { + printf("Saisissez l'élément de A aux coordonnées (%3d;%3d) : ", i, j); + scanf("%lf", &A[i][j]); + } + } + // Saisie du second membre y + double Y[n]; + for (i = 0; i <= n-1; i++) { + printf("Saisissez la composante numéro %3d du vecteur second membre y : ", i); + scanf("%lf", &Y[i]); + } + // Saisie du vecteur initial x + double X[n]; + for (i = 0; i <= n-1; i++) { + printf("Saisissez la composante numéro %3d du vecteur initial x⁽⁰⁾ : ", i); + scanf("%lf", &X[i]); + } + // Saisie de la précision epsilon (pas demmandé explicitement mais marqué + // comme "donné", donc dans le doute on le demande) + double E; + printf("Saisissez la précision Epsilon : "); + scanf("%lf", &E); + + printf("\n"); + // Affichage de la matrice (pas demmandé mais utile) + for (i = 0; i <= n-1; i++) { + for (j = 0; j <= n-1; j++) { + printf("%11lf", A[i][j]); + } + printf("\n"); + } + + // Vérification si la matrice est à diagonale dominante + if (!diagdom(n, A)) { + printf("La matrice n'est pas à diagonale dominante.\n"); + return 1; + } + + // Application de la méthode itérative + double Xp[n]; // Vecteur itéré précédent + double R[n]; // Vecteur résidu + int it = 0; // Nombre d'itérations + double S1; // Première somme de (1) + double S2; // Deuxième somme de (1) + do { + // L'utilisation d'une boucle do...while permet d'éviter + // d'initialiser Xp et R avant la boucle. Du coup la première + // itération est forcée mais le cas où 0 itération serait + // necessaire est plutôt rare + // Une boucle while classique aurait aussi tout à fait possible + + it++; // Nouvelle itération + // On copie X → Xp + for (i = 0; i <= n-1; i++) { + Xp[i] = X[i]; + } + // On applique (1) + for (i = 0; i <= n-1; i++) { + // Première somme de (1) + S1 = 0; + for (j = 0; j <= i-1; j++) { + S1 += A[i][j] * X[j]; + } + // Deuxième somme de (1) + S2 = 0; + for (j = i+1; j <= n-1; j++) { + S2 += A[i][j] * Xp[j]; + } + + X[i] = (1/A[i][i])*(Y[i]-S1-S2); + } + + // Calcul de r + for (i = 0; i <= n-1; i++) { + R[i] = X[i] - Xp[i]; + } + } while (norm(n, R) >= E); + + // Affichage du résultat + printf("X =\n"); + for (i = 0; i <= n-1; i++) { + printf("%lf\n", X[i]); + } + printf("%d itérations ont été nécessaire pour arriver à la précision %11lf.\n", it, E); + + return 0; +} + +// 2) c) + +// Saisissez l'ordre n du système : 3 +// Saisissez l'élément de A aux coordonnées ( 0; 0) : 3 +// Saisissez l'élément de A aux coordonnées ( 0; 1) : 1 +// Saisissez l'élément de A aux coordonnées ( 0; 2) : 1 +// Saisissez l'élément de A aux coordonnées ( 1; 0) : 1 +// Saisissez l'élément de A aux coordonnées ( 1; 1) : -3 +// Saisissez l'élément de A aux coordonnées ( 1; 2) : 2 +// Saisissez l'élément de A aux coordonnées ( 2; 0) : -1 +// Saisissez l'élément de A aux coordonnées ( 2; 1) : 2 +// Saisissez l'élément de A aux coordonnées ( 2; 2) : 4 +// Saisissez la composante numéro 0 du vecteur second membre y : -2 +// Saisissez la composante numéro 1 du vecteur second membre y : 1 +// Saisissez la composante numéro 2 du vecteur second membre y : 5 +// Saisissez la composante numéro 0 du vecteur initial x⁽⁰⁾ : 1 +// Saisissez la composante numéro 1 du vecteur initial x⁽⁰⁾ : 1 +// Saisissez la composante numéro 2 du vecteur initial x⁽⁰⁾ : 1 +// Saisissez la précision Epsilon : 0.0000001 +// +// 3.000000 1.000000 1.000000 +// 1.000000 -3.000000 2.000000 +// -1.000000 2.000000 4.000000 +// X = +// -1.000000 +// 0.000000 +// 1.000000 +// 14 itérations ont été nécessaire pour arriver à la précision 0.000000. + +// Saisissez l'ordre n du système : 4 +// Saisissez l'élément de A aux coordonnées ( 0; 0) : 2 +// Saisissez l'élément de A aux coordonnées ( 0; 1) : -1 +// Saisissez l'élément de A aux coordonnées ( 0; 2) : 0 +// Saisissez l'élément de A aux coordonnées ( 0; 3) : 0 +// Saisissez l'élément de A aux coordonnées ( 1; 0) : -1 +// Saisissez l'élément de A aux coordonnées ( 1; 1) : 2 +// Saisissez l'élément de A aux coordonnées ( 1; 2) : -1 +// Saisissez l'élément de A aux coordonnées ( 1; 3) : 0 +// Saisissez l'élément de A aux coordonnées ( 2; 0) : 0 +// Saisissez l'élément de A aux coordonnées ( 2; 1) : -1 +// Saisissez l'élément de A aux coordonnées ( 2; 2) : 2 +// Saisissez l'élément de A aux coordonnées ( 2; 3) : -1 +// Saisissez l'élément de A aux coordonnées ( 3; 0) : 0 +// Saisissez l'élément de A aux coordonnées ( 3; 1) : 0 +// Saisissez l'élément de A aux coordonnées ( 3; 2) : -1 +// Saisissez l'élément de A aux coordonnées ( 3; 3) : 2 +// Saisissez la composante numéro 0 du vecteur second membre y : -3 +// Saisissez la composante numéro 1 du vecteur second membre y : 1 +// Saisissez la composante numéro 2 du vecteur second membre y : 4 +// Saisissez la composante numéro 3 du vecteur second membre y : -4 +// Saisissez la composante numéro 0 du vecteur initial x⁽⁰⁾ : 1 +// Saisissez la composante numéro 1 du vecteur initial x⁽⁰⁾ : 1 +// Saisissez la composante numéro 2 du vecteur initial x⁽⁰⁾ : 1 +// Saisissez la composante numéro 3 du vecteur initial x⁽⁰⁾ : 1 +// Saisissez la précision Epsilon : 0.0000001 +// +// 2.000000 -1.000000 0.000000 0.000000 +// -1.000000 2.000000 -1.000000 0.000000 +// 0.000000 -1.000000 2.000000 -1.000000 +// 0.000000 0.000000 -1.000000 2.000000 +// X = +// -1.000000 +// 1.000000 +// 2.000000 +// -1.000000 +// 38 itérations ont été nécessaire pour arriver à la précision 0.000000. + +// (notons que Epsilon n'est pas affiché totalement malgré le fait qu'il soit bien stocké en mémoire !) +// De plus, saisir un Epsilon trop petit pourrait être considéré comme zéro par le programme et ne pas +// fonctionner correctement (division par 0) diff --git a/DS2/E2.c b/DS2/E2.c new file mode 100644 index 0000000..ac6476e --- /dev/null +++ b/DS2/E2.c @@ -0,0 +1,93 @@ +/* Dérivées */ + +#include +#include +#include + +// 1) + +double f(double x) { + // L'utilisation d'un pointeur ici est superflue car + // il est plus rapide et moins consommateur de + // faire des opérations de la sorte sur une copie de x + // plutôt que sur des références vers x + return ( (2*x+1)*(x-1) ) / sqrt( pow(x, 2) + 1 ); +} + +// 2) + +double deriv(double (*Pf)(double x), double x, double h) { + return ( (*Pf)(x + h) - (*Pf)(x - h) ) / (2*h); +} + +// 3) + +double deriv2(double (*Pf)(double x), double x, double h) { + double Pfd(double a) { // On définit f'(a) qui est défini selon Pf et h + return deriv(Pf, a, h); + } + // return ( deriv(Pf, x+h, h) - deriv(Pf, x-h, h) ) / (2 * h); // Sans pointeur + return deriv(Pfd, x, h); // Avec fonction +} + +int main(int argc, char *argv[]) { + // Saisie de x + double x; + printf("Saisissez x : "); + scanf("%lf", &x); + + // Choix du degré de dérivation + int choix; + printf("Saisissez le degré de dérivation désiré pour f : "); + scanf("%d", &choix); + + // Saisie du pas de dérivation + double h; // On ne demmande h uniquement s'il y a dérivée, c'est inutile sinon + if (choix > 0) { + printf("Saisissez le pas de dérivation h : "); + scanf("%lf", &h); + } + + // Éxecution selon le choix + switch (choix) { + case 0: + printf("f(%11lf) = %11f\n", x, f(x)); + break; + + case 1: + printf("f'(%11lf) = %11f (précision %lf)\n", x, deriv(f, x, h), h); + break; + + case 2: + printf("f\"(%11lf) = %11f (précision %lf)\n", x, deriv2(f, x, h), h); + break; + + default: + printf("Merci de bien saisir un degré de dérivation compris entre 0 et 2.\n"); + return 1; + } + + return 0; +} + +// 4) Test + +// Saisissez x : 2 +// Saisissez le degré de dérivation désiré pour f : 0 +// f( 2.000000) = 2.236068 +// (Valeur exacte = 2.23606797749979) + +// Saisissez x : 2 +// Saisissez le degré de dérivation désiré pour f : 1 +// Saisissez le pas de dérivation h : 0.001 +// f'( 2.000000) = 2.236068 (précision 0.001000) +// (Valeur exacte = 2.23606797749979) + +// Saisissez x : 2 +// Saisissez le degré de dérivation désiré pour f : 2 +// Saisissez le pas de dérivation h : 0.001 +// f"( 2.000000) = -0.089443 (précision 0.001000) +// (Valeur exacte = -0.089442719099992) + +// 5) : Déjà inclus. Les test produisent exactement la même sortie. + diff --git a/DS2/E2.in b/DS2/E2.in new file mode 100644 index 0000000..4e9d1fb --- /dev/null +++ b/DS2/E2.in @@ -0,0 +1,3 @@ +2 +1 +0.001 diff --git a/DS2/Makefile b/DS2/Makefile new file mode 100644 index 0000000..7cc75c7 --- /dev/null +++ b/DS2/Makefile @@ -0,0 +1,9 @@ +all: $(patsubst %.c,%.exe,$(shell ls *.c)) + +%.exe: %.c + gcc $< -o $@ -lm -Wall -g + +.PHONY: all clean + +clean: + rm *.exe