Buongiorno a tutti e buon inizio di 2022! Vi sottopongo quello che per me sta diventando un vero fardello. Ho scritto il codice sotto riportato, ma non riesco ad individuare quale sia l'errore che non mi permette di avere un output corretto, per l'esattezza ottengo che le soluzioni sono tutte uguali a 0.0000 e il numero di iterazioni ottenuto risulta essere sempre 1. Grazie per la vostra attenzione e il vostro eventuale aiuto.
/*Metodi di Jacobi e Gauss-Seidel*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 100
#define MAX_NORMA 100
#define MAX_ITER 10000
#define MAX_DIM 100
void leggiMatrice (int *n, int *m, float A[MAX_DIM][MAX_DIM]) { //n=numero di righe, m=numero di colonne
int i,j; //i=indice di riga, j=indice di colonna
printf ("Numero di righe (n): \n");
scanf ("%d",n);
printf ("Numero di colonne (m): \n");
scanf ("%d",m);
for (i=0;i<*n;i++) {
printf ("Inserisci gli elementi della riga %d: \n",i);
for (j=0;j<*m;j++) {
scanf ("%f",&A[j]);
}
}
}
void stampaVettore (int n, float v[MAX_DIM]) {
int i;
for (i=0;i<n;i++) {
printf ("%f",v);
printf ("\n");
}
printf ("\n");
}
void copiaVettore (int n, float x[], float v[]) {
int i;
for (i=0;i<n;i++) {
v=x;
}
}
float jacobi_gs (int n, float x[], float A[MAX][MAX], int indice) { //indice=1 per Jacobi oppure indice=2 per Gauss-Seidel
int k=0,i,j;
float v[MAX], sum, norma=MAX_NORMA, eps=1e-6;
while (norma>eps) { //Condizioni di arresto
copiaVettore (n,x,v); //Si usa il vettore di appoggio non solo per il metodo di Jacobi, ma anche per la norma
for (j=0;j<n;j++) { //j scorre le soluzioni x(j)
sum=0;
for (i=0;i<n;i++) {
if (i!=j) {
if (indice==1)
sum=sum+A[j]*v; //Metodo di Jacobi
else
sum=sum+A[j]*x; //Metodo di Gauss-Seidel (variabili già aggiornate)
}
}
x[j]=(1/A[j][j])*(A[j][n]-sum);
}
norma=0;
for (j=0;j<n;j++) {
norma=norma+pow(x[j]-v[j],2); //Si aggiorna la norma ||x(j)-x(j-1)|| per le condizioni di arresto
}
norma=sqrt(norma);
k++; //k=numero di iterazioni (per contarle)
if (k>=MAX_ITER) //Numero massimo di iterazioni
break;
}
return (k);
}
void dominanzaDiagonale (int n, float A[MAX][MAX]) {
int i,j; //i=indice di riga, j=indice di colonna
for (i=0;i<n;i++) { //Si scorrono le righe della matrice
float R=0; //R=somma iterata degli elementi che NON si trovano sulla diagonale della riga i
for (j=0;j<n;j++) { //Si scorrono le colonne della matrice
if (j!=i)
R=R+fabs(A[j]);
}
if (fabs(A[i])<=R) {
printf ("\nLa matrice non e' strettamente dominante diagonale, pertanto il sistema potrebbe non convergere.");
break; //Si interrompe la verifica se già si scopre la non dominanza diagonale alla riga i
}
}
}
int main () {
int i,n,m,k,indice;
float x[MAX], A[MAX][MAX];
printf ("\n");
printf ("La convergenza e' assicurata con una matrice dominante diagonale.\n");
leggiMatrice (&n,&m,A);
dominanzaDiagonale (n,A);
do {
printf ("\nDigita 1 per Jacobi, 2 per Gauss-Seidel, 0 per uscire.\n");
scanf ("%d",&indice);
while (indice!=1 && indice!=2 && indice!=0) { //Controllo dell'indice
printf ("Inserisci 1,2 oppure 0: \n");
scanf ("%d",&indice);
}
if (indice!=0) {
for (i=0;i<n;i++) {
x[i]=0;
}
k=jacobi_gs(n,x,A,indice); //I due metodi sono stati implementati nella stessa funzione jacobi_gs; quindi passo indice alla funzione jacobi_gs
printf ("\nLa soluzione e': \n");
stampaVettore (n,x);
printf ("Il numero di iterazioni eseguite e': %d. \n",k);
}
}
while (indice!=0); //Condizione per uscire
printf ("\nCiao!\n");
return (0);
}