/* 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)