Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Allocazione dinamica Matrici-Array
Forum - C/C++ - Allocazione dinamica Matrici-Array

Avatar
SynapseZero (Normal User)
Newbie


Messaggi: 6
Iscritto: 14/06/2011

Segnala al moderatore
Postato alle 18:07
Martedì, 13/03/2012
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:
Codice sorgente - presumibilmente C++

  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. class matrici
  6. {
  7.     private:
  8.         float **matrice;
  9.         int ordine, riga, colonna;
  10.         float *termini;
  11.         void azzeramento_sinistro(int, int, int);
  12.         void azzeramento_destro(int ord, int x, int y);
  13.     public:
  14.         matrici();
  15.         matrici(int);
  16.         void riempi();
  17.         void visualizza();
  18.         float *gauss();
  19.         float *gauss_jordan();
  20. };
  21.  
  22. void matrici::azzeramento_sinistro(int ord, int x, int y) // Rende la matrice triangolare superiore
  23. {
  24.     int i, memo=y;
  25.     float divisore, moltiplicatore;
  26.     divisore=matrice[x][y];
  27.     for (i=0; i<ordine; i++, y++)
  28.         matrice[x][y]/=divisore;
  29.     termini[x]/=divisore;
  30.     y=memo;
  31.     for (i=1; i<ord; i++)
  32.     {
  33.         moltiplicatore=-matrice[x+i][y];
  34.         for (int j=0; j<ord; j++, y++)
  35.             matrice[x+i][y]+=moltiplicatore*matrice[x][y];
  36.         termini[x+i]+=moltiplicatore*termini[x];
  37.         y=memo;
  38.     }
  39. }
  40.  
  41. void matrici::azzeramento_destro(int ord, int x, int y) // Rende la matrice triangolare inferiore
  42. {
  43.     int memo=y;
  44.     float moltiplicatore;
  45.     for (int i=1; i<ord; i++)
  46.     {
  47.         moltiplicatore=-matrice[x-i][y];
  48.         for (int j=0; j<ord; j++, y--)
  49.             matrice[x-i][y]+=moltiplicatore*matrice[x][y];
  50.         termini[x-i]+=moltiplicatore*termini[x];
  51.         y=memo;
  52.     }
  53. }
  54.  
  55. matrici::matrici() // Costruttore di default, inizializza una matrice di prova
  56. {
  57.     ordine=3;
  58.     matrice = new float*[ordine];
  59.     for (int i=0; i<ordine; i++)
  60.         matrice[i] = new float[ordine];
  61.     matrice[0][0]=1;
  62.     matrice[0][1]=2;
  63.     matrice[0][2]=-4;
  64.     matrice[1][0]=2;
  65.     matrice[1][1]=-1;
  66.     matrice[1][2]=1;
  67.     matrice[2][0]=1;
  68.     matrice[2][1]=1;
  69.     matrice[2][2]=3;
  70.     termini = new float[ordine];
  71.     termini[0]=3;
  72.     termini[1]=5;
  73.     termini[2]=8;
  74. }
  75.  
  76. matrici::matrici(int ord) // Costruttore a un parametro, alloca spazio per la matrice e il vettore
  77. {
  78.     if (ord>0)
  79.         ordine=ord;
  80.     else
  81.         cout << "Errore, valore ordine non valido";
  82.     matrice = new float*[ord];
  83.     for (int i=0; i<ord; i++)
  84.         matrice[i] = new float[ord];
  85.     termini = new float[ord];
  86. }
  87.  
  88. void matrici::riempi() // Funzione membro per l'inserimento della matrice e dei termini noti
  89. {
  90.     for (riga=0; riga<ordine; riga++)
  91.     {
  92.         for (colonna=0; colonna<ordine; colonna++)
  93.         {
  94.             cout << "Inserisci elemento[" << riga+1 << "][" << colonna+1 << "]";
  95.             cin >> matrice[riga][colonna];
  96.         }
  97.     }
  98.     for (int i=0; i<ordine; i++)
  99.     {
  100.         cout << "Inserisci termine noto" << i+1;
  101.         cin >> termini[i];
  102.     }
  103. }
  104.  
  105. void matrici::visualizza() // Funzione membro per la visualizzazione della matrice e dei termini noti
  106. {
  107.     cout << "Matrice:" << endl;
  108.     for (riga=0; riga<ordine; riga++)
  109.     {
  110.         for (colonna=0; colonna<ordine; colonna++)
  111.         {
  112.             cout << matrice[riga][colonna] << " ";
  113.         }
  114.         cout << endl;
  115.     }
  116.     cout << "Termini noti:" << endl;
  117.     for (int i=0; i<ordine; i++)
  118.         cout << termini[i] << " ";
  119.     cout << endl;
  120. }
  121.  
  122. float* matrici::gauss() // Risolve il sistema applicando la regola di Gauss
  123. {
  124.     return termini;
  125. }
  126.  
  127. float* matrici::gauss_jordan() // Risolve il sistema applicando la regola di Gauss-Jordan
  128. {
  129.     int x=0, y=0, ord=ordine;
  130.     for (int i=0; i<ordine; i++, x++, y++, ord--)
  131.         azzeramento_sinistro(ord, x, y);
  132.     x--;
  133.     y--;
  134.     ord=ordine;
  135.     for (int i=0; i<ordine; i++, x--, y--, ord--)
  136.         azzeramento_destro(ord, x, y);
  137.     return termini;
  138. }



Il main:

Codice sorgente - presumibilmente C++

  1. #include <iostream>
  2. #include "Matrici.h"
  3.  
  4. using namespace std;
  5.  
  6. main ()
  7. {
  8.     matrici prova;
  9.     prova.visualizza();
  10.     prova.gauss_jordan();
  11.     prova.visualizza();
  12. }



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 il 13/03/2012 alle 19:37
PM
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6381
Iscritto: 03/01/2010

Up
1
Down
V
Segnala al moderatore
Postato alle 19:44
Martedì, 13/03/2012
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

Okay sono allibito... stesso identico codice che ho incollato sopra a me eseguendolo da Termini noti: 0.576923 2 1... - SynapseZero - 13/03/12 19:49
Quale IDE/compilatore usi? - nessuno - 13/03/12 19:50
A scuola dev (e mi dava lo stesso problema), qua a casa uso il mac con Xcode e se devo compilarlo/eseguirlo uso da terminale il g++ (come su linux, dato che a scuola ce li fanno provare anche li..) - SynapseZero - 13/03/12 19:57
Ho provato con Visual C++ 2010 e con DevC++ e ho avuto lo stesso risultato ... - nessuno - 13/03/12 20:00
http://i40.tinypic.com/jg7f5y.png Guarda tu stesso.. Adesso accendo l'altro computer e provo lì... - SynapseZero - 13/03/12 20:05
Ho provato su windows e va.. Ho provato su Linux e da lo stesso identico errore.. Vabbè.. Comunque grazie mille per l'aiuto! - SynapseZero - 13/03/12 20:23


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à.
PM
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6381
Iscritto: 03/01/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 19:09
Martedì, 13/03/2012
Ci mostri la parte privata della classe con i membri ?

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(); - SynapseZero - 13/03/12 19:20
void visualizza(); float *gauss(); float *gauss_jordan(); }; P.S. Ma non posso aggiungere una risposta? -_- - SynapseZero - 13/03/12 19:23
Puoi modificare (edit) il primo post ... - nessuno - 13/03/12 19:29
Non vedo problemi evidenti ... puoi postare (modificando il tuo primo post) un esempio completo e compilabile indicando cosa inserire e cosa ottenere (e il problema nel valore di cui parlavi)? - nessuno - 13/03/12 19:30


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à.
PM