📄 matrix.h
字号:
#ifndef NDEBUG
if(numberOfRows != numberOfColumns)
{
std::cout << std::endl
<< "Flood Error: Matrix Template." << std::endl
<< "setToIdentity(void) method." << std::endl
<< "Matrix must be square." << std::endl
<< std::endl;
exit(1);
}
#endif
for(int i = 0; i < numberOfRows; i++)
{
for(int j = 0; j < numberOfColumns; j++)
{
if(i==j)
{
matrix[i][j] = 1;
}
else
{
matrix[i][j] = 0;
}
}
}
}
// Type calculateDeterminant(void) method
/// This method returns the determinant of a square matrix.
template <class Type>
inline Type Matrix<Type>::calculateDeterminant(void)
{
// Control sentence (if debug)
#ifndef NDEBUG
if(numberOfRows != numberOfColumns)
{
std::cerr << std::endl
<< "Flood Error: Matrix Template." << std::endl
<< "calculateDeterminant(void) method." << std::endl
<< "Matrix must be square." << std::endl
<< std::endl;
exit(1);
}
#endif
Type determinant = 0;
if(numberOfRows == 0)
{
std::cerr << std::endl
<< "Flood Error: Matrix Template." << std::endl
<< "calculateDeterminant(void) method." << std::endl
<< "Size of matrix is zero." << std::endl
<< std::endl;
exit(1);
}
else if(numberOfRows == 1)
{
determinant = matrix[0][0];
}
else if(numberOfRows == 2)
{
determinant = matrix[0][0]*matrix[1][1] - matrix[1][0]*matrix[0][1];
}
else
{
for(int j1 = 0; j1 < numberOfRows; j1++)
{
Matrix<double> subMatrix(numberOfRows-1, numberOfColumns-1, 0.0);
for(int i = 1; i < numberOfRows; i++)
{
int j2 = 0;
for(int j = 0; j < numberOfColumns; j++)
{
if(j == j1)
{
continue;
}
subMatrix[i-1][j2] = matrix[i][j];
j2++;
}
}
determinant += pow(-1.0, j1+2.0)*matrix[0][j1]*subMatrix.calculateDeterminant();
}
}
return(determinant);
}
// Matrix<Type> calculateInverse(void) method
/// This method returns the inverse of a square matrix.
/// An error message is printed if the matrix is singular.
template <class Type>
inline Matrix<Type> Matrix<Type>::calculateInverse(void)
{
// Control sentence (if debug)
#ifndef NDEBUG
if(numberOfRows != numberOfColumns)
{
std::cerr << std::endl
<< "Flood Error: Matrix Template." << std::endl
<< "calculateDeterminant(void) method." << std::endl
<< "Matrix must be square." << std::endl
<< std::endl;
exit(1);
}
#endif
double determinant = calculateDeterminant();
if(determinant == 0.0)
{
std::cerr << std::endl
<< "Flood Error: Matrix Template." << std::endl
<< "calculateInverse(void) method." << std::endl
<< "Matrix is singular." << std::endl
<< std::endl;
exit(1);
}
Matrix<Type> inverse(numberOfRows, numberOfColumns);
// Get cofactor matrix
Matrix<double> cofactor(numberOfRows, numberOfColumns, 0.0);
Matrix<double> c(numberOfRows-1, numberOfColumns-1, 0.0);
for(int j = 0; j < numberOfRows; j++)
{
for(int i = 0; i < numberOfRows; i++)
{
// Form the adjoint a[i][j]
int i1 = 0;
for(int ii = 0; ii < numberOfRows; ii++)
{
if(ii == i)
{
continue;
}
int j1 = 0;
for(int jj = 0; jj < numberOfRows; jj++)
{
if(jj == j)
{
continue;
}
c[i1][j1] = matrix[ii][jj];
j1++;
}
i1++;
}
double determinant = c.calculateDeterminant();
cofactor[i][j] = pow(-1.0, i+j+2.0)*determinant;
}
}
// Adjoint matrix is the transpose of cofactor matrix
Matrix<double> adjoint(numberOfRows, numberOfColumns, 0.0);
for(int i = 0; i < numberOfRows; i++)
{
for(int j = 0; j < numberOfRows; j++)
{
adjoint[i][j] = cofactor[j][i];
}
}
// Inverse matrix is adjoint matrix divided by matrix determinant
for(int i = 0; i < numberOfRows; i++)
{
for(int j = 0; j < numberOfRows; j++)
{
inverse[i][j] = adjoint[i][j]/determinant;
}
}
return(inverse);
}
// Matrix<Type> operator + (Type)
/// Sum matrix+scalar arithmetic operator.
template <typename Type>
inline Matrix<Type> Matrix<Type>::operator + (Type scalar)
{
Matrix<Type> sum(numberOfRows, numberOfColumns);
for(int i = 0; i < numberOfRows; i++)
{
for(int j = 0; j < numberOfColumns; j++)
{
sum[i][j] = matrix[i][j] + scalar;
}
}
return(sum);
}
// Matrix<Type> operator + (Matrix<Type>)
/// Sum matrix+matrix arithmetic operator.
template <typename Type>
inline Matrix<Type> Matrix<Type>::operator + (Matrix<Type> otherMatrix)
{
// Control sentence (if debug)
#ifndef NDEBUG
int otherNumberOfRows = otherMatrix.getNumberOfRows();
int otherNumberOfColumns = otherMatrix.getNumberOfColumns();
if(otherNumberOfRows != numberOfRows || otherNumberOfColumns != numberOfColumns)
{
std::cerr << std::endl
<< "Flood Error: Matrix Template." << std::endl
<< "Matrix<Type> operator + (Matrix<Type>)." << std::endl
<< "Both matrix sizes must be the same." << std::endl
<< std::endl;
exit(1);
}
#endif
Matrix<Type> sum(numberOfRows, numberOfColumns);
for(int i = 0; i < numberOfRows; i++)
{
for(int j = 0; j < numberOfColumns; j++)
{
sum[i][j] = matrix[i][j] + otherMatrix[i][j];
}
}
return(sum);
}
// Matrix<Type> operator - (Type)
/// Difference matrix-scalar arithmetic operator.
template <typename Type>
inline Matrix<Type> Matrix<Type>::operator - (Type scalar)
{
Matrix<Type> difference(numberOfRows, numberOfColumns);
for(int i = 0; i < numberOfRows; i++)
{
for(int j = 0; j < numberOfColumns; j++)
{
difference[i][j] = matrix[i][j] - scalar;
}
}
return(difference);
}
// Matrix<Type> operator - (Matrix<Type>)
/// Difference matrix-matrix arithmetic operator.
template <typename Type>
inline Matrix<Type> Matrix<Type>::operator - (Matrix<Type> otherMatrix)
{
// Control sentence (if debug)
#ifndef NDEBUG
int otherNumberOfRows = otherMatrix.getNumberOfRows();
int otherNumberOfColumns = otherMatrix.getNumberOfColumns();
if(otherNumberOfRows != numberOfRows || otherNumberOfColumns != numberOfColumns)
{
std::cerr << std::endl
<< "Flood Error: Matrix Template." << std::endl
<< "Matrix<Type> operator - (Type)." << std::endl
<< "Both matrix sizes must be the same." << std::endl
<< std::endl;
exit(1);
}
#endif
Matrix<Type> difference(numberOfRows, numberOfColumns);
for(int i = 0; i < numberOfRows; i++)
{
for(int j = 0; j < numberOfColumns; j++)
{
difference[i][j] = matrix[i][j] - otherMatrix[i][j];
}
}
return(difference);
}
// Matrix<Type> operator * (Type)
/// Product matrix*scalar arithmetic operator.
template <typename Type>
inline Matrix<Type> Matrix<Type>::operator * (Type scalar)
{
Matrix<Type> product(numberOfRows, numberOfColumns);
for(int i = 0; i < numberOfRows; i++)
{
for(int j = 0; j < numberOfColumns; j++)
{
product[i][j] = matrix[i][j]*scalar;
}
}
return(product);
}
// Vector<Type> operator * (Vector<Type>)
/// Product matrix*vector arithmetic operator.
template <typename Type>
inline Vector<Type> Matrix<Type>::operator * (Vector<Type> vector)
{
// Control sentence (if debug)
#ifndef NDEBUG
int size = vector.getSize();
if(size != numberOfColumns)
{
std::cerr << std::endl
<< "Flood Error: Matrix Template." << std::endl
<< "Vector<Type> operator * (Vector<Type>)." << std::endl
<< "Vector size must be equal to matrix number of columns."
<< std::endl
<< std::endl;
exit(1);
}
#endif
// Calculate matrix-vector poduct
Vector<Type> product(numberOfRows);
for(int i = 0; i < numberOfRows; i++)
{
product[i] = 0;
for(int j = 0; j < numberOfColumns; j++)
{
product[i] += vector[j]*matrix[i][j];
}
}
return(product);
}
// Matrix<Type> operator * (Matrix<Type>)
/// Product matrix*matrix arithmetic operator.
template <typename Type>
inline Matrix<Type> Matrix<Type>::operator * (Matrix<Type> otherMatrix)
{
// Control sentence
int otherNumberOfColumns = otherMatrix.getNumberOfColumns();
Matrix<Type> product(numberOfRows, otherNumberOfColumns, 0.0);
for(int i = 0; i < numberOfRows; i++)
{
for(int j = 0; j < otherNumberOfColumns; j++)
{
for(int k = 0; k < numberOfColumns; k++)
{
product[i][j] += matrix[i][k]*otherMatrix[k][j];
}
}
}
return(product);
}
// Matrix<Type> operator / (Type)
/// Cocient Matrix/scalar arithmetic operator.
template <typename Type>
inline Matrix<Type> Matrix<Type>::operator / (Type scalar)
{
Matrix<Type> cocient(numberOfRows, numberOfColumns);
for(int i = 0; i < numberOfRows; i++)
{
for(int j = 0; j < numberOfColumns; j++)
{
cocient[i][j] = matrix[i][j]/scalar;
}
}
return(cocient);
}
// DESTRUCTOR
/// Destructor.
template <class Type>
Matrix<Type>::~Matrix()
{
if(matrix != 0)
{
delete[] (matrix[0]);
delete[] (matrix);
}
}
/// This method re-writes the input operator >> for the Vector template.
template<typename Type>
std::istream& operator>>(std::istream& is, Matrix<Type>& m)
{
int numberOfRows = m.getNumberOfRows();
int numberOfColumns = m.getNumberOfColumns();
for(int i = 0; i < numberOfRows; i++)
{
for(int j = 0; j < numberOfColumns; j++)
{
is >> m[i][j];
}
}
return(is);
}
// Output operator
/// This method re-writes the output operator << for the Vector template.
template<typename Type>
std::ostream& operator<<(std::ostream& os, Matrix<Type>& m)
{
int numberOfRows = m.getNumberOfRows();
int numberOfColumns = m.getNumberOfColumns();
for(int i = 0; i < numberOfRows; i++)
{
for(int j = 0; j < numberOfColumns; j++)
{
os << m[i][j] << " ";
}
os << std::endl;
}
return(os);
}
// void load(char*) method
/// This method loads the numbers of rows and columns and the values of the matrix from a data file.
///
/// @param filename Filename.
template <class Type>
inline void Matrix<Type>::load(char* filename)
{
std::fstream file;
// Open file
file.open(filename, std::ios::in);
if(!file.is_open())
{
std::cerr << std::endl
<< "Flood Error: Matrix template." << std::endl
<< "void load(char*) method." << std::endl
<< "Cannot open matrix data file." << std::endl
<< std::endl;
exit(1);
}
else
{
std::cout << std::endl
<< "Loading matrix from data file..." << std::endl;
}
// Read file
file >> numberOfRows;
file >> numberOfColumns;
resize(numberOfRows, numberOfColumns);
file >> matrix;
// Close file
file.close();
}
// void save(char*) method
/// This method saves the numbers of rows and columns and the values of the matrix to a data file.
///
/// @param filename Filename.
template <class Type>
inline void Matrix<Type>::save(char* filename)
{
std::fstream file;
// Open file
file.open(filename, std::ios::out);
if(!file.is_open())
{
std::cerr << std::endl
<< "Flood Error: Matrix template." << std::endl
<< "void save(char*) method." << std::endl
<< "Cannot open matrix data file." << std::endl
<< std::endl;
exit(1);
}
else
{
std::cout << std::endl
<< "Saving matrix to data file..."
<< std::endl;
}
// Write file
file << numberOfRows << " " << numberOfColumns << std::endl;
for(int i = 0; i < numberOfRows; i++)
{
for(int j = 0; j < numberOfColumns; j++)
{
file << matrix[i][j] << " ";
}
file << std::endl;
}
// Close file
file.close();
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -