📄 matrix.h
字号:
/*
This "SOFTWARE" is a free software.
You are allowed to download, use, modify and redistribute this software.
The software is provided "AS IS" without warranty of any kind.
Copyright: 2002, University of Koblenz-Landau, Dirk Balthasar
*/
/*******************************************************************************
File: Matrix.h
Cool! Template class for basic matrix operations
(c) 2001 Labor Bilderkennen
Universitaet Koblenz-Landau
Dirk Balthasar
*******************************************************************************/
#ifndef Matrix_h
#define Matrix_h
#include <assert.h>
/// Matrix template class implementation
template < class Type >
class CMatrix
{
public:
/// destructor
~CMatrix();
/// create empty matrix
CMatrix();
/// create matrix with \param<w> columns and \param<h> rows. \param SetToZero = true -> Set all elemets = 0
CMatrix(int w, int h, bool SetToZero);
/// create matrix with \param<w> columns and \param<h> rows
CMatrix(int w, int h);
/// copy constructor
CMatrix(const CMatrix<Type> &Original);
/// get value at position x,y
const Type &Get(int x, int y);
/// set value at position x, y
void Set(int x, int y, const Type& T);
/// retreive the amount of memory of one entry (pixel)
int GetCellSize(){return sizeof(Type);}
/// nice access to data
Type &operator() (unsigned x, unsigned y);
/// access with range check
Type &operator()(int x, int y, Type &OutsideMatrix);
/// linear access to data
Type &operator()(int datapos);
/// retreive liniar position, where item x,y is stored
int GetDataPos(int x, int y){return (m_Width*y+x);}
/// get x,y offset of linear address
void GetXYPos(int datapos, int &x, int &y){x = datapos % m_Width; y = datapos / m_Width;}
/// get x offset of linear address
int GetXPos(int datapos){return datapos % m_Width;}
/// get y offset of linear address
int GetYPos(int datapos){return datapos / m_Width;}
/// set all fields to zero
void Zero();
/// set all elements to Value
void Set(const Type &Value);
/// (*) Matrix multiply operator
CMatrix<Type> operator*(CMatrix<Type> &Operator2);
/// (=) assignment operator
CMatrix<Type>& operator=(CMatrix<Type> &right);
/// get a string with values of matrix
// char* GetTraceString();
/// trace matrix
void Trace(char *Title = NULL);
/// create identity matrix (Einheitsmatrix)
void IdentityMatrix();
/// returns biggest element in Matrix
Type *MaxValue();
/// returns biggest element and position of biggest element in Matrix
Type *MaxValueXYPos(int &x, int &y);
/// returns biggest element in Line
Type *MaxInLine(int Line);
/// returns smallest element in Matrix
Type *MinValue();
/// returns smallest element and position of smallest element in Matrix
Type *MinValueXYPos(int &x, int &y);
/// returns smallest element in Line
Type *MinInLine(int Line);
/// returns sum of all elements in Line
Type SumInLine(int Line);
/// set matrix to given size
void SetSize(int w, int h);
/// Retrieve width of Matrix
int GetWidth()const{return m_Width;}
/// Retrieve height of Matrix
int GetHeight()const{return m_Height;}
protected:
/// stores width of matrix
int m_Width;
/// stores height of matrix
int m_Height;
// init
void Init(int w, int h);
/// core function for matrix multipication
static void Multiply(CMatrix<Type> &A, CMatrix<Type> &B, CMatrix<Type> &Result);
/// pointer to memory
Type *m_Data;
};
/////////////////////////////////////////////////////////////////////////////
// CMatrix implementation
/////////////////////////////////////////////////////////////////////////////
template <class Type>
CMatrix<Type>::~CMatrix()
{
delete [] m_Data;
}
template < class Type >
CMatrix<Type>:: CMatrix(int w, int h)
{
m_Data = NULL;
Init(w,h);
}
template < class Type >
CMatrix<Type>::CMatrix(int w, int h, bool SetToZero)
{
m_Data = 0;
Init(w,h);
if (SetToZero) Zero();
}
template < class Type >
CMatrix<Type>::CMatrix()
{
m_Data = 0;
m_Height = m_Width = 0;
}
template < class Type >
CMatrix<Type>::CMatrix(const CMatrix<Type> &Original)
{
// TRACE("Copy constructor!\n");
m_Data = 0;
Init(Original.GetWidth(), Original.GetHeight());
memcpy(m_Data, Original.m_Data, GetWidth()*GetHeight()*sizeof(Type));
}
template < class Type >
const Type& CMatrix<Type>::Get(int x, int y)
{
return m_Data[(m_Width*y+x)];
}
template <class Type>
Type &CMatrix<Type>::operator()(unsigned x, unsigned y)
{
//if (row >= rows_ || col >= cols_)
// throw BadIndex("const Matrix subscript out of bounds");
return m_Data[(m_Width*y + x)];
}
template < class Type >
Type &CMatrix<Type>::operator()(int datapos)
{
return m_Data[datapos];
}
template < class Type >
Type &CMatrix<Type>::operator()(int x, int y, Type &OutsideMatrix)
{
if ((x < 0) || (y < 0) || (x >= GetWidth()) || (y >= GetHeight()))
{ // out of image
return OutsideMatrix;
}
else return (*this)(x,y);
}
template < class Type >
void CMatrix<Type>::Set(int x, int y, const Type &T)
{
m_Data[(m_Width*y+x)] = T;
}
template < class Type >
void CMatrix<Type>::Set(const Type &Value)
{
for (int i = 0; i < m_Width*m_Height; i++)
m_Data[i] = Value;
}
template < class Type >
void CMatrix<Type>::Zero()
{
for (int i = 0; i < m_Width*m_Height; i++)
m_Data[i] = 0;
}
template < class Type >
CMatrix<Type> CMatrix<Type>::operator*(CMatrix<Type> &Operator2)
{ // this is Operator1
CMatrix<Type> Result(GetHeight(), Operator2.GetWidth());
Multiply(*this, Operator2, Result);
return Result;
}
template < class Type >
CMatrix<Type>& CMatrix<Type>::operator=(CMatrix<Type> &right)
{
SetSize(right.GetWidth(), right.GetHeight());
// copy values
for (int x = 0; x < GetWidth(); x++)
for (int y = 0 ; y < GetHeight(); y++)
Set(x,y, right.Get(x,y));
return *this;
}
/*
template < class Type >
char* CMatrix<Type>::GetTraceString()
{
ostrstream A;
for (int y = 0; y < GetHeight(); y++)
{
for (int x = 0; x < GetWidth(); x++)
{
A << Get(x,y) << " ";
}
A << endl;
}
A << ends; // 0-Termination
return A.str();
}
*/
template < class Type >
void CMatrix<Type>::Trace(char *Title)
{
/* char *str = GetTraceString();
if (Title != NULL)
TTRACE("%s\n%s\n", Title, str);
else
TTRACE("%s\n", str);
delete str;*/
}
template < class Type >
void CMatrix<Type>::SetSize(int w, int h)
{
if (w != GetWidth() || h != GetHeight())
Init(w,h);
}
template < class Type >
void CMatrix<Type>::Init(int w, int h)
{
delete m_Data;
m_Data = new Type[w*h];
m_Width = w;
m_Height = h;
// Zero();
}
template < class Type >
void CMatrix<Type>::Multiply(CMatrix<Type> &A, CMatrix<Type> &B, CMatrix<Type> &Result)
{
// check input
assert(A.GetWidth() == B.GetHeight());
// check target size
assert(Result.GetWidth() == A.GetHeight());
assert(Result.GetHeight() == B.GetWidth());
// todo: optimization: we need no tmp, if A!=C / B!=C
CMatrix<Type> C(Result.GetWidth(), Result.GetHeight());
Type Sum;
for (int x = 0; x < A.GetWidth(); x++)
for (int y = 0; y < A.GetHeight(); y++)
{ // A-line * B-column
Sum = 0;
for (int i = 0; i < A.GetHeight(); i++)
{
Sum += A.Get(i,y) * B.Get(x,i);
}
C.Set(x,y,Sum);
}
Result = C;
}
template < class Type >
void CMatrix<Type>::IdentityMatrix()
{
for( int y=0; y < GetHeight(); ++y)
{
for( int x=0; x < GetWidth(); ++x)
{
if( y==x)
(*this)(x,y) = 1;
else
(*this)(x,y) = 0;
}
}
}
template < class Type >
Type *CMatrix<Type>::MaxInLine(int Line)
{
Type *MAX = 0;
for (int i = 0; i < GetWidth(); i++)
if (!MAX)
MAX = &((*this)(i, Line));
else
if (*MAX < (*this)(i, Line))
MAX = &((*this)(i, Line));
return MAX;
}
template < class Type >
Type *CMatrix<Type>::MaxValue()
{
Type *MAX = 0;
for (int y = 0; y < GetHeight(); y++)
for (int x = 0; x < GetWidth(); x++)
if (!MAX)
MAX = &((*this)(x, y));
else
if (*MAX < (*this)(x, y))
MAX = &((*this)(x, y));
return MAX;
}
template < class Type >
Type *CMatrix<Type>::MaxValueXYPos(int &xPos, int &yPos)
{
Type *MAX = NULL;
xPos = yPos = 0;
for (int y = 0; y < GetHeight(); y++)
for (int x = 0; x < GetWidth(); x++)
if (!MAX)
{
MAX = &((*this)(x, y));
xPos = x;
yPos = y;
}
else
if (*MAX < (*this)(x, y))
{
MAX = &((*this)(x, y));
xPos = x;
yPos = y;
}
return MAX;
}
template < class Type >
Type *CMatrix<Type>::MinInLine(int Line)
{
Type *MIN = NULL;
for (int i = 0; i < GetWidth(); i++)
if (!MIN)
MIN = &((*this)(i, Line));
else
if (*MIN > (*this)(i, Line))
MIN = &((*this)(i, Line));
return MIN;
}
template < class Type >
Type *CMatrix<Type>::MinValue()
{
Type *MIN = 0;
for (int y = 0; y < GetHeight(); y++)
for (int x = 0; x < GetWidth(); x++)
if (!MIN)
MIN = &((*this)(x, y));
else
if (*MIN > (*this)(x, y))
MIN = &((*this)(x, y));
return MIN;
}
template < class Type >
Type *CMatrix<Type>::MinValueXYPos(int &xPos, int &yPos)
{
Type *MIN = NULL;
xPos = yPos = 0;
for (int y = 0; y < GetHeight(); y++)
for (int x = 0; x < GetWidth(); x++)
if (!MIN)
{
xPos = x;
yPos = y;
MIN = &((*this)(x, y));
}
else
if (*MIN > (*this)(x, y))
{
xPos = x;
yPos = y;
MIN = &((*this)(x, y));
}
return MIN;
}
template < class Type >
Type CMatrix<Type>::SumInLine(int Line)
{
Type Sum = 0;
for (int i = 0; i < GetWidth(); i++)
Sum += Get(i, Line);
return Sum;
}
/*
template <class Type>
void CMatrix<Type>::Load(std::ifstream &in)
{
int w,h,sizeoftype;
in >> w;
in >> h;
Init(w,h);
Zero();
in >> sizeoftype;
for (int x = 0; x < m_Width; x++)
for (int y = 0; y < m_Height; y++)
in >> (*this)(x,y);
// in.read((char*)m_Data, m_Width*m_Height*sizeof(Type));
}
template <class Type>
void CMatrix<Type>::Save(std::ofstream &out)
{
out << m_Width << endl;
out << m_Height << endl;
out << (int)sizeof(Type) << endl;
for (int x = 0; x < m_Width; x++)
for (int y = 0; y < m_Height; y++)
{
out << (*this)(x,y) << endl;
}
// out.write((const char*)m_Data, m_Width*m_Height*sizeof(Type));
}
*/
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -