📄 matrix5.h
字号:
#ifndef MATRIX5_H
#define MATRIX5_H
#include <iostream>
#include <stdexcept>
#include <iomanip>
using namespace std;
/**
Matrix exception class for indexing error.
*/
class MatrixIndexException : public out_of_range
{
public:
MatrixIndexException(int i);
private:
string format_message(int i);
};
/**
Matrix exception class for mismatched argument error.
*/
class MatrixMismatchException : public invalid_argument
{
public:
MatrixMismatchException();
};
/**
This class describes a row in a matrix.
*/
template<typename T> class Matrix;
template<typename T>
class MatrixRow
{
public:
/**
Remembers a row for a given matrix.
@param m a pointer to the matrix
@param s the size of the row
*/
MatrixRow(Matrix<T>* m, int s);
/**
Accesses a row element.
@param j the column index
@return a reference to the element with the given index
*/
T& operator[](int j) throw (MatrixIndexException);
private:
Matrix<T>* mat;
int i;
};
/**
This class describes a row in a constant matrix.
*/
template<typename T>
class ConstMatrixRow
{
public:
/**
Constructs a row with a given start and size.
@param m a pointer to the matrix
@param s the size of the row
*/
ConstMatrixRow(const Matrix<T>* m, int s);
/**
Accesses a row element.
@param j the column index
@return a reference to the element with the given index
*/
const T& operator[](int j) const throw (MatrixIndexException);
private:
const Matrix<T>* mat;
int i;
};
/**
This class describes a matrix with arbitrary rows and columns.
*/
template <typename T>
class Matrix
{
public:
/**
Constructs a matrix of a given size.
*/
Matrix(int r, int c);
/**
The big three
*/
Matrix(const Matrix<T>& other);
Matrix<T>& operator=(const Matrix<T>& other);
~Matrix();
/**
Gets the number of rows of this matrix.
@return the number of rows
*/
int get_rows() const;
/**
Gets the number of columns of this matrix.
@return the number of columns
*/
int get_columns() const;
/**
Accesses a matrix element.
@param i the row index
@param j the column index
@return a reference to the element with the given indexes
*/
T& operator()(int i, int j) throw (MatrixIndexException);
/**
Accesses a matrix element.
@param i the row index
@param j the column index
@return the element with the given indexes
*/
T operator()(int i, int j) const throw (MatrixIndexException);
/**
Accesses a matrix row.
@param i the row index
@return the row with the given index
*/
MatrixRow<T> operator[](int i) throw (MatrixIndexException);
/**
Accesses a matrix row.
@param i the row index
@return the row with the given index
*/
ConstMatrixRow<T> operator[](int i) const
throw (MatrixIndexException);
/**
Computes the matrix sum.
@param right another matrix
@return the updated matrix
*/
Matrix<T>& operator+=(const Matrix<T>& right)
throw (MatrixMismatchException);
private:
/**
Copies another matrix into this matrix.
@param other the other matrix
*/
void copy(const Matrix<T>& other);
/**
Frees the memory for this matrix.
*/
void free();
int rows;
int columns;
T* elements;
};
/**
Computes the matrix sum.
@param right another matrix
@return the sum of two matrices
*/
template<typename T>
Matrix<T> operator+(const Matrix<T>& left, const Matrix<T>& right)
throw (MatrixMismatchException);
/**
Computes the matrix product.
@param right another matrix
@return the product of two matrices
*/
template<typename T>
Matrix<T> operator*(const Matrix<T>& left, const Matrix<T>& right)
throw (MatrixMismatchException);
/**
Computes the scalar product of a scalar value and a matrix.
@param left a scalar value
@param right a matrix
@return the product of the given value and the given matrix
*/
template<typename T>
Matrix<T> operator*(T left, const Matrix<T>& right);
/**
Computes the scalar product of a matrix and a scalar value.
@param right a scalar value
@return the product of this matrix and the given value
*/
template<typename T>
Matrix<T> operator*(const Matrix<T>& left, T right);
/**
Prints a matrix to an output stream.
@param left an output stream
@param right a matrix
@return the given output stream
*/
template<typename T>
ostream& operator<<(ostream& left, const Matrix<T>& right);
inline MatrixIndexException::MatrixIndexException(int idx)
: out_of_range(format_message(idx)) {}
inline MatrixMismatchException::MatrixMismatchException()
: invalid_argument("Matrix arguments have incompatible sizes") {}
template<typename T>
inline Matrix<T>::Matrix(const Matrix<T>& other)
{
copy(other);
}
template<typename T>
inline Matrix<T>::~Matrix()
{
free();
}
template<typename T>
inline int Matrix<T>::get_rows() const
{
return rows;
}
template<typename T>
inline int Matrix<T>::get_columns() const
{
return columns;
}
template<typename T>
inline void Matrix<T>::free()
{
delete[] elements;
}
template<typename T>
inline MatrixRow<T> Matrix<T>::operator[](int i)
throw (MatrixIndexException)
{
return MatrixRow<T>(this, i);
}
template<typename T>
inline ConstMatrixRow<T> Matrix<T>::operator[](int i) const
throw (MatrixIndexException)
{
return ConstMatrixRow<T>(this, i);
}
template<typename T>
inline MatrixRow<T>::MatrixRow(Matrix<T>* m, int s) : mat(m), i(s) { }
template<typename T>
inline T& MatrixRow<T>::operator[](int j) throw (MatrixIndexException)
{
return (*mat)(i,j);
}
template<typename T>
inline ConstMatrixRow<T>::ConstMatrixRow(const Matrix<T>* m, int s)
: mat(m), i(s) { }
template<typename T>
inline const T& ConstMatrixRow<T>::operator[](int j) const
throw (MatrixIndexException)
{
return (*mat)(i, j);
}
template<typename T>
inline Matrix<T> operator*(T left, const Matrix<T>& right)
{
return right * left;
}
template<typename T>
Matrix<T>::Matrix(int r, int c)
: rows(r), columns(c), elements(new T[rows * columns]) {}
template<typename T>
Matrix<T>& Matrix<T>::operator=(const Matrix<T>& other)
{
if (this != &other)
{
free();
copy(other);
}
return *this;
}
template<typename T>
void Matrix<T>::copy(const Matrix<T>& other)
{
rows = other.rows;
columns = other.columns;
elements = new T[rows * columns];
for (int i = 0; i < rows * columns; i++)
elements[i] = other.elements[i];
}
template<typename T>
T& Matrix<T>::operator()(int i, int j) throw (MatrixIndexException)
{
if (i < 0 || i >= rows)
throw MatrixIndexException(i);
if (j < 0 || j >= columns)
throw MatrixIndexException(j);
return elements[i * get_columns() + j];
}
template<typename T>
T Matrix<T>::operator()(int i, int j) const throw (MatrixIndexException)
{
if (i < 0 || i >= rows)
throw MatrixIndexException(i);
if (j < 0 || j >= columns)
throw MatrixIndexException(j);
return elements[i * get_columns() + j];
}
template<typename T>
Matrix<T>& Matrix<T>::operator+=(const Matrix<T>& right)
throw (MatrixMismatchException)
{
if (rows != right.rows || columns != right.columns)
throw MatrixMismatchException();
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
(*this)(i, j) += right(i, j);
return *this;
}
template<typename T>
Matrix<T> operator+(const Matrix<T>& left, const Matrix<T>& right)
throw (MatrixMismatchException)
{
Matrix<T> result = left;
result += right;
return result;
}
template<typename T>
Matrix<T> operator*(const Matrix<T>& left, const Matrix<T>& right)
throw (MatrixMismatchException)
{
if (left.get_columns() != right.get_rows())
throw MatrixMismatchException();
Matrix<T> result(left.get_rows(), right.get_columns());
for (int i = 0; i < left.get_rows(); i++)
for (int j = 0; j < right.get_columns(); j++)
for (int k = 0; k < left.get_columns(); k++)
result(i, j) += left(i, k) * right(k, j);
return result;
}
template<typename T>
Matrix<T> operator*(const Matrix<T>& left, T right)
{
Matrix<T> result(left);
for (int i = 0; i < result.get_rows(); i++)
for (int j = 0; j < result.get_columns(); j++)
result(i, j) *= right;
return result;
}
template<typename T>
ostream& operator<<(ostream& left, const Matrix<T>& right)
{
const int WIDTH = 10;
for (int i = 0; i < right.get_rows(); i++)
{
for (int j = 0; j < right.get_columns(); j++)
left << setw(WIDTH) << right(i, j);
left << "\n";
}
return left;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -