Metodo di Gauss

Pinturicchio10
Ciao a tutti. Sto realizzando un programma che esegua l'algoritmo di Gauss, per ridurre una matrice a scala. Credo di aver fatto praticamente tutto ma mi resta un solo problema. Vi incollo il programma e poi vi esplicito il mio dubbio.

/* Algoritmo di Gauss */

#include
#include
#include

void Genera(int m, int n, int a[m][n]);
void Stampa(int m, int n, int a[m][n]);
void Scambio(int m, int n, int i, int j, int a[m][n]);
void Gauss(int m, int n, int a[m][n]);

int main(void) {

int r, c;

printf("Inserisci l'ordine della matrice nr:nc: ");
scanf("%d:%d", &r, &c);

int a[r][c]; /* Alloca la matrice */

Genera(r, c, a);
Stampa(r, c, a);
Gauss(r, c, a);
Stampa(r, c, a);

return 0;

}


void Genera(int m, int n, int a[m][n]) {

int i, j, cod;

srand((unsigned) time(NULL));

printf("Generare una matrice casuale 1) - Inserire le entrate 2): ");
scanf("%d", &cod);

if(cod == 1) {
for(i = 0; i < m; i++) {

for(j = 0; j < n; j++) {

a[j] = rand() % 100;

}
}
}

else if(cod == 2) {
printf("Inserisci le entrate: ");

for(i = 0; i < m; i++) {

for(j = 0; j < n; j++) {

scanf("%d", &a[j]);

}
}
}

}

void Stampa(int m, int n, int a[m][n]) {

int i, j;

for(i = 0; i < m; i++) {

for(j = 0; j < n; j++) {

printf("%d ", a[j]);

}
printf("\n");
}

printf("\n \n");
}

void Scambio(int m, int n, int i, int j, int a[m][n]) {

int p, q;

for(p = 0; p < n; p++) {

q = a

;
a

= a[j]

;
a[j]

= q;

}

}

void Gauss(int m, int n, int a[m][n]) {

int col, riga, i, j;
double cost;

for(col = 0; col < m-1; col++) {

riga = col;
while(a[riga][col] == 0)
riga++;

if(riga != col)
Scambio(m, n, riga, col, a);

for(i = col+1; i < m; i++) { /* Parto dalla riga (col+1) */

cost = a[col]/a[riga][col];

for(j = col; j < n; j++) { /* Seleziono la colonna */

a[j] = a[j] - cost * a[riga][j];

}
}
}
}


Il problema secondo me si trova nell' ultimo for della funzione Gauss perchè a[j] = a[j] - cost * a[riga][j] non cambia il valore come dovrebbe. In pratica la variabile cost risulta uguale ad un intero e non a un double come dichiarato e quindi non mi annulla per esempio gli elementi della colonna ma a questi sottrae il multiplo piu grande del pivot che sia minore dell'elemento stesso. Per esempio, 55 - (55/10) *10 non fa 0 ma fa 5.
Come dovrei secondo voi risolvere questo dettaglio? Grazie per la pazienza.


Risposte
Super Squirrel
Dovrebbe andar bene. Il return comunque è superfluo e se proprio vuoi metterlo la condizione dell'if deve essere pivot==min(m,n) o ancora meglio pivot==m visto che il ciclo più esterno interessa le colonne.

Se ti può essere utile ti posto il codice di come avrei impostato io il problema:

#include <iostream>

void genera(const unsigned int& rig, const unsigned int& col, double a[50][50])
{
    for(unsigned int i = 0; i < rig; i++)
    {
        for(unsigned int j = 0; j < col; j++)
        {
            std::cin >> a[i][j];
        }
    }
}

void stampa(const unsigned int& rig, const unsigned int& col, double a[50][50])
{
    std::cout << std::endl;
    for(unsigned int i = 0; i < rig; i++)
    {
        for(unsigned int j = 0; j < col; j++)
        {
            std::cout << a[i][j] << "\t";
        }
        std::cout << std::endl;
    }
}

void scambia_righe(const unsigned int& i_1, const unsigned int& i_2, const unsigned int& col, double a[50][50])
{
    double temp;
    for(unsigned int j = 0; j < col; j++)
    {
        temp = a[i_1][j];
        a[i_1][j] = a[i_2][j];
        a[i_2][j] = temp;
    }
}

void gauss(const unsigned int& rig, const unsigned int& col, double a[50][50])
{
    unsigned int pivot = 0;
    unsigned int i;
    double cost;
    bool dispari = false;
    for(unsigned int j = 0; j < col; j++)
    {
        for(i = pivot; i < rig; i++)
        {
            if(a[i][j] != 0)
            {
                if(i != pivot)
                {
                    scambia_righe(i, pivot, col, a);
                    dispari = !dispari;
                }
                for(unsigned int i_2 = pivot + 1; i_2 < rig; i_2++)
                {
                    if(a[i_2][j] != 0)
                    {
                        cost = - (a[i_2][j] / a[pivot][j]);
                        for(unsigned int j_2 = j; j_2 < col; j_2++)
                        {
                            a[i_2][j_2] += cost * a[pivot][j_2];
                            if((a[i_2][j_2] > 0 && a[i_2][j_2] < 0.1e-013) || (a[i_2][j_2] < 0 && a[i_2][j_2] > -0.1e-013))
                            {
                                a[i_2][j_2] = 0;
                            }
                        }
                    }
                }
                ++pivot;
                break;
            }
        }
    }
    std::cout << std::endl << "rango = " << pivot;
    if(rig == col)
    {
        cost = 1;
        for(i = 0; i < rig; i++)
        {
            cost *= a[i][i];
        }
        if(dispari)
        {
            cost = -cost;
        }
        std::cout << std::endl << "determinante = " << cost;
    }
}

int main()
{
    unsigned int rig, col;
    double a[50][50];
    std::cout << "righe(max50): ";
    std::cin >> rig;
    std::cout << "colonne(max50): ";
    std::cin >> col;
    genera(rig, col, a);
    stampa(rig, col, a);
    gauss(rig, col, a);
    stampa(rig, col, a);
}

Pinturicchio10
Ti ringrazio di cuore per avermi aiutato e per avermi offerto la tua impostazione. Me la studierò in quanto sicuramente più efficiente della mia.

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.