Domanda Risolto Algoritmo di Gauss senza riordinamento pivotale

alessina02

Utente Bronze
2 Gennaio 2022
35
11
0
25
Ultima modifica:
Devo risolvere un sistema lineare con il metodo di Gauss senza il riordinamento, ma l'output della matrice a scala per righe è sbagliato nella diagonale principale e non riesco a capire perchè.
Questo è il codice completo
C++:
/*Programma che stampa una matrice data
e la riduce a scala per righe con l'algoritmo
di Gauss senza riordinamento pivotale*/
#include <stdio.h>
#include <math.h>
#define N 5
void matrice (double [N][N]);
void sostituzione_indietro (double [N][N], int, double[], double[]);
int main ()

{double a[N][N];
matrice (a);
double b[N]={2,1,1,1,2};
printf ("c="); for (int i=0; i<N; i++) printf ("\t%.0lf\n", b[i]);
double m;
int k, i, j;
for (int k=0; k<N;k++)
    {for (int i=k+1; i<N; i++)
            {m=a[i][k]/a[k][k]; a[i][k]=0;
                for(j=k+1; j<N; j++) { a[i][j]=a[i][j]-m*a[k][j];}
                b[i]=b[i]-m*b[i];}
}

printf ("\nMatrice a scala="); for (int i=0; i<N; i++) {printf ("\n");
for (int j=0; j<N; j++) printf ("\t%.2lf", a[i][j]);}
return 0;}


void matrice (double a[N][N])
{int i,j;
for (i=0; i<N; i++) {for (j=0; j<N; j++) {int s=i-j;
    switch (s){
        case 0: a[i][j]=3;
        break;
        case 1:
        case -1: a[i][j]=-1;
        break;
        default: a[i][j]=0;}
}
}
printf ("B="); for (int k=0; k<N; k++) {for (int h=0; h<N; h++) {printf ("\t%.0lf\t", a[k][h]);} printf ("\n");}
return;}

void sostituzione_indietro (double L[N][N], int n, double b[], double x[])
{x[n]=b[n]/L[n][n];
for (int i=n-1; i>1; i--) {x[i]=b[i]; for (int j=i; j>0; j++) {x[i]=x[i]-L[i][j]*x[j];} x[i]=x[i]/L[i][i];}
for (int k=0; k<n; k++) {printf ("\nx%d=%.2lf\n", k+1, x[k]); }
 
Hai sbagliato l'algoritmo, ci sono un po' di off-by-one. Prova a vedere se il mio ti sembra giusto.

Forward:
C:
for (int k = 0; k < N - 1; k++) {    
  for (int i = k + 1; i < N; i++) {  
    double m = a[i][k] / a[k][k];    
    a[i][k] = 0;                     
    for (int j = k; j < N; j++)      
      a[i][j] = a[i][j] - m * a[k][j];
    b[i] = b[i] - m * b[k];          
  }                                  
}

Backward:
C:
double x[N] = {0, 0, 0, 0, 0};       
x[N - 1] = b[N - 1] / a[N - 1][N - 1];
for (int i = N - 2; i >= 0; i--) {   
  x[i] = b[i];                       
  for (int j = i + 1; j < N; j++)    
    x[i] = x[i] - a[i][j] * x[j];    
  x[i] = x[i] / a[i][i];             
}
 
Ultima modifica:
ho provato l'algoritmo forward e mi trasforma tutti i -1 sotto la diagonale in +1 e ho ancora il problema dei valori sbagliati sulla diagonale principale.
Mentre quello backward ristampa la matrice iniziale.
 
Mi aspetto: tutti zeri sotto la diagonale, tutti -1 subito sopra e la diagonale principale dovrebbe avere i numeri 3, -2.67,-3.37,-1.09,1.03.
Con il codice iniziale invece ottengo sulla diagonale principale 3, 2.67, 2.63,2.62,2.62
 
Mi aspetto: tutti zeri sotto la diagonale, tutti -1 subito sopra e la diagonale principale dovrebbe avere i numeri 3, -2.67,-3.37,-1.09,1.03.
Con il codice iniziale invece ottengo sulla diagonale principale 3, 2.67, 2.63,2.62,2.62
Uhm... no? Fammi sapere se ho sbagliato qualche passaggio
Codice:
Matrice di partenza
---------------------------------
 3.00  -1.00   0.00   0.00   0.00     
-1.00   3.00  -1.00   0.00   0.00    
 0.00  -1.00   3.00  -1.00   0.00    
 0.00   0.00  -1.00   3.00  -1.00    
 0.00   0.00   0.00  -1.00   3.00


2nd = 2nd - 1st * (-0.33)
---------------------------------
 3.00  -1.00   0.00   0.00   0.00     
 0.00   2.67  -1.00   0.00   0.00    
 0.00  -1.00   3.00  -1.00   0.00    
 0.00   0.00  -1.00   3.00  -1.00    
 0.00   0.00   0.00  -1.00   3.00


3nd = 3nd - 2st * (-0.37)
---------------------------------
 3.00  -1.00   0.00   0.00   0.00     
 0.00   2.67  -1.00   0.00   0.00    
 0.00   0.00   2.62  -1.00   0.00    
 0.00   0.00  -1.00   3.00  -1.00    
 0.00   0.00   0.00  -1.00   3.00


4nd = 4nd - 3st * (-0.38)
---------------------------------
 3.00  -1.00   0.00   0.00   0.00     
 0.00   2.67  -1.00   0.00   0.00    
 0.00   0.00   2.62  -1.00   0.00    
 0.00   0.00   0.00   2.62  -1.00    
 0.00   0.00   0.00  -1.00   3.00

5nd = 5nd - 4st * (-0.38)
---------------------------------
 3.00  -1.00   0.00   0.00   0.00     
 0.00   2.67  -1.00   0.00   0.00    
 0.00   0.00   2.62  -1.00   0.00    
 0.00   0.00   0.00   2.62  -1.00    
 0.00   0.00   0.00   0.00   2.62
 
Hai ragione, avevo ridotto male la matrice, ma comunque non mi trovo con i segni...la diagonale dovrebbe essere tutta negativa mente gli 1 sopra tutti positivi (tranne che per la prima riga)
Stai ancora sbagliando la parte sulla matematica. Ti ho fatto step by step tutti i calcoli della parte forward, se qualcosa non ti torna fammi vedere i tuoi calcoli e discutiamone. Prendiamo, ad esempio, il primo passaggio 2nd = 2nd - 1st * (-0.33) e vediamo cosa succede alla seconda riga.

Per prima cosa calcolo 1st * (-0.33)
Codice:
[  3.00  -1.00   0.00   0.00   0.00 ]  * (-0.33)
------------------------------------------------
1)   3.00 * (-0.33) = -1.00
2)  -1.00 * (-0.33) =  0.33
3)   0.00 * (-0.33) =  0.00
4)   0.00 * (-0.33) =  0.00
5)   0.00 * (-0.33) =  0.00
------------------------------------------------
[ -1.00   0.33   0.00   0.00   0.00 ]

Poi calcolo 2nd - 1st * (-0.33) facendo la sottrazione con il vettore che appena finito di calcolare
Codice:
[ -1.00   3.00  -1.00   0.00   0.00 ] -
[ -1.00   0.33   0.00   0.00   0.00 ] =
-------------------------------------
[  0.00   2.67  -1.00   0.00   0.00 ]
 
  • Mi piace
Reazioni: alessina02