/*
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