Aiuto programma Gauss

di il
4 risposte

Aiuto programma Gauss

Salve a tutti, questo è il mio primo post, nel caso dovessi compiere qualche errore perdonatemi

Sto combattendo da qualche pomeriggio con un programma che deve trovare la soluzione di un sistema applicando Gauss e sostituzione all'indietro alla matrice associata A (b è il vettore dei termini noti), per poi calcolare la norma infinito del vettore residuo r=Ax-b.
Ecco il programma:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define MAXN 100


int legginat(){
	int n;

	do{
	printf("\n\nInserisci la dimensione della matrice\n\t");
	scanf("%d",&n);
	}while(n<0||n>=MAXN);
	
return(n);
}


void vett(int n,float b[]){
	int i;

//vettore b dei termini noti
	
	for(i=0;i<n;i++){
		printf("\n\nInserisci la componente %d del vettore dei termini noti\n\t",i);
		scanf("%f",&b[i]);
	}	
	
return;
}

void scambiocol(float a[MAXN][MAXN],int n,int i){
	int j;
	float app;
	
	for(j=0;j<=n;j++){
		app=a[j][i];
		a[j][i]=a[j][i+1];
		a[j][i+1]=app;
	}
	
return;
}

void leggimat(int n, float a[MAXN][MAXN]){
	int i,j;

//indici delle colonne
	for(j=0;j<n;j++){
		a[0][j]=j+1;
	}

//coefficienti della matrice A	
	for(i=1;i<n+1;i++){
		for(j=0;j<n;j++){
			printf("\n\nInserisci la componente %d,%d della matrice\n\t",i-1,j);
			scanf("%f",&a[i][j]);
		}
	}

//stampa della matrice inserita
	printf("\n\nMatrice iniziale:\n");
	for(i=0;i<=n;i++){
		for(j=0;j<n;j++){
			printf("\t%f",a[i][j]);
		}
		printf("\n");
	}


return;
	
}

int massimo(float a[MAXN][MAXN],int n,int k){
  int i,imax;
  float app;

	app=a[k+1][k];
	imax=k+1;
	for(i=k+1;i<=n;i++) {
		if(fabs(a[i][k])>app)
		imax=i;
	}	

return(i);
}

void scambiorighe(float a[MAXN][MAXN],int n,int imax,int i){
	int j;
	float app;
	
	for(j=0;j<n;j++){
		app=a[i][j];
		a[i][j]=a[imax][j];
		a[imax][j]=app;
	}
	
return;
}

void gauss(int n,float a[MAXN][MAXN],float b[]){
	int i,j,k;
	float c,imax,m;

	for(k=0;k<n-1;k++){
		imax=massimo(a,n,k);
		if(imax=!k+1) scambiorighe(a,n,imax,k+1);
		for(i=k+2;i<=n;i++){
			//controllo pivot		
			if(a[k+1][k]==0) scambiocol(a,n,k);
			
			m=a[i][k]/a[k+1][k]; printf("\n\nValore %d di m: %f",k,m); //stampa di controllo
			for(j=k;j<n;j++){
				a[i][j]=a[i][j]-m*a[k+1][j];
			}
			b[i-1]=b[i-1]-m*b[k];
		}
			//stampa della matrice parziale
			printf("\n\nMatrice parziale, passaggio %d:\n",k);
			for(i=0;i<=n;i++){
			for(j=0;j<n;j++){
				printf("\t%f",a[i][j]);
			}
			printf("\n");
		}
	}

//stampa di U
	printf("\n\nMatrice triangolarizzata:\n");
	for(i=0;i<=n;i++){
		for(j=0;j<n;j++){
			printf("\t%f",a[i][j]);
		}
		printf("\n");
	}
	
//singolarità 
	for(i=0;i<n;i++){
		if(a[i+1][i]==0){
			printf("\n\nLa matrice e' SINGOLARE, non esiste un'unica soluzione");
			leggimat(n,a);
		}
	}
	
return;

}

void sost_indietro(int n,float U[MAXN][MAXN], float b[MAXN],float x[MAXN]){
	int i,j,k;
	float som;	
	
	x[n-1]=b[n-1]/U[n][n-1];
	
	for(k=n-1;k>0;k--){
		som=0;
		for(j=k+1;j<n;j++){
			som+=(U[k][j]*x[j]);
		}
		x[k]=(1./U[k][k])*(b[k]-som);
	}
	
return;
}

void stampa(int n,float x[]){
	printf("\n\nLa soluzione del sistema associato alla matrice e':\n");
	for(int i=0;i<n;i++){
		printf("%f\n",x[i]);}
		
return;
}

void prods(int n,float a[MAXN][MAXN],float x[],float prod[]) {
   	int i,j;
   	
//inizializzazione
   	for(i=0;i<n;i++){
		prod[i]=0;
	}

//prodotto righe per colonne Ax
	for(j=0;j<=n;j++){
		for(i=0;i<n;i++){
			prod[i]=prod[i]+(a[j][i]*x[i]);
		}
	}   
	
return;   
}

float norma(int n,float a[MAXN][MAXN],float b[],float x[],float r[]){
	float prod[MAXN],res=0;
	int i;
	
	for(i=0;i<n;i++){
		prods(n,a,x,prod);
		r[i]=b[i]-prod[i];	
	}
	
	for(i=0;i<n;i++){
	if (res<r[i])
	res=r[i];
	}

return(res);
}

int main (){
	int n;
	float a[MAXN][MAXN],b[MAXN],x[MAXN],r[MAXN],res;
    
	n=legginat();
	leggimat(n,a);
	vett(n,b);
	gauss(n,a,b);
	sost_indietro(n,a,b,x);
	stampa(n,x);
	res=norma(n,a,b,x,r);
	printf("\n\n La norma infinito e' %f",res);
	
return (1);
}

Ho provato il programma con

A:

12 1 2 3
1 12 2 3
1 2 12 3
1 2 3 12

b: 18, 18, 18, 18

In teoria la soluzione dovrebbe essere un vettore x= 1,1,1,1

Ecco l'output:

Valore 0 di m:12
valore 0 di m:1
Valore 0 di m:1

Matrice parziale, passaggio 0:
1 2 3 4
1 12 2 3
0 -143 -22 -33
0 -10 10 0
0 -10 1 9

Valore 1 di m:-0.833333
Valore 1 di m:-0.833333

Matrice parziale, passaggio 1:
1 2 3 4
0 -143 -22 -33
1 12 2 3
0 -0 11.666667 2.5
0 -0 2.666667 11.5

Valore 2 di m: -0.121212

Matrice parziale, passaggio 2:
1 2 3 4
0 -0 11.666667 2.5
1 12 2 3
0 -143 -22 -33
0 -0 -0 7.5

Matrice triangolarizzata:
1 2 3 4
0 -0 11.666667 2.5
1 12 2 3
0 -143 -22 -33
0 -0 -0 7.5

La matrice è SINGOLARE, non esiste un'unica soluzione

Inserisci la componente 0,0 della matrice

Probabilmente c'è qualche problema serio nella funzione gauss, ma non riesco a trovarlo.. in più proprio non riesco a capire come mai il valore di m venga calcolato più di una volta!
HELP

4 Risposte

  • Re: Aiuto programma Gauss

    Se non usi i tag CODE e una corretta indentazione, il codice non si capisce ...
  • Re: Aiuto programma Gauss

    oregon ha scritto:


    Se non usi i tag CODE e una corretta indentazione, il codice non si capisce ...
    Ok, lo modifico!
  • Re: Aiuto programma Gauss

    Meglio?
  • Re: Aiuto programma Gauss

    Ciao ti passo questo codice che avevo scritto qualche anno fa per passarci il tempo, ti avverto su un'po di cose
    1)ti conviene ingrandire le dimensioni sia della finestra di output che quelle del buffer, perchè se no risulta una cosa incasinata
    2) è pieno di scritte inutili che poco centrano con l'algoritmo, poi non sapevo ancora usare l' allocazione dinamica di memoria, che quindi non c'è
    3) il copia incolla fa schiffo, quindi ti tocca aggiustare le cose da te

    #include<stdio.h>
    #include<math.h>
    #include<windows.h>
    main(){

    int a,b,i,j,r,u,t;
    double l[500][501],mol[501],max[501],somma,x[501],k,lo[500];
    char v[2],f,risp[2];/* lettera della variabile che vorremo usare*/
    loop:
    system("cls");
    system("color 74");


    printf("\n\n\t\t\t\t\tRISOLUZIONE DI SISTEMI Ux=b MEDIANTE L' ALGORITMO DI GAUSS CON PIVOTING PARZIALE");
    printf("\n\n\nINDICARE IN CHE VARIABILE SI INTENDE RISOLVERE IL SISTEMA:");
    scanf("%s",&v[0]);
    printf("\n\nINSERIRE LE DIMENSIONI DELLA MATRICE COMPLETA U|b NEL SEGUENTE ORDINE:[numero righe] spazio [numero colonne]\n");
    scanf("%d%d",&a,&b);
    printf("\nmatrice [%d]x[%d]\nATTENZIONE:L'ULTIMO TERMINE DELLA RIGA FA PARTE DEL VETTORE DEI TERMINI NOTI\n\n",a,b);


    /*scansione della matrice*/

    for(i=0;i<a;i++){
    printf("inserire riga%d della matrice U|b completa:",i+1);
    for(j=0;j<b;j++)
    scanf("%lf",&l[j]);};

    /*visualizzazione della matrice iniziale*/

    printf("\nil sistema da te caricato:\n\n",v);
    for(i=0;i<a;i++){
    for(j=0,t=0;j<b && t<b;j++,t++) if(t==b-1) {printf("%15.7lf\t",l[j]);}else
    if(j==b-2) {printf("%15.7lf.%s%d =\t",l[j],v,t+1);} else
    {printf("%15.7lf.%s%d\t",l[j],v,t+1);}printf("\n");};

    /*pausa per controllare il sistema;
    premere invio per continuare*/
    getchar();
    getchar();


    printf("\n\n\n\t\t\tMETODO DI GAUSS\n");

    /*CICLO FOR CHE GOVERNA IL TUTTO*/

    for(u=0;u<a-1;u++){

    /*Pivoting*/

    printf("\n\npasso %d\n",u+1);

    // 1° CONTROLLA NELLA COLONNA TUTTI GLI ELEMENTI MAGGIORI DI QUELLO INIZIALE ed li salva in max

    for(i=u;i<a;i++){ if(fabs(l)>fabs(l)) for(r=0;r<b;r++) max[r]=l[r] ;

    //2° SE NON VI SONO ELEMENTI MAGGIORI AL PRIMO ASSOCIA LA PRIMA RIGA DEL CICLO AL VETTORE MAX

    else for(r=0;r<b;r++) max[r]=l[r];};

    /*3° SE VI è ALMENO UN ELEMENTO MAGGIORE DEL PRIMO DELLA COLONNA CONTROLLA SE QUEST'ULTIMO è IL PIU
    GRANDE, COSI FACENDO TROVA IL MASSIMO ELEMENTO DELLA COLONNA ED ASSOCIA LA SUA RIGA AL VETTORE MAX*/

    for(i=u;i<a;i++){ if(fabs(l)>fabs(max)) for(r=0;r<b;r++) max[r]=l[r];};

    printf("\nelemento massimo: %lf\n",max);

    /*4° SOSTITUISCE PRIMA LA RIGA CONTENENTE IL PIVOT CON QUELLA CHE PRESENTA IL MASSIMO ELEMENTO DELLA COLONNA
    PRIMA CONSIDERATA*/

    for(i=u;i<a;i++){ for(r=0;l[r]==max[r]&&r<b;r++) if(r==b-1) for(r=0;r<b;r++) l[r]=l[r];};



    /*5° SOSTITUISCE LA PRIMA RIGHA DEL CICLO CON IL VETTORE MAX*/

    for(r=0;r<b;r++) l[r]=max[r];


    /*PIVOTING FINITO*/

    /*6 DISEGNA IL SISTEMA PIVOTATO*/

    printf("\nla matrice Ux=b pivotata:\n");
    for(i=0;i<a;i++){
    for(j=0,t=0;j<b && t<b;j++,t++) if(t==b-1) {printf("%15.7lf\t",l[i][j]);}else
    if(j==b-2) {printf("%15.7lf.%s%d =\t",l[i][j],v,t+1);} else
    {printf("%15.7lf.%s%d\t",l[i][j],v,t+1);}printf("\n");};

    /*MOLTIPLICATORI ED ALGORITMO */



    /*calcolo moltiplicatori*/
    for(i=u+1;i<a;i++){
    mol[i]=l[i]/(l[u][u]);


    /* applicazione algoritmo*/

    for(j=u;j<b;j++){
    l[i][j]=(l[i][j])-(mol[i]*l[u][j]);}};
    printf("\n\n");

    /*visualizzazione della matrice finale ed moltilicatori*/

    for(i=u+1;i<a;i++){printf("moltiplicatore%d: %f\t",i,mol[i]);}
    printf("\n");
    printf("\napplicazione algoritmo alla matrice U|b:\n");
    printf("\n");
    for(i=0;i<a;i++){
    for(j=0;j<b;j++)
    {printf("%15.7lf\t",l[i][j]);}printf("\n");};
    printf("\n");
    printf("\n______________________________________________________________________________________________\n\n");}




    /*Visualizzazione del sistema triangolare finale*/
    printf("\t\t\t RISOLUZIONE DEL SISTEMA TRIANGOLARE:\n\n");
    for(i=0;i<a;i++){
    for(j=0,t=0;j<b && t<b;j++,t++) if(t==b-1) {printf("%15.10lf\t",l[i][j]);}else
    if(j==b-2) {printf("%15.7lf.%s%d =\t",l[i][j],v,t+1);} else
    {printf("%15.7lf.%s%d\t",l[i][j],v,t+1);}printf("\n");};


    /*Risoluzione sistema triangolare*/
    printf("\n\t\tSOLUZIONI:\n");


    /*Condizione iniziale per il calcolo: i coefficienti delle variabili dipendenti devono essere diversi da 0 ossia maggiori di
    0,0000000000001 per approssimazione */

    if(b==a+1 && fabs(l[a-1][b-2])>0.00000000000001){

    /*primo passo... divido il termine noto per il coefficiente della variabile dipendente
    e lo moltiplico per tutta la colonna*/

    k=l[a-1][b-1]/l[a-1][b-2];

    for(i=0;i<a-1;i++){l[i][b-2]=k*l[i][b-2];}

    /*passi successivi....*/
    for(u=a-2;u>-1;u--){
    somma=0; for(j=b-2;j>u;j--) somma=somma+l[u][j];
    x[u]=((l[u][b-1]-somma)/l[u][u]);
    for(i=0;i<u;i++)
    l[i][u]=x[u]*l[i][u];}
    printf("\n");
    x[a-1]=k;
    for(u=0; u<a;u++){
    printf("%s%d=%.10lf",v,u+1,x[u]);printf("\t\t");};}


    /*Se ho che l[a-1][b-2]<0.000000000000001 dò errore*/
    else {printf("\n\t\t\tERRORE:CONTROLLARE IL SISTEMA FINALE...");}
    printf("\n\n\n");

    printf("\t\trisolvere altro sistema? [si/no]\n\n");
    scanf("%c",&risp);
    if(risp[0]=='s') goto loop;
    getchar();
    getchar();
    }
Devi accedere o registrarti per scrivere nel forum
4 risposte