?? matrix.inl
字號:
template< class T >
Matrix<T>& Matrix<T>::Add(Matrix<T>& m)
{
if(!Matrix<T>::IsCompatible(*this, m))
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Matrix sizes are not compatible!");
}
for(int i=0;i<this->length;i++)
{
this->data[i] += m.data[i];
}
return *this;
}
template< class T >
Matrix<T>& Matrix<T>::Subtract(Matrix<T>& m)
{
if(!Matrix<T>::IsCompatible(*this, m))
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Matrix sizes are not compatible!");
}
for(int i=0;i<this->length;i++)
{
this->data[i] -= m.data[i];
}
return *this;
}
template< class T >
Matrix<T>& Matrix<T>::Multiply(Matrix<T>& m)
{
if(!Matrix<T>::IsCompatible(*this, m))
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Matrix sizes are not compatible!");
}
for(int i=0;i<this->length;i++)
{
this->data[i] *= m.data[i];
}
return *this;
}
template< class T >
Matrix<T>& Matrix<T>::Divide(Matrix<T>& m)
{
if(!Matrix<T>::IsCompatible(*this, m))
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Matrix sizes are not compatible!");
}
for(int i=0;i<this->length;i++)
{
if(m.data[i] != 0)
{
this->data[i] /= m.data[i];
}
else
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Divide by zero in matrix division!");
}
}
return *this;
}
// /////////////
// Arithmetic operation between "this" matrix and a value
// /////////////
template< class T >
Matrix<T>& Matrix<T>::Add(T v)
{
for(int i=0;i<this->length;i++)
{
this->data[i] += v;
}
return *this;
}
template< class T >
Matrix<T>& Matrix<T>::Subtract(T v)
{
for(int i=0;i<this->length;i++)
{
this->data[i] -= v;
}
return *this;
}
template< class T >
Matrix<T>& Matrix<T>::Multiply(T v)
{
for(int i=0;i<this->length;i++)
{
this->data[i] *= v;
}
return *this;
}
template< class T >
Matrix<T>& Matrix<T>::Divide(T v)
{
if(v == 0)
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Divide by zero in matrix by value division!");
}
for(int i=0;i<this->length;i++)
{
this->data[i] /= v;
}
return *this;
}
// /////////
// OPERATORS
// /////////
template< class T >
Matrix<T>& Matrix<T>::operator= (Matrix<T>& m)
{
if(&m != this)
{
ndims = m.ndims;
length = m.length;
xDim = m.xDim;
yDim = m.yDim;
data = m.data;
columns = m.columns;
delete clean;
clean = new (std::nothrow) Cleaner<T>(data, columns);
Utility::CheckPointer(clean);
}
return *this;
}
//template< class T >
//Matrix<T>& Matrix<T>::operator= (Array<T>& m)
//{
// ndims = 2;
// xDim = 0;
// yDim = 0;
// data = 0;
// columns = 0;
//
// if(m.ndims == 2){
// length = m.length;
// data = m.data;
// xDim = m.xDim;
// yDim = m.yDim;
//
// columns = new (std::nothrow) Vector<T>[Columns()];
// Utility::CheckPointer(columns);
// for(int i=0; i<Columns(); i++)
// {
// columns[i].Set(&(data[i*Rows()]), Rows());
// }
//
// delete clean;
// clean = new (std::nothrow) Cleaner<T>(data, columns);
// Utility::CheckPointer(clean);
// }
// else if(m.ndims > 0) // Convert to row matrux
// {
// length = m.length;
// data = m.data;
// xDim = length;
// yDim = 1;
//
// columns = new (std::nothrow) Vector<T>[1];
// Utility::CheckPointer(columns);
// columns[0].Set(&(data[0]),length);
//
// delete clean;
// clean = new (std::nothrow) Cleaner<T>(data, columns);
// Utility::CheckPointer(clean);
//
// Utility::Warning("Array (not of dimension 2) is converted to row Matrix. dimensionality information is lost.");
// }
//
//
// return *this;
//}
template< class T >
Matrix<T>& Matrix<T>::operator= (Vector<T>& m)
{
*this = (Matrix<T>)m;
return *this;
}
template< class T >
Matrix<T>& Matrix<T>::operator= (SubMatrix<T>& m)
{
if(xDim != m.xDim || yDim != m.yDim)
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("All Matrix and SubMatrix dimensions should agree!");
}
for(int i=0;i<m.xDim;i++)
{
for(int j=0;j<m.yDim;j++)
{
columns[i].data[j] = m[i][j];
}
}
return *this;
}
template< class T >
Matrix<T>& Matrix<T>::operator= (string str)
{
Matrix<T> temp(str);
*this = temp;
return *this;
}
// ////
//Unary operators
// ////
/// \brief Unary +. Does not have any effect. Returns the same matrix.
template< class T >
inline Matrix<T> Matrix<T>::operator+ ()
{
return *this;
}
/// \brief Unary -
template< class T >
inline Matrix<T> Matrix<T>::operator- ()
{
Matrix<T> temp(yDim, xDim);
for(int i=0;i<length;i++)
{
temp.data[i] = - data[i];
}
return temp;
}
template< class T >
inline Matrix<int> Matrix<T>::operator! ()
{
Matrix<int> temp(yDim, xDim);
for(int i=0;i<length;i++)
{
if(data[i] == 0)
{
temp.Data()[i] = 1;
}
else
{
temp.Data()[i] = 0;
}
}
return temp;
}
/// \brief Transpose ~
template< class T >
inline Matrix<T> Matrix<T>::operator~ ()
{
return Matrix<T>::Transpose(*this);
}
//---------------
/// \brief Matrix element access (sequential: column scan). Bounds are checked.
template< class T >
inline T& Matrix<T>::Elem(const int i)
{
if(i<0 || i>=length)
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Index outside bounds!");
}
return data[i];
}
/// \brief Matrix element access (sequential: column scan). Bounds are not checked.
template< class T >
inline T& Matrix<T>::ElemNC(const int i)
{
return data[i];
}
/// \brief Matrix element access (row,col). Bounds are checked.
template< class T >
inline T& Matrix<T>::Elem(const int j, const int i)
{
if(i<0 || i>=xDim || j<0 || j>=yDim)
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Index outside bounds!");
}
return columns[i].data[j];
}
/// \brief Matrix element access (row,col). Bounds are not checked.
template< class T >
inline T& Matrix<T>::ElemNC(const int j, const int i)
{
return columns[i].data[j];
}
/// \brief Matrix element access using coordinates (x,y). Bounds are checked.
template< class T >
inline T& Matrix<T>::Coor(const int i, const int j)
{
if(i<0 || i>=dims[0] || j<0 || j>=dims[1])
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Index outside bounds!");
}
return columns[i].data[j];
}
/// \brief Matrix element access using coordinates (x,y). Bounds are not checked.
template< class T >
inline T& Matrix<T>::CoorNC(const int i, const int j)
{
return columns[i].data[j];
}
//---------------
/// \brief Matrix element access (sequential: column scan). Bounds are checked (See ElemNC() for element access with no bounds check).
template< class T >
inline T& Matrix<T>::operator() (const int i)
{
if(i<0 || i>=length)
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Index outside bounds!");
}
return data[i];
}
/// \brief Matrix element access (row,col). Bounds are checked (See ElemNC() for element access with no bounds check).
template< class T >
inline T& Matrix<T>::operator() (const int j, const int i)
{
#ifdef CIMPL_BOUNDS_CHECK
if(i<0 || i>=xDim || j<0 || j>=yDim)
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Index outside bounds!");
}
#endif
return columns[i].data[j];
}
/// \brief Returns a pointer to the beginning of a column.
template< class T >
inline Vector<T>& Matrix<T>::operator[] (const int i)
{
return columns[i];
}
template< class T >
inline SubMatrix<T> Matrix<T>::operator() (const int row1, const int row2, const int col1, const int col2)
{
if(row1<0 || row1>=YDim() || row2<0 || row2>=YDim())
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Index outside bounds!");
}
if(row1 > row2)
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Second slice parameter cannot be less than the first parameter!");
}
if(col1<0 || col1>=XDim() || col2<0 || col2>=XDim())
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Index outside bounds!");
}
if(col1 > col2)
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Second slice parameter cannot be less than the first parameter!");
}
SubMatrix<T> temp;
temp.xDim = col2-col1+1;
temp.yDim = row2-row1+1;
temp.columns = new (std::nothrow) Vector<T>[temp.xDim];
Utility::CheckPointer(temp.columns);
temp.clean = new (std::nothrow) Cleaner<T>(temp.columns);
Utility::CheckPointer(temp.clean);
for(int j=col1; j<=col2; j++)
{
temp.columns[j-col1].Set(&(columns[j].data[row1]), row2-row1+1);
}
return temp;
}
template< class T >
SubMatrix<T> Matrix<T>::operator() (string str1, string str2)
{
int row1, row2, col1, col2;
vector<string> bounds1 = Utility::Split(str1, ":");
vector<string> bounds2 = Utility::Split(str2, ":");
if(str1 == ":")
{
row1 = 0;
row2 = yDim-1;
}
else if(bounds1.size() == 2)
{
row1 = Utility::ToInt(bounds1[0]);
row2 = Utility::ToInt(bounds1[1]);
}
else
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Incorrect slice argument. String cannot be parsed!");
}
if(str2 == ":")
{
col1 = 0;
col2 = xDim-1;
}
else if(bounds2.size() == 2)
{
col1 = Utility::ToInt(bounds2[0]);
col2 = Utility::ToInt(bounds2[1]);
}
else
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("Incorrect slice argument. String cannot be parsed!");
}
return this->operator()(row1, row2, col1, col2);
}
template< class T >
Vector<T> Matrix<T>::operator() (string str)
{
Vector<T> temp = (Vector<T>)*this;
return temp(str);
}
// ////
// Arithmetic operators
// ////
template< class T >
Matrix<T>& Matrix<T>::operator+= (Matrix<T>& m)
{
return this->Add(m);
}
template< class T >
Matrix<T>& Matrix<T>::operator-= (Matrix<T>& m)
{
return this->Subtract(m);
}
template< class T >
Matrix<T>& Matrix<T>::operator*= (Matrix<T>& m)
{
return this->Multiply(m);
}
template< class T >
Matrix<T>& Matrix<T>::operator/= (Matrix<T>& m)
{
return this->Divide(m);
}
template< class T >
Matrix<T>& Matrix<T>::operator+= (T v)
{
return this->Add(v);
}
template< class T >
Matrix<T>& Matrix<T>::operator-= (T v)
{
return this->Subtract(v);
}
template< class T >
Matrix<T>& Matrix<T>::operator*= (T v)
{
return this->Multiply(v);
}
template< class T >
Matrix<T>& Matrix<T>::operator/= (T v)
{
return this->Divide(v);
}
// TYPE CONVERSIONS
//template< class T >
//Matrix<T>::Matrix(Array<T> &m)
//{
// ndims = 2;
// xDim = 0;
// yDim = 0;
// data = 0;
// columns = 0;
//
// if(m.ndims == 2){
// length = m.length;
// data = m.data;
// xDim = m.XDim();
// yDim = m.YDim();
//
// columns = new (std::nothrow) Vector<T>[Columns()];
// Utility::CheckPointer(columns);
// for(int i=0; i<Columns(); i++)
// {
// columns[i].Set(&(data[i*Rows()]), Rows());
// }
// clean = new (std::nothrow) Cleaner<T>(data, columns);
// Utility::CheckPointer(clean);
//
// }
// else if(m.ndims > 0)
// {
// length = m.length;
// data = m.data;
// xDim = 1;
// yDim = length;
//
// columns = new (std::nothrow) Vector<T>[1];
// Utility::CheckPointer(columns);
// columns[0].Set(&(data[0]),length);
// clean = new (std::nothrow) Cleaner<T>(data, columns);
// Utility::CheckPointer(clean);
//
// if(ndims != 1)
// {
// Utility::Warning("Array (which was not of dimension 2) is converted to a Nx1 (column) Matrix. Dimensionality information is lost.");
// }
// }
//
//}
template< class T >
Matrix<T>::Matrix(Vector<T> &v)
{
ndims = 2;
length = v.length;
data = v.data;
xDim = 1;
yDim = length;
columns = new (std::nothrow) Vector<T>[1];
Utility::CheckPointer(columns);
columns[0].Set(&(data[0]),length);
clean = new (std::nothrow) Cleaner<T>(data, columns);
Utility::CheckPointer(clean);
}
template< class T >
Matrix<T>::Matrix(SubMatrix<T> &m)
{
if(m.yDim < 1 || m.xDim < 1)
{
cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
Utility::RunTimeError("All Matrix dimensions should be larger than 0!");
}
ndims = 2;
length = m.yDim*m.xDim;
xDim = m.xDim;
yDim = m.yDim;
data = new (std::nothrow) T[length];
Utility::CheckPointer(data);
columns = new (std::nothrow) Vector<T>[xDim];
Utility::CheckPointer(columns);
for(int i=0; i<xDim; i++)
{
columns[i].Set(&(data[i*yDim]), yDim);
}
clean = new (std::nothrow) Cleaner<T>(data, columns);
Utility::CheckPointer(clean);
for(int i=0;i<m.xDim;i++)
{
for(int j=0;j<m.yDim;j++)
{
columns[i].data[j] = m[i][j];
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -