Oppure

Loading
13/03/12 17:07
SynapseZero
Ciao a tutti, cercherò di essere il più breve e conciso possibile.
Ho creato una classe "matrici" che mi serve per risolvere sistemi di n equazioni in n incognite tramite gli algoritmi di Gauss e Gauss-Jordan. Il tutto cercando di lavorare con la memoria dinamica.
-- EDIT --
Con questo costruttore alloco spazio per la matrice e il vettore dei termini noti. In breve volevo sapere se è giusto o no, perchè quando compila non mi da nessun errore, ma quando (alla fine) il programma mi ritorna l'array con le soluzioni del sistema, il primo elemento è sempre sbagliato. Sapendo che non è un errore di algoritmo perchè lo stesso programma l'avevo fatto in vba ho provato a riscrivere il codice usando matrice e vettore statici, e tutto fila perfettamente.
Quindi a questo punto suppongo di aver fatto qualche casino con i puntatori..

Vi riporto anche i metodi che uso nel calcolo delle soluzioni..

--- EDIT ---

Allora.. posto il programma completo che faccio prima.. (la definizione della classe l'ho messa in un header file)

La classe:
#include <iostream>

using namespace std;

class matrici
{
    private:
        float **matrice;
        int ordine, riga, colonna;
        float *termini;
        void azzeramento_sinistro(int, int, int);
        void azzeramento_destro(int ord, int x, int y);
    public:
        matrici();
        matrici(int);
        void riempi();
        void visualizza();
        float *gauss();
        float *gauss_jordan();
};

void matrici::azzeramento_sinistro(int ord, int x, int y) // Rende la matrice triangolare superiore
{
    int i, memo=y;
    float divisore, moltiplicatore;
    divisore=matrice[x][y];
    for (i=0; i<ordine; i++, y++)
        matrice[x][y]/=divisore;
    termini[x]/=divisore;
    y=memo;
    for (i=1; i<ord; i++)
    {
        moltiplicatore=-matrice[x+i][y];
        for (int j=0; j<ord; j++, y++)
            matrice[x+i][y]+=moltiplicatore*matrice[x][y];
        termini[x+i]+=moltiplicatore*termini[x];
        y=memo;
    }
}

void matrici::azzeramento_destro(int ord, int x, int y) // Rende la matrice triangolare inferiore
{
    int memo=y;
    float moltiplicatore;
    for (int i=1; i<ord; i++)
    {
        moltiplicatore=-matrice[x-i][y];
        for (int j=0; j<ord; j++, y--)
            matrice[x-i][y]+=moltiplicatore*matrice[x][y];
        termini[x-i]+=moltiplicatore*termini[x];
        y=memo;
    }
}

matrici::matrici() // Costruttore di default, inizializza una matrice di prova
{
    ordine=3;
    matrice = new float*[ordine];
    for (int i=0; i<ordine; i++)
        matrice[i] = new float[ordine];
    matrice[0][0]=1;
    matrice[0][1]=2;
    matrice[0][2]=-4;
    matrice[1][0]=2;
    matrice[1][1]=-1;
    matrice[1][2]=1;
    matrice[2][0]=1;
    matrice[2][1]=1;
    matrice[2][2]=3;
    termini = new float[ordine];
    termini[0]=3;
    termini[1]=5;
    termini[2]=8;
}

matrici::matrici(int ord) // Costruttore a un parametro, alloca spazio per la matrice e il vettore
{
    if (ord>0)
        ordine=ord;
    else 
        cout << "Errore, valore ordine non valido";
    matrice = new float*[ord];
    for (int i=0; i<ord; i++)
        matrice[i] = new float[ord];
    termini = new float[ord];
}

void matrici::riempi() // Funzione membro per l'inserimento della matrice e dei termini noti
{
    for (riga=0; riga<ordine; riga++)
    {
        for (colonna=0; colonna<ordine; colonna++)
        {
            cout << "Inserisci elemento[" << riga+1 << "][" << colonna+1 << "]";
            cin >> matrice[riga][colonna];
        }
    }
    for (int i=0; i<ordine; i++)
    {
        cout << "Inserisci termine noto" << i+1;
        cin >> termini[i];
    }
}

void matrici::visualizza() // Funzione membro per la visualizzazione della matrice e dei termini noti
{
    cout << "Matrice:" << endl;
    for (riga=0; riga<ordine; riga++)
    {
        for (colonna=0; colonna<ordine; colonna++)
        {
            cout << matrice[riga][colonna] << " ";
        }
        cout << endl;
    }
    cout << "Termini noti:" << endl;
    for (int i=0; i<ordine; i++)
        cout << termini[i] << " ";
    cout << endl;
}

float* matrici::gauss() // Risolve il sistema applicando la regola di Gauss
{
    return termini;
}

float* matrici::gauss_jordan() // Risolve il sistema applicando la regola di Gauss-Jordan
{
    int x=0, y=0, ord=ordine;
    for (int i=0; i<ordine; i++, x++, y++, ord--)
        azzeramento_sinistro(ord, x, y);
    x--;
    y--;
    ord=ordine;
    for (int i=0; i<ordine; i++, x--, y--, ord--)
        azzeramento_destro(ord, x, y);
    return termini;
}


Il main:

#include <iostream>
#include "Matrici.h"

using namespace std;

main ()
{
    matrici prova;
    prova.visualizza();
    prova.gauss_jordan();
    prova.visualizza();
}


L'output è tutto giusto tranne il primo elemento del vettore, che in questo caso esce "0,576923" mentre dovrebbe uscire "3"
Ultima modifica effettuata da SynapseZero 13/03/12 18:37
aaa
13/03/12 18:09
nessuno
Ci mostri la parte privata della classe con i membri ?
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
13/03/12 18:44
nessuno
Io ho questi risultati

Matrice:
1 2 -4
2 -1 1
1 1 3
Termini noti:
3 5 8
Matrice:
1 0 0
0 1 0
0 0 1
Termini noti:
3 2 1
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.