自己尝试以模板的形式写了一个基础矩阵类,提供了矩阵运算的基本方法,包括加减乘除、转置、求行列式、求逆,后续还会进行陆续的补充,下面添上源码,可能存在一些不足之处,希望能得到大家的建议。
//头文件Matrix.h
/*
*@copyright yyh 2017
*/
#pragma once
#include "stdafx.h"
#define CHUDENG 0 //初等变换
#define BANSUI 1//伴随阵
#define REC 0//递归求行列式 速度太慢
#define TRIA 1//上三角求行列式
template<typename T=double>
class Matrix//:private myMat
{
private:
typedef T value_type;
T** data;//存放数据
int cols;//矩阵列
int rows;//矩阵行
public:
Matrix();
Matrix(const int &rows, const int &cols);//构造大小为rows*cols的矩阵
Matrix(T *p, int rows, int cols);//用二维数组来构造矩阵
Matrix(const Matrix &m1, const Matrix &m2);//合并两个矩阵
Matrix(const Matrix &m);//深拷贝构造函数
void showMatrix();//输出显示整个矩阵
void zeros();//初始化为0矩阵
double cofactor(int i, int j);//求i,j处的代数余子式
bool unit();//初始化为单位阵
void exchangeRow(const int &i1, const int &i2);//交换矩阵两行
T* operator[](const int &i);//通过下标访问数矩阵元素
Matrix& operator=(const Matrix & m);//重载赋值运算符实现深拷贝
Matrix Trans();//矩阵转置
double det(int method=TRIA);//求矩阵行列式
Matrix operator*(Matrix & m);//矩阵相乘
Matrix operator+(Matrix & m);//矩阵相加
Matrix operator-(Matrix & m);//矩阵相减
template<typename T, typename S> friend Matrix operator*(Matrix & m, S num);//矩阵乘以一个数
template<typename T, typename S> friend Matrix operator*(S num,Matrix & m );//矩阵乘以一个数
template<typename T, typename S> friend Matrix operator/(Matrix & m, S num);//矩阵除以一个数
Matrix inverse(int method=CHUDENG);//矩阵求逆
~Matrix();
};
cpp文件
#include "stdafx.h"
#include "Matrix.h"
//构造函数
template<typename T>
Matrix::Matrix()
{
data = NULL;
rows = 0;
cols = 0;
}
template<typename T>
Matrix::Matrix(const int &rows, const int &cols)
{
data = new T* [rows];
for (int i = 0; i < rows; i++)
data[i] = new T[cols];
this->cols = cols;
this->rows = rows;
}
//用二维数组来构造矩阵
template<typename T>
Matrix::Matrix(T *p, int rows, int cols)
{
this->rows = rows;
this->cols = cols;
data = new T*[rows];
for (int i = 0; i < rows; i++)
{
data[i] = new T[cols];
memcpy(data[i], p + i*cols, sizeof(T)*cols);
}
}
template<typename T>
Matrix::Matrix(const Matrix &m){
this->cols = m.cols;
this->rows = m.rows;
data = new T*[rows];
for (int i = 0; i < rows; i++)
{
data[i] = new T[cols];
memcpy(data[i], m.data[i], sizeof(T)*cols);
}
}
//矩阵合并构造函数
template<typename T>
Matrix::Matrix(const Matrix &m1, const Matrix &m2)
{
if (m1.rows != m2.rows) exit(0);
cols = m1.cols + m2.cols;
rows = m1.rows;
data = new T*[rows];
for (int i = 0; i < rows; i++)
{
data[i] = new T[cols];
memcpy(data[i], m1.data[i], sizeof(T)*m1.cols);
memcpy(data[i]+ m1.cols, m2.data[i], sizeof(T)*m2.cols);
}
}
//输出显示整个矩阵
template<typename T>
void Matrix::showMatrix(){
//控制台下有效
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
cout << data[i][j] << " ";
cout << endl;
}
}
//重载赋值运算符
template<typename T>
Matrix& Matrix::operator=(const Matrix & m)
{
for (int i = 0; i < rows; i++)
delete[] data[i];
delete[]data;
this->cols = m.cols;
this->rows = m.rows;
data = new T*[rows];
for (int i = 0; i < rows; i++)
{
data[i] = new T[cols];
memcpy(data[i], m.data[i], sizeof(T)*cols);
}
return *this;
}
template<typename T>
T* Matrix::operator[](const int &i){
return data[i];
}
//0矩阵
template<typename T>
void Matrix::zeros(){
for (int i = 0; i < rows;i++)
for (int j = 0; j < cols; j++)
data[i][j] = 0;
}
//单位阵
template<typename T>
bool Matrix::unit(){
if (rows != cols) return false;
this->zeros();
for (int i = 0; i < rows; i++)
data[i][i] = 1;
return true;
}
//交换矩阵的两行
template<typename T>
void Matrix::exchangeRow(const int &i1, const int &i2)
{
T *tmp = new T[cols];
memcpy(tmp, data[i1], sizeof(T)*cols);
memcpy(data[i1], data[i2], sizeof(T)*cols);
memcpy(data[i2], tmp, sizeof(T)*cols);
delete[]tmp;
}
//矩阵转置
template<typename T>
Matrix Matrix::Trans(){
Matrix m(cols, rows);
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
m[i][j] = this->data[j][i];
return m;
}
//求矩阵行列式
template<typename T>
double Matrix::det(int method){
if (rows != cols) exit(0);
double result=0;
int q = 1;
if (cols == 1){
result = data[0][0];
return result;
}
if (method == REC)
{
for (int i = 0; i < cols; i++)
{
Matrix M(cols - 1, cols - 1);//代数余子式
for (int u = 0; u < M.rows; u++)
for (int v = 0; v < M.cols; v++)
{
if (v < i)
M[u][v] = data[u + 1][v];
else
M[u][v] = data[u + 1][v + 1];
}
if (i % 2 == 0) q = 1; else q = -1;
if (data[0][i] == 0) continue;
else
result += data[0][i] * q*M.det();//递归求行列式
}
return result;
}
if (method == TRIA)
{
Matrix M(*this);
for (int i = 0; i < rows; i++)
{
if (M.data[i][i] == 0)
{
for (int j = i + 1; j < rows; j++)
{
if (M.data[j][i] != 0)
{
M.exchangeRow(i, j);
q = -1;
goto outer;
}
}
result = 0;
return result;
}
outer:
for (int u = i+1; u < rows; u++)
{
if (M.data[u][i] == 0) continue;
for (int v = i + 1; v < cols; v++)
{
M.data[u][v] = M.data[u][v] - M.data[u][i] / M.data[i][i] * M.data[i][v];
}
}
}
result = 1;
for (int i = 0; i < rows; i++)
{
result *= M.data[i][i];
}
return result;
}
}
//矩阵相乘
template<typename T>
Matrix Matrix::operator*(Matrix & m){
if (cols != m.rows) exit(0);
Matrix result(rows,m.cols);
for (int i = 0; i < result.rows; i++)
for (int j = 0; j < result.cols; j++)
{
result[i][j] = 0;
for (int k = 0; k < cols; k++)
result[i][j] += data[i][k] * m[k][j];
}
return result;
}
//矩阵乘以一个数
template<typename T,typename S>
Matrix operator*(Matrix & m, S num)
{
Matrix result(m.rows, m.cols);
for (int i = 0; i < m.rows;i++)
for (int j = 0; j < m.cols; j++)
{
result.data[i][j] = num*m.data[i][j];
}
return result;
}
//矩阵乘以一个数
template<typename T, typename S>
Matrix operator*(S num,Matrix & m)
{
return m*num;
}
//矩阵除以一个数
template<typename T, typename S>
Matrix operator/(Matrix & m, S num)
{
Matrix result(m.rows, m.cols);
for (int i = 0; i < m.rows; i++)
for (int j = 0; j < m.cols; j++)
{
result.data[i][j] = m.data[i][j]/num;
}
return result;
}
//矩阵相加
template<typename T>
Matrix Matrix::operator+(Matrix & m){
if (cols != m.cols || rows != m.rows) exit(0);
Matrix result(rows,cols);
for (int i = 0; i < result.rows; i++)
for (int j = 0; j < result.cols; j++)
{
result[i][j] = data[i][j] + m[i][j];
}
return result;
}
//矩阵相减
template<typename T>
Matrix Matrix::operator-(Matrix & m){
if (cols != m.cols || rows != m.rows) exit(0);
Matrix result(rows, cols);
for (int i = 0; i < result.rows; i++)
for (int j = 0; j < result.cols; j++)
{
result[i][j]= data[i][j] - m[i][j];
}
return result;
}
//矩阵求逆
template<typename T>
Matrix Matrix::inverse(int method)
{
if (rows != cols) exit(0);
Matrix result(rows,cols);
//初等行变换求逆矩阵
if (method == CHUDENG)
{
Matrix m(rows, cols);
m.unit();
Matrix expand_Matrix(*this, m);//定义扩展矩阵,左边为原矩阵,右边为单位阵
//调整矩阵
for (int i = 0; i < rows; i++)
{
if (expand_Matrix[i][i] == 0)//如果某行对角线元素等于0,搜索其它行不为0的元素的值
{
for (int j = i + 1; j < rows; j++)
{
if (expand_Matrix[j][i] != 0)//交换这两行
{
expand_Matrix.exchangeRow(i, j);
goto outer;
}
}
exit(0);//矩阵行列式为0,程序退出
}
outer:
for (int j = i+1; j < expand_Matrix.cols; j++)
{
expand_Matrix[i][j] /= expand_Matrix[i][i];
}
expand_Matrix[i][i] = 1;
//把其它行在该列的值变为0
for (int t = 0; t < rows; t++)
{
if (t == i) continue;
for (int j = i + 1; j < expand_Matrix.cols; j++)
{
expand_Matrix[t][j] = expand_Matrix[t][j] - expand_Matrix[i][j] * expand_Matrix[t][i];
}
expand_Matrix[t][i] = 0;
}
}
for (int i = 0; i < rows;i++)
for (int j = 0; j < cols; j++)
{
result[i][j] = expand_Matrix[i][j + cols];
}
return result;
}
//伴随矩阵法求逆
if (method == BANSUI)
{
double D = this->det();
if (D == 0) exit(0);
for (int i = 0; i < rows;i++)
for (int j = 0; j < cols; j++)
{
result[i][j] = this->cofactor(j, i) / D;
}
return result;
}
}
//求i,j处的代数余子式
template<typename T>
double Matrix::cofactor(int i, int j)
{
if (rows != cols) exit(0);
int p = 0;
if (p % 2 == 0) p = 1; else p = -1;
Matrix M(rows - 1, cols - 1);//代数余子式
for (int u = 0; u < M.rows; u++)
for (int v = 0; v < M.cols; v++)
{
if (u < i&&v< j)
M[u][v] = data[u][v];
else if (u=j)
M[u][v] = data[u][v + 1];
else if (u>=i&&v1][v];
else
M[u][v] = data[u + 1][v+1];
}
return M.det()*p;
}
//析构函数
template<typename T>
Matrix::~Matrix()
{
for (int i = 0; i < rows; i++)
delete[] data[i];
delete[]data;
}