La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Matrici: un’implementazione parametrica in C++

Presentazioni simili


Presentazione sul tema: "Matrici: un’implementazione parametrica in C++"— Transcript della presentazione:

1 Matrici: un’implementazione parametrica in C++
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

2 ADT delle matrici Matrice di ordine n  m
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

3 ADT delle matrici Retrive(i, j, M) Post: ritorna aij in M
AssignEntry(i, j, x, M) Post: assegna ad x l’entrata aij di M Assign(M1,M2) Pre: M1 ed M2 hanno lo stesso ordine Post: assegna ad M1 le entrate di M2 Add(M1, M2) Pre: M1 ed M2 hanno lo stesso ordine Post: ritorna la somma M1 + M2 Mult (M1, M2) Pre: M1 ha ordine n  m, M2 ha ordine m  p Post: ritorna il prodotto M1  M2 di dimensione n  p Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

4 Una struttura dati  n m
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

5 La classe Matrix template <class T> class Matrix { private:
int row_dim, col_dim; T** element; public: inline Matrix (); // costruttore di default Matrix (int rdim, int cdim); // costruttore Matrix (int rdim, int cdim, T* initval); // costruttore con inzializzazione delle entrate Matrix (const Matrix<T>&); // costruttre di copia ~Matrix (); // distruttore // altri metodi }; Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

6 Matrici come vettori di righe/colonne
La memoria è unidimensionale: le matrici (con due o più dimensioni) possono essere rappresentate come un vettore di righe (o di colonne) Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

7 Un costruttore della classe Matrix
template <class T> Matrix<T>::Matrix (int rdim, int cdim, T* initval) // Pre: initval elenca le entrate per riga { row_dim = rdim; col_dim = cdim; element = new T* [row_dim]; for (int i = 0; i < rdim; i++) element[i] = new T [col_dim]; for (int j = 0; j < cdim; j++) element[i][j] = initval [cdim * i + j]; } Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

8 Costruttore di copia template <class T>
Matrix<T>::Matrix (const Matrix<T>& m) { row_dim = m.row_dim; col_dim = m.col_dim; element = new T* [row_dim]; for (int i = 0; i < rdim; i++) element[i] = new T [col_dim]; for (int j = 0; j < cdim; j++) element[i][j] = m.element[i][j]; } Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

9 Le deallocazioni con delete sono simmetriche alle allocazioni con new
Il distruttore template <class T> Matrix<T>::~Matrix () { for (int i = 0; i < row_dim; i++) delete [] element[i]; delete [] element; } Le deallocazioni con delete sono simmetriche alle allocazioni con new Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

10 Metodi “get”: sono const
const assicura che il metodo non altera lo stato template <class T> class Matrix { public: // altri metodi inline int Row () const { return row_dim; } inline int Col () const { return col_dim; } T GetEntry (int i, int j) const; // ritorna this[i, j] dove i e j variano da 1 // a n (== row_dim) ed m (== col_dim) risp. }; T Matrix<T>::GetEntry (int i, int j) const { assert (1 <= i && i <= row_dim && 1 <= j && j <= col_dim); return element[i - 1][j - 1]; } Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

11 Sovraccarico degli operatori
template <class T> Matrix<T>& Matrix<T>::operator= (const Matrix<T>& m) { for (int i = 0; i < row_dim; i++) delete [] element[i]; delete [] element; row_dim = m.row_dim; col_dim = m.col_dim; element = new T* [row_dim]; for (int i = 0; i < rdim; i++) element[i] = new T [col_dim]; for (int i = 0; i < row_dim; i++) for (int j = 0; j < col_dim; j++) element[i][j] = m.element[i][j]; return *this; } Deallocazione dello stato “vecchio” Allocazione del nuovo stato Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

12 La somma di due matrici template <class T> class Matrix {
template <class S> friend Matrix<S> operator+ (const Matrix<S>& m1, const Matrix<S> m2); }; template <class S> Matrix<S> operator+ (const Matrix<S>& m1, const Matrix<S> m2) { assert (m1.Row() == m2.Row() && m1.Col() == m2.Col()); Matrix<S> R (m1.Row(), m1.Col()); for (int i = 0; i < m1.Row(); i++) for (int j = 0; j < m1.Col(); j++) R.element[i][j] = m1.element[i][j] + m2.element[i][j]; return R; } Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

13 La stampa di una matrice
Template <class T> Matrix { // ... template <class S> friend ostream& operator<<(ostream& os, const Matrix<S>& m); // invia una stampa di this sullo stream os // (tipicamente cout) }; Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

14 La stampa di una matrice
template <class T> ostream& operator<<(ostream& os, const Matrix<T>& m) { for (int i = 0; i < m.row_dim; i++) { for (int j = 0; j < m.col_dim; j++) os << ' ' << m.element[i][j]; os << endl; } return os; os è una sorta di buffer, in cui si accumula il flusso dell’informazione, per poi essere “trasmessa” con return os Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

15 La stampa di una matrice
int main() { int init[6] = {1, 2, 3, 4, 5, 6}; Matrix<int> M (2, 3, init); cout << M; } L’effetto di questa istruzione è analogo alla stampa di un intero Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

16 Calcolo del determinante
Se A è una matrice n  n (con n  2) allora dove il cofattore cij è definito: Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

17 Calcolo del determinante
template <class T> T Matrix<T>::Det () { assert(row_dim == col_dim && row_dim >= 2); if (row_dim == 2) return element[0][0]*element[1][1] - element[0][1]*element[1][0]; else { T det = Minor(1,1)*element[0][0]; for (int i = 1; i < row_dim; i++) det += Minor(i+1,1)*element[i][0]; return det; } Minor usa indici da 1 in poi; element da 0 in poi Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

18 Vediamo ora il dettaglio dell’istruzione pseudocodificata
I minori template <class T> T Matrix<T>::Minor (int i, int j) { Matrix<T> A (row_dim-1, col_dim-1); copia in A le entrate di this, salvo la riga i e la colonna j if ((i+j) % 2 == 0) return A.Det(); else return - A.Det(); } Vediamo ora il dettaglio dell’istruzione pseudocodificata Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

19 I minori template <class T>
T Matrix<T>::Minor (int i, int j) { Matrix<T> A (row_dim-1, col_dim-1); for (int h = 0; h < i-1; h++) { for (int k = 0; k < j-1; k++) A.element[h][k] = element[h][k]; for (int k = j; k < col_dim; k++) A.element[h][k-1] = element[h][k]; } Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10

20 I minori template <class T>
T Matrix<T>::Minor (int i, int j) { … for (int h = i; h < row_dim; h++) { for (int k = 0; k < j-1; k++) A.element[h-1][k] = element[h][k]; for (int k = j; k < col_dim; k++) A.element[h-1][k-1] = element[h][k]; } if ((i+j) % 2 == 0) return A.Det(); else return - A.Det(); Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 10


Scaricare ppt "Matrici: un’implementazione parametrica in C++"

Presentazioni simili


Annunci Google