Salve ragazzi,questo di cui vi parlo è un problema legato al codice di cui ho parlato nel post precedente(su cui ancora sto sbattendo la testa). Premesso che so scrivere l'istruzione di come far generare numeri interi casuali ad esempio tra 1 e 15,in C,tramite le funzioni srand(time(0)) e rand,nel seguente modo: rand()%15+1 (perché rand() genera un numero intero tra 0 e 2^31 -1,che è il max intero rappresentabile nel computer,ne si prende il resto della sua divisione per 15,e quindi si ottiene un numero tra 0 e 14,e a questo resto si somma 1). Il problema nel codice,oltre alla riduzione di Gauss con pivoting in sé,sta (anche)in partenza,perché riesco a fargli generare sì numeri reali casuali in modulo minori di 1,ma me li genera o tutti negativi o tutti positivi.Invece essendo appunto casuali,dovrebbero potermi apparire contemporaneamente sia numeri positivi che negativi all'interno della matrice. Poi c'è il problema di Gauss,ma devo prima risolvere questo "problemino" iniziale. Scusatemi.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h> //per inizializzare a zero il generatore di numeri casuali
#define MAXDIM 50 //massimo ordine della matrice A e del vettore colonna b
typedef double matrice[MAXDIM][MAXDIM];
typedef double vettore[MAXDIM];
void letturaecontrollodimensione(int&);
void costruzionematrice(matrice,int);
void stampamatrice(matrice,int);
void costruzionevettore(vettore,matrice,int);
void stampavettore(vettore,int);
void riduzionegauss(matrice,vettore,int);
int ricercapivot(matrice,int,int);
double modulo(double);
void scambio(int&,int&);
void scambiorighe(matrice,vettore,int,int&,int&);
void soluzione_sistematriangolaresuperiore(matrice,vettore,vettore,int);
int main(){
printf("Programma C++ che legge un numero 0<n<=50,genera casualmente la matrice A di ordine n con elementi reali casuali compresi in [-1,1],costruisce il vettore b in cui ogni elemento e' somma delle componenti della corrispondente riga di A,risolve il sistema lineare Ax=b col metodo di Gauss con riordinamento pivotale e stampa le componenti del vettore soluzione x\n");
int n;
matrice A;
letturaecontrollodimensione(n);
costruzionematrice(A,n);
printf("La matrice A[%d][%d] con elementi reali casuali appartenenti a [-1,1] e':\n",n,n);
stampamatrice(A,n);
vettore b;
costruzionevettore(b,A,n);
printf("\n\nIl vettore b[%d] i cui elementi sono le somme delle componenti di ogni riga della matrice A[%d][%d] e':\n\n",n,n,n);
stampavettore(b,n);
riduzionegauss(A,b,n);
printf("\nMatrice dopo riduzione Gauss:\n");
for(int i=0;i<n;i++){printf("\n");
for(int j=0;j<n;j++){
printf("%lf\t",A
[j]);
}
}
vettore x;
soluzione_sistematriangolaresuperiore(A,b,x,n);
printf("\nIl vettore soluzione x[%d] del sistema lineare Ax=b e':\n",n);
stampavettore(x,n);
return 0;
}
//Lettura dimensione della matrice A e del vettore dei termini noti b e controllo che sia compresa tra 0(escluso)e 50(incluso):
void letturaecontrollodimensione(int &d){
do {printf("Inserire un numero intero 0<n<=50:\n"); scanf("%d",&d);} while(d<0||d>MAXDIM);
return;
}
//Costruzione della matrice con numeri random reali appartenenti all'intervallo [-1,1]:
void costruzionematrice(matrice a,int d){
srand(time(0));
for(int i=0;i<d;i++){
for(int j=0;j<d;j++)
{/*Dividendo per RAND_MAX(cioè 2^31 -1)il numero intero generato casualmente,si ottiene un numero reale tra 0 e 1*/
a[j]=rand()/(float)RAND_MAX;
}
}
return;
}
//Stampa della matrice sopra definita:
void stampamatrice(matrice a,int d){
for(int i=0;i<d;i++){printf("\n");
for(int j=0;j<d;j++){
printf("%lf\t",a[j]);
}
}
return;
}
//Costruzione del vettore in cui ogni elemento è la somma delle componenti della corrispondente riga della matrice A:
void costruzionevettore(vettore v,matrice a,int d){
for(int i=0;i<d;i++)
{
for(int j=0;j<d;j++)
{
v+=a[j];
}
}
return;
}
//Stampa di un vettore
void stampavettore(vettore v,int d){
for(int i=0;i<d;i++)
{printf("%lf\t",v);}
return;
}
//Metodo della riduzione di Gauss(con riordinamento pivotale)applicato al sistema lineare Ax=b:
void riduzionegauss(matrice a,vettore v,int d)
{
double m[MAXDIM][MAXDIM-1];/*matrice in cui si inseriscono i coefficienti moltiplicatori m[k]:ha MAXDIM-1 colonne(si moltiplica per questi coefficienti a
partire dalla seconda riga della matrice originaria e dalla seconda componente del vettore dei termini noti,e poi via via le altre)*/
for(int k=0;k<d-1;k++) /*ordine della riduzione delle righe:in particolare,partendo dalla riga successiva alla prima(che è la riga 0)si eseguono operazioni
sulle rimanenti righe,per d-1 volte(e arrivando quindi all'ordine (d-2) compreso)*/
{int k_pivot=ricercapivot(a,d,k);
if (k_pivot!=k)
scambiorighe(a,v,d,k,k_pivot); //scambio tra loro delle righe k-esima e k_pivot-esima(cioè quella in cui c'è il pivot)
for(int i=k+1;i<d;i++) //si parte considerando la "sottomatrice" della matrice di partenza(per far annullare gli elementi sotto la k-esima colonna)
{m[k]=a[k]/a[k][k]; //calcolo del moltiplicatore di ogni k-esima riga(della matrice di partenza e di ogni sottomatrice che si creerà dopo)
for(int j=k+1;j<d;j++)
{
a[j]=a[i][j]-m[i][k]*a[k][j];/*calcolo dell'elemento a[i][j] della matrice ridotta, al passo k-esimo:gli elementi sotto la prima colonna di ogni
//sottomatrice dovranno annullarsi*/
}
v[i]=v[i]-m[i][k]*v[k]; //calcolo dell'elemento v[i] della colonna dei termini noti ridotta, al passo k-esimo
}
}
return;
}
//Calcolo dei moduli degli elementi della matrice(per poi trovare il pivot,cioè l'elemento con maggior valore assoluto sulla colonna):
double modulo(double x)
{if(x<0) return -x;
else return x;
}
//Ricerca dell'indice della riga in cui è presente il pivot:
int ricercapivot(matrice a,int d,int k)
{ double mk,max;
int indice_pivot=k;
for(int i=k+1;i<d;i++){
max=modulo(a[k][k]);
mk=modulo(a[i][k]);
if(mk>max)
{max=mk;
indice_pivot=i;
}
}
return indice_pivot;
}
//Funzione scambio(per poi scambiare tra loro le componenti delle due righe k-esima e k_pivot-esima della matrice):
void scambio(double& x,double& y){
double aux=x;x=y;y=aux;
return;
}
//Funzione che scambia tra loro le righe k-esima e k_pivot-esima della matrice:
void scambiorighe(matrice a,vettore v,int d,int& k,int& k_pivot)
{
for(int j=k;j<d;j++) { //scorrendo sulla colonna k-esima,dalla componente k-esima fino all'ultima,si scambiano gli elementi della riga k e della riga k_pivot
scambio(a[k][j],a[k_pivot][j]);
scambio(v[k],v[k_pivot]);}
return;
}
//Funzione che risolve il sistema triangolare superiore (ottenuto dopo la riduzione di Ax=b con l'algoritmo di Gauss) tramite l'algoritmo backward:
void soluzione_sistematriangolaresuperiore(matrice a,vettore v,vettore x,int d)
{x[0]=v[0]/a[0][0];
for(int i=d-1;i>=0;i--) //partendo dall'ultima riga del sistema,si trova la componente x[i] del vettore soluzione x[d] del sistema:si fa poi l'algoritmo backward
{x[i]=v[i];
for(int j=i+1;j<d;j++)
x[i]-=a[i][j]*x[j];
x[i]/=a[i][i];
}
return;
}