c++手写矩阵类

c++手写矩阵类实现矩阵的运算,只做理解用,实际工程还是用现成的库。

类实现的矩阵功能有:

  1. 矩阵的复制
  2. 将数组的值传给矩阵
  3. 矩阵的+ - x /操作
  4. 求解线性方程组Ax=b
  5. 求矩阵的行列式
  6. 求矩阵的逆矩阵
  7. 制造一个单位矩阵
  8. 矩阵转置的实现,且不改变矩阵
  9. 高斯消元法
     

github地址


//main.cpp
/*
author: cclplus
date:2020/10/25
if you think it is necessary to reward me,
my qq number is 641208111
*/
//#include 
//#include //输入输出接口
#include 
#include 

using namespace std;
int main()
{
	for(int i=0;i<10;i++)
	{
		cout<< i;
		printf("\n");//换行
	}
	cout << "\n";//换行
	cout << "按任意键继续……";
	cout << "\n";
	cout << "按任意键继续……";
	/*Matrix A = Matrix(3, 1);
	cin >> A;
	A.Show();
	Matrix b = Matrix(3,2,1.5);
	cin >> b;
	b.Show();*/
	
	Matrix C = Matrix(3, 3, 2);
	Matrix D = Matrix(3, 3, 4);
	Matrix S = Matrix::Hadamard(C, D);
	//C.Show();
	//D.Show();
	//S.Show();
	cin.clear();
	cin.sync();
	cin.get();
	/*
	Matrix A = Matrix(3, 3);
	cin >> A;
	Matrix b = Matrix(3, 1);
	cin >> b;
	Matrix x = Matrix::Solve(A, b);
	x.Show();
	*/
	
	system("pause");
}                                                                                                                                                                                                                                                                     

 

/*
author: cclplus
date:2020/10/25
if you think it is necessary to reward me,
my qq number is 641208111
*/
//matrix.h
#ifndef __MATRIX_CLL_H__
#define __MATRIX_CCL_H__
#include "pch.h"

class Matrix {
private:
	int rows_num, cols_num;
	double **p;
	void initialize();//初始化矩阵

public:
	Matrix(int, int);
	Matrix(int, int, double);//预配分空间
	virtual ~Matrix();//析构函数应当是虚函数,除非此类不用做基类
	Matrix& operator=(const Matrix&);//矩阵的复制
	Matrix& operator=(double *);//将数组的值传给矩阵
	Matrix& operator+=(const Matrix&);//矩阵的+=操作
	Matrix& operator-=(const Matrix&);//-=
	Matrix& operator*=(const Matrix&);//*=
	Matrix operator*(const Matrix & m)const;
	static Matrix Hadamard(const Matrix & m, const Matrix & n);
	static Matrix Solve(const Matrix&, const Matrix&);//求解线性方程组Ax=b
	void Show() const;//矩阵显示
	void swapRows(int, int);
	double det();//求矩阵的行列式
	double Point(int i, int j) const;
	static Matrix inv(Matrix);//求矩阵的逆矩阵
	static Matrix eye(int);//制造一个单位矩阵
	int row() const;
	int col() const;
	static Matrix T(const Matrix & m);//矩阵转置的实现,且不改变矩阵
	Matrix gaussianEliminate();//高斯消元法
	friend std::istream& operator>>(std::istream&, Matrix&);//实现矩阵的输入
};


#endif
/*
author: cclplus
date:2020/10/25
if you think it is necessary to reward me,
my qq number is 641208111
*/
//matrix.cpp 
#include "matrix.h"
using namespace std;
const double EPS = 1e-10;
void Matrix::initialize()
{
	p = new double*[rows_num];//分配rows_num个指针
	int i;
	for (i = 0; i < rows_num; ++i) {
		p[i] = new double[cols_num];//为p[i]进行动态内存分配,大小为cols
	}
}
//声明一个全0矩阵
Matrix::Matrix(int rows, int cols)
{
	rows_num = rows;
	cols_num = cols;
	initialize();
	for (int i = 0; i < rows_num; i++) {
		for (int j = 0; j < cols_num; j++) {
			p[i][j] = 0;
		}
	}
}
//声明一个值全部为value的矩阵
Matrix::Matrix(int rows,int cols, double value)
{
	rows_num = rows;
	cols_num = cols;
	initialize();
	for (int i = 0; i < rows_num; i++) {
		for (int j = 0; j < cols_num; j++) {
			p[i][j] = value;
		}
	}
}
//析构函数
Matrix::~Matrix()
{
	for (int i = 0; i < rows_num; ++i) {
		delete[] p[i];
	}
	delete[] p;
}
//矩阵的复制
Matrix & Matrix::operator=(const Matrix &m)
{
	// TODO: 在此处插入 return 语句
	if (this == &m) {
		return *this;
	}

	if (rows_num != m.rows_num || cols_num != m.cols_num) {
		for (int i = 0; i < rows_num; ++i) {
			delete[] p[i];
		}
		delete[] p;

		rows_num = m.rows_num;
		cols_num = m.cols_num;
		initialize();
	}
	//return Matrix(1, 1);
}

//将数组的值传递给矩阵(要求矩阵的大小已经被声明过了)
Matrix& Matrix::operator=(double *a) {
	for (int i = 0; i < rows_num; i++) {
		for (int j = 0; j < cols_num; j++) {
			p[i][j] = *(a + i * cols_num + j);
		}
	}
	return *this;
}
//+=操作
Matrix& Matrix::operator+=(const Matrix& m)
{
	for (int i = 0; i < rows_num; i++) {
		for (int j = 0; j < cols_num; j++) {
			p[i][j] += m.p[i][j];
		}
	}
	return *this;
}
//实现-=
Matrix& Matrix::operator-=(const Matrix& m)
{
	for (int i = 0; i < rows_num; i++) {
		for (int j = 0; j < cols_num; j++) {
			p[i][j] -= m.p[i][j];
		}
	}
	return *this;
}
//实现*=
Matrix& Matrix::operator*=(const Matrix& m)
{
	Matrix temp(rows_num, m.cols_num);//若C=AB,则矩阵C的行数等于矩阵A的行数,C的列数等于B的列数。
	for (int i = 0; i < temp.rows_num; i++) {
		for (int j = 0; j < temp.cols_num; j++) {
			for (int k = 0; k < cols_num; k++) {
				temp.p[i][j] += (p[i][k] * m.p[k][j]);
			}
		}
	}
	*this = temp;
	return *this;
}
//实现矩阵的乘法
Matrix Matrix::operator*(const Matrix & m)const {
	Matrix ba_M(rows_num, m.cols_num, 0.0);
	for (int i = 0; i < rows_num; i++) {
		for (int j = 0; j < m.cols_num; j++) {
			for (int k = 0; k < cols_num; k++) {
				ba_M.p[i][j] += (p[i][k] * m.p[k][j]);
			}
		}
	}
	return ba_M;
}

Matrix Matrix::Hadamard(const Matrix & m, const Matrix & n)
{
	if ((m.cols_num != n.cols_num) || (m.rows_num != n.rows_num)) {
		cout << "矩阵必须行列相等,否则无法进行Hadmard乘积" << endl;
		abort();
	}
	Matrix ans(m.rows_num, m.cols_num, 0.0);
	for (int i = 0; i < m.rows_num; i++) {
		for (int j = 0; j < m.cols_num; j++) {
			ans.p[i][j] = m.p[i][j] * n.p[i][j];
		}
	}
	return ans;
}


//解方程Ax=b
Matrix Matrix::Solve(const Matrix &A, const Matrix &b)
{
	//高斯消去法实现Ax=b的方程求解
	for (int i = 0; i < A.rows_num; i++) {
		if (A.p[i][i] == 0) {

			cout << "请重新输入" << endl;
		}
		for (int j = i + 1; j < A.rows_num; j++) {
			for (int k = i + 1; k < A.cols_num; k++) {
				A.p[j][k] -= A.p[i][k] * (A.p[j][i] / A.p[i][i]);
				if (abs(A.p[j][k]) < EPS)
					A.p[j][k] = 0;
			}
			b.p[j][0] -= b.p[i][0] * (A.p[j][i] / A.p[i][i]);
			if (abs(A.p[j][0]) < EPS)
				A.p[j][0] = 0;
			A.p[j][i] = 0;
		}
	}

	// 反向代换
	Matrix x(b.rows_num, 1);
	x.p[x.rows_num - 1][0] = b.p[x.rows_num - 1][0] / A.p[x.rows_num - 1][x.rows_num - 1];
	if (abs(x.p[x.rows_num - 1][0]) < EPS)
		x.p[x.rows_num - 1][0] = 0;
	for (int i = x.rows_num - 2; i >= 0; i--) {
		double sum = 0;
		for (int j = i + 1; j < x.rows_num; j++) {
			sum += A.p[i][j] * x.p[j][0];
		}
		x.p[i][0] = (b.p[i][0] - sum) / A.p[i][i];
		if (abs(x.p[i][0]) < EPS)
			x.p[i][0] = 0;
	}

	return x;
}

//矩阵显示
void Matrix::Show() const {
	//cout << rows_num <<" "< EPS) && (abs(p[j][i]) > EPS)) {
					flag = true;
					//注:进行互换后,p[i][j]变为p[j][j],p[j][i]变为p[i][i]
					//对矩阵进行行变换
					double temp;
					for (int k = 0; k < cols_num; k++) {
						temp = p[i][k];
						p[i][k] = p[j][k];
						p[j][k] = temp;
					}
				}
			}
			if (flag)
				return 0;
		}
	}
	for (int i = 0; i < rows_num; i++) {
		for (int j = i + 1; j < rows_num; j++) {
			for (int k = i + 1; k < cols_num; k++) {
				p[j][k] -= p[i][k] * (p[j][i] * p[i][i]);
			}
		}
	}
	for (int i = 0; i < rows_num; i++) {
		ans *= p[i][i];
	}
	for (int i = 0; i < rows_num; i++) {
		for (int j = 0; j < cols_num; j++) {
			p[i][j] = back_up[i][j];
		}
	}
	return ans;
}
//返回矩阵第i行第j列的数
double Matrix::Point(int i, int j) const {
	return this->p[i][j];
}
//求矩阵的逆矩阵
Matrix Matrix::inv(Matrix A) {
	if (A.rows_num != A.cols_num) {
		std::cout << "只有方阵能求逆矩阵" << std::endl;
		std::abort();//只有方阵能求逆矩阵
	}
	double temp;
	Matrix A_B = Matrix(A.rows_num, A.cols_num);
	A_B = A;//为矩阵A做一个备份
	Matrix B = eye(A.rows_num);
	//将小于EPS的数全部置0
	for (int i = 0; i < A.rows_num; i++) {
		for (int j = 0; j < A.cols_num; j++) {
			if (abs(A.p[i][j]) <= EPS) {
				A.p[i][j] = 0;
			}
		}
	}
	//选择需要互换的两行选主元
	for (int i = 0; i < A.rows_num; i++) {
		if (abs(A.p[i][i]) <= EPS) {
			bool flag = false;
			for (int j = 0; (j < A.rows_num) && (!flag); j++) {
				if ((abs(A.p[i][j]) > EPS) && (abs(A.p[j][i]) > EPS)) {
					flag = true;
					for (int k = 0; k < A.cols_num; k++) {
						temp = A.p[i][k];
						A.p[i][k] = A.p[j][k];
						A.p[j][k] = temp;
						temp = B.p[i][k];
						B.p[i][k] = B.p[j][k];
						B.p[j][k] = temp;
					}
				}
			}
			if (!flag) {
				std::cout << "逆矩阵不存在\n";
				std::abort();
			}
		}
	}
	//通过初等行变换将A变为上三角矩阵
	double temp_rate;
	for (int i = 0; i < A.rows_num; i++) {
		for (int j = i + 1; j < A.rows_num; j++) {
			temp_rate = A.p[j][i] / A.p[i][i];
			for (int k = 0; k < A.cols_num; k++) {
				A.p[j][k] -= A.p[i][k] * temp_rate;
				B.p[j][k] -= B.p[i][k] * temp_rate;
			}
			A.p[j][i] = 0;
		}
	}
	//使对角元素均为1
	for (int i = 0; i < A.rows_num; i++) {
		temp = A.p[i][i];
		for (int j = 0; j < A.cols_num; j++) {
			A.p[i][j] /= temp;
			B.p[i][j] /= temp;
		}
	}
	//std::cout<<"算法可靠性检测,若可靠,输出上三角矩阵"<= 1; i--) {
		for (int j = i - 1; j >= 0; j--) {
			temp = A.p[j][i];
			for (int k = 0; k < A.cols_num; k++) {
				A.p[j][k] -= A.p[i][k] * temp;
				B.p[j][k] -= B.p[i][k] * temp;
			}
		}
	}
	std::cout << "算法可靠性检测,若可靠,输出单位矩阵" << std::endl;
	for (int i = 0; i < A.rows_num; i++) {
		for (int j = 0; j < A.cols_num; j++) {
			printf("%7.4lf\t\t", A.p[i][j]);
		}
		cout << endl;
	}
	A = A_B;//还原A
	return B;//返回该矩阵的逆矩阵
}
//制造一个单位矩阵
Matrix Matrix::eye(int n) {
	Matrix A(n, n);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (i == j) {
				A.p[i][j] = 1;
			}
			else {
				A.p[i][j] = 0;
			}
		}
	}
	return A;
}
//读取矩阵行列数
int Matrix::row() const {
	return rows_num;
}
int Matrix::col() const {
	return cols_num;
}
//实现矩阵的转置
Matrix Matrix::T(const Matrix & m)
{
	int col_size = m.col();
	int row_size = m.row();
	Matrix mt(col_size, row_size);
	for (int i = 0; i < row_size; i++) {
		for (int j = 0; j < col_size; j++) {
			mt.p[j][i] = m.p[i][j];
		}
	}
	return mt;
}
//高斯消元法
Matrix Matrix::gaussianEliminate()
{
	Matrix Ab(*this);
	int rows = Ab.rows_num;
	int cols = Ab.cols_num;
	int Acols = cols - 1;

	int i = 0; //跟踪行
	int j = 0; //跟踪列
	while (i < rows)
	{
		bool flag = false;
		while (j < Acols && !flag)
		{
			if (Ab.p[i][j] != 0) {
				flag = true;
			}
			else {
				int max_row = i;
				double max_val = 0;
				for (int k = i + 1; k < rows; ++k)
				{
					double cur_abs = Ab.p[k][j] >= 0 ? Ab.p[k][j] : -1 * Ab.p[k][j];
					if (cur_abs > max_val)
					{
						max_row = k;
						max_val = cur_abs;
					}
				}
				if (max_row != i) {
					Ab.swapRows(max_row, i);
					flag = true;
				}
				else {
					j++;
				}
			}
		}
		if (flag)
		{
			for (int t = i + 1; t < rows; t++) {
				for (int s = j + 1; s < cols; s++) {
					Ab.p[t][s] = Ab.p[t][s] - Ab.p[i][s] * (Ab.p[t][j] / Ab.p[i][j]);
					if (abs(Ab.p[t][s]) < EPS)
						Ab.p[t][s] = 0;
				}
				Ab.p[t][j] = 0;
			}
		}
		i++;
		j++;
	}
	return Ab;
}
//实现矩阵的输入
istream& operator >> (istream& is, Matrix& m)
{
	for (int i = 0; i < m.rows_num; i++) {
		for (int j = 0; j < m.cols_num; j++) {
			is >> m.p[i][j];
		}
	}
	return is;
}

 

你可能感兴趣的:(C++)