/* CMatrix.h */ #ifndef CMATRIX_H #define CMATRIX_H #include <stdio.h> #include <assert.h>
// Lettura singolo valore void ReadValue(FILE *pFile,int &element,const char *format = NULL) { fscanf(pFile,format ? format : "%d",&element); } void ReadValue(FILE *pFile,double &element,const char *format = NULL) { fscanf(pFile,format ? format : "%lf",&element); }
// Scrittura singolo valore void WriteValue(FILE *pFile,const int element,const char *format = NULL) { fprintf(pFile,format ? format : "%d",element); } void WriteValue(FILE *pFile,const double element,const char *format = NULL) { fprintf(pFile,format ? format : "%lf",element); }
template <class T> class CMatrix { private:
int m_numRows; // Numero di righe int m_numCols; // Numero di colonne T *m_pBase; // Matrice memorizzata per righe
bool SetAttribute(int numRows,int numCols) { assert(!IsValid()); assert(numRows > 0 && numCols > 0); m_pBase = new T [numRows * numCols]; if(m_pBase) { m_numRows = numRows; m_numCols = numCols; } return IsValid(); }
void ResetAttribute() { if(IsValid()) { delete [] m_pBase; m_pBase = NULL; m_numRows = m_numCols = 0; } }
void SetValues(T value = 0) { assert(IsValid()); for(int nr = 0; nr < GetNumRows(); nr++) for(int nc = 0; nc < GetNumCols(); nc++) (*this)(nr,nc) = value; }
void SetValues(const CMatrix &from) { assert(IsValid()); assert(AreComparable(from)); for(int nr = 0; nr < GetNumRows(); nr++) for(int nc = 0; nc < GetNumCols(); nc++) (*this)(nr,nc) = from(nr,nc); }
public:
// Accesso agli attributi // Restituisce il numero di righe inline int GetNumRows() const { return m_numRows; } // Restituisce il numero di colonne inline int GetNumCols() const { return m_numCols; }
// Accesso al generico elemento della matrice inline T &operator () (int nr,int nc) { assert(AreValid(nr,nc)); return m_pBase[nr * GetNumCols() + nc]; } // Accesso al generico elemento della matrice (se costante) inline const T &operator () (int nr,int nc) const { assert(AreValid(nr,nc)); return m_pBase[nr * GetNumCols() + nc]; }
// Matrice valida? inline bool IsValid() const { return (m_pBase != NULL); }
// Indice di riga valido? inline bool IsValidRow(int nr) const { return (0 <= nr && nr < GetNumRows()); } // Indice di colonna valido? inline bool IsValidCol(int nc) const { return (0 <= nc && nc < GetNumCols()); } // Indici di riga e di colonna validi? inline bool AreValid(int nr,int nc) const { return (IsValidRow(nr) && IsValidCol(nc)); }
// Matrici con la stessa dimensione? inline bool AreComparable(const CMatrix &other) const { return (GetNumRows() == other.GetNumRows() && GetNumCols() == other.GetNumCols()); }
// Costruttori e distruttori
// Costruttore di default // la matrice generata NON č valida CMatrix() : m_numRows(0), m_numCols(0), m_pBase(NULL) { }
// Costruttore e inizializzatore // la matrice generata puņ non essere valida CMatrix(int numRows,int numCols,T value = 0) : m_numRows(0), m_numCols(0), m_pBase(NULL) { if(SetAttribute(numRows,numCols)) SetValues(value); }
// Costruttore per copia // la matrice generata puņ non essere valida CMatrix(const CMatrix &from) : m_numRows(0), m_numCols(0), m_pBase(NULL) { if(SetAttribute(from.GetNumRows(),from.GetNumCols())) SetValues(from); }
// Distruttore ~CMatrix() { ResetAttribute(); }
// Operatori
// CMatrix = CMatrix CMatrix &operator = (const CMatrix &from) { if(this == &from) return *this; ResetAttribute(); if(from.IsValid()) if(SetAttribute(from.GetNumRows(),from.GetNumCols())) SetValues(from); return *this; }
// CMatrix + CMatrix CMatrix operator + (const CMatrix &other) const { assert(IsValid()); if(!AreComparable(other)) throw "Not comparable"; CMatrix temp(*this); for(int nr = 0; nr < GetNumRows(); nr++) for(int nc = 0; nc < GetNumCols(); nc++) temp(nr,nc) += other(nr,nc); return temp; }
// CMatrix += CMatrix inline CMatrix operator += (const CMatrix &other) { (*this) = (*this) + other; return *this; }
// CMatrix * CMatrix CMatrix operator * (const CMatrix &other) const { assert(IsValid()); if(GetNumCols() != other.GetNumRows()) throw "Not comparable"; CMatrix temp(GetNumRows(),other.GetNumCols()); for(int nr = 0; nr < GetNumRows(); nr++) for(int nc = 0; nc < other.GetNumCols(); nc++) for(int n = 0; n < GetNumCols(); n++) temp(nr,nc) += (*this)(nr,n) * other(n,nc); return temp; }
// CMatrix *= CMatrix inline CMatrix operator *= (const CMatrix &other) { (*this) = (*this) * other; return *this; }
// CMatrix == CMatrix bool operator == (const CMatrix &other) const { assert(IsValid()); if(!AreComparable(other)) throw "Not comparable"; for(int nr = 0; nr < GetNumRows(); nr++) for(int nc = 0; nc < GetNumCols(); nc++) if((*this)(nr,nc) != other(nr,nc)) return false; return true; }
// CMatrix != CMatrix inline bool operator != (const CMatrix &other) const { return !(*this == other); }
// Operazioni di Input/Output
// Lettura matrice void Read(FILE *pFile) { assert(IsValid()); assert(pFile != NULL); for(int nr = 0; nr < GetNumRows(); nr++) for(int nc = 0; nc < GetNumCols(); nc++) ReadValue(pFile,(*this)(nr,nc)); }
// Scrittura matrice void Write(FILE *pFile) const { assert(IsValid()); assert(pFile != NULL); for(int nr = 0; nr < GetNumRows(); nr++) { for(int nc = 0; nc < GetNumCols(); nc++) { if(nc) fprintf(pFile," "); WriteValue(pFile,(*this)(nr,nc)); } fprintf(pFile,"\n"); } }
}; #endif