#C++矩阵类的实现

2023-11-18

C++矩阵类的实现

环境:Win10、VS2017

最近老师布置一个简单的C++作业——实现一个矩阵类,并且实现矩阵运算。
主要实现运算为矩阵的加、减、乘、除以及求行列式,伴随矩阵,代数余子式和逆矩阵等。在参考网上的一些前辈的代码后,写出了这些运算的简单实现。
因为矩阵的加、减、乘、除(完成求逆矩阵后)、转置等运算比较简单,所以此处主要讲上述其余运算的实现。

话不多说,开始:
首先定义一个矩阵类,需要实现功能略多,还有各运算函数的声明,大概如下:

class Matrix 
{
publicMatrix(): DataArray(0) {}
	Matrix(int rows, int cols) :DataArray(rows)
	{
		for (int i = 0; i < rows; i++)
			DataArray[i].resize(cols);
	}
	Matrix(const Matrix &m) { (*this) = m; }
	friend istream&operator>>(istream &is, Matrix &A);         //重载运算符>>用于输入矩阵
	friend ostream&operator<<(ostream &os, const Matrix &A);  //重载运算符<<用于输出矩阵
	//加、减、乘
	const Matrix& operator+=(const Matrix &A); 
	.........
	//需要用到一些的函数
	void resize(int, int);                //改变矩阵大小
	bool push_back(const vector<T>& v) { DataArray.push_back(v); }     //添加一行
	void swap_row(int ,int );                       //交换矩阵的两行
	int rows() const { return DataArray.size(); } 
	int cols() const { return rows() ? (DataArray[0].size()) : 0; }
	bool empty() const { return rows() == 0; }
	bool square() const { return !(empty()) && rows() == cols(); }       //判断矩阵是否为方阵
	const vector<double> operator[](int row) const { return DataArray[row]; }  //这两行用于取矩阵元素
	vector<double>& operator[](int row) { return DataArray[row]; }
protected:
	vector<vector<double>>DataArray;
};

const double det(const Matrix &A); //求行列式
const double alge_cofactor(const Matrix &A, int row, int col);//求代数余子式
const Matrix adjoint(const Matrix &A); //求伴随矩阵
const Matrix inv(const Matrix &A);  //求逆矩阵

矩阵类定义完成,接下来完成resize函数,swap_row比较简单此处不再展出

void Matrix::resize(int rows, int cols)
{
	int rs = this->rows();
	int cs = this->cols();
	if (rows == rs && cols == cs)
	{
		return;
	}
	else if (rows == rs && cols != cs)    //改列数
	{
		for (int i = 0;i < rows; i++)
		{
			DataArray[i].resize(cols);
		}
	}
	else if (rows != rs && cols == cs)   //改行数
	{
		DataArray.resize(rows);
		for (int i = rs; i < rows; i++)
		{
			DataArray[i].resize(cols);
		}
	}
	else										//二者都改
	{
		DataArray.resize(rows);
		for (int i = 0; i < rows; i++)
		{
			DataArray[i].resize(cols);
		}
	}
}

接下来进入正题,求行列式,代数余子式,伴随矩阵和逆矩阵。步骤如下:

1.求行列式|A|,因为需要计算的行列式阶数并不是很高,所以我选择的求行列式方式为使用公式: ∑ ( − 1 ) t a 1 p 1 a 2 p 2 a 1 p 3 . . . . . . a n p n \sum(-1)^ta_{1p_1}a_{2p_2}a_{1p_3}......a_{np_n} (1)ta1p1a2p2a1p3......anpn,该公式也比较容易实现。然而在完成该函数之前需要先完成 p 1 p_1 p1 p n p_n pn的全排列,以及排列完成后各逆序数:

1)排列算法函数,不了解可自行搜索,比较简单,大概实现即用一个vector<int> p存储一种排列然后用vector<<int>> q存储全排列。

void swap(vector<int>& v, int i, int j)
{
	int temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}

void Permutation(vector<int> &p, vector<vector<int>> &q,int c) 
{
	if (c == ((unsigned int)p.size() - 1))
	{
		q.push_back(p);         
	}
	else
	{
		for (int i = c; i < (unsigned int)p.size(); i++)
		{
			swap(p, i, c);
			Permutation(p, q, c + 1);
			swap(p, i, c);
		}
	}
}

2)求逆序数t:

int Power(vector<int>& v)
{
	int count = 0;
	for (int i = 0; i < (unsigned int)v.size(); i++)
	{
		for (int j = i + 1; j < (unsigned int)v.size(); j++)
		{
			if (v[i] > v[j])
			{
				count += 1;
			}
		}
	}
	return count;
}

3)求行列式,上面两步完成后,求行列式的步骤变得极其简单:

const double det(const Matrix &A)
{
	if (!A.square())         //此处可自行修改
	{
		cout << "fail" << endl;
		return 0.0;
	}
	//完成p1到pn的排列组合
	vector<int> rs;           
	vector<vector<int> > I;
	for (int i = 0; i < A.rows(); i++)      //输入1-n
	{
		rs.push_back(i);
	}
	Permutation(rs, I);
	
	double result = 0.0;
	for (int i = 0; i < I.size(); i++)
	{
		rs= I[i];                        //取出一种排列
		int temp = pow(-1.0, (double)Power(rs));   //算出该排列的逆序数
		int row = 0;
		for (int j = 0; j < (unsigned int)rs.size(); j++)    //计算一种排列对应的乘积
		{
			int col = rs[j];
			temp *= A[row][col];
			row++;
		}
		result += temp;
	}
	return result;
}

2.完成求代数余子式的函数,将划去行列元素放入一个新的矩阵,然后求解(其实求出行列式后,剩下三个函数会变得极其简单)。

const double alge_cofactor(const Matrix &A, int row, int col)
{
	if (!A.square())
	{
		cout << "fail" << endl;
		return 0.0;
	}

	vector<int> rs;
	vector<vector<int> > I;
	vector<double> ret;
	Matrix B((A.rows() - 1), (A.cols() - 1));
	for (int i = 0; i < A.rows(); i++)     //把组成行列式的元素移到ret中
	{
		if (i == (row-1))
			continue;
		for (int j = 0; j < A.cols(); j++)
		{
			if (j == (col-1))
				continue;
			else
				ret.push_back(A[i][j]);
		}
	}
	
	int count = 0;                     //剩下的元素组成一个新的行列式
	for (int i = 0; i < B.rows(); i++)
	{
		for (int j = 0; j < B.cols(); j++)
		{
			B[i][j] = ret[count];
			count++;
		}
	}

	double result = det(B)*pow(-1, (double)(row + col));   
	return result;
}

3.求伴随矩阵,A*:

const Matrix adjoint(const Matrix &A)
{
	Matrix B(A.rows(), A.cols());

	for (int i = 0; i < A.rows(); i++)
	{
		for (int j = 0; j < A.cols(); j++)
		{
			B[i][j] = alge_cofactor(A, (j + 1), (i + 1));
		}
	}

	return B;
}

4.求逆矩阵,使用公式 A − 1 = A ∗ ∣ A ∣ A^{-1}=\frac{A^*}{|A|} \quad A1=AA即可:

const Matrix inv(const Matrix &A)
{
	if (det(A) == 0||A.rows()!=A.cols())
		return A;
	else
	{
		return (adjoint(A) / det(A));  //该处需要重载一下 / 函数声明:const Matrix operator/(const Matrix A, double a);实现矩阵乘一个分数或者说除以一个数
	}
}

只需要测试一下矩阵求逆是否正确,即可验证一下其余函数的正确性,测试结果:
在这里插入图片描述
虽然可能还存在着很多问题,但是基本上完成任务了。最后感谢那些为我提供参考的前辈们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

#C++矩阵类的实现 的相关文章

随机推荐

  • python程序里一定要有一个主函数吗_Python 为什么没有 main 函数?为什么我不推荐写 main 函数?...

    在开始正题之前 先要来回答这两个问题 所谓的 main 函数 是指什么 为什么有些编程语言需要强制写一个 main 函数 某些编程语言以 main 函数作为程序的执行入口 例如 C C C Java Go 和 Rust 等 它们具有特定的含
  • JS属性defer

    JS属性defer 利用defer属性 让浏览器读js脚本的时候完全不等脚本 就开始读取图片和html代码 给外链JS脚本添加defer true
  • Android源码分析 - Framework层的ContentProvider全解析

    开篇 本篇以android 11 0 0 r25作为基础解析 在四大组件中 可能我们平时用到最少的便是ContentProvider了 ContentProvider是用来帮助应用管理其自身和其他应用所存储数据的访问 并提供与其他应用共享数
  • Rocky9.2 第一次配置virtualbox报错Kernel driver not installed (rc=-1908)

    完整报错信息如下 Kernel driver not installed rc 1908 The VirtualBox Linux kernel driver is either not loaded or not set up corre
  • PDF文件转化成mobi格式,亲测kindle或者iReader可用!

    convertfiles 点击连接 然后选择要转换的文件 比如我的是MySQL的 选择输入文件和输出文件的格式 转换 对了记得输入邮箱号码 转化完毕会发送连接到邮箱提供下载 或者 网络流畅的情况下转化完毕会自动重定向到下载页面
  • Vue3之路--Less教学

    概览 Less Leaner Style Sheets 的缩写 是一门向后兼容的 CSS 扩展语言 这里呈现的是 Less 的官方文档 中文版 包含了 Less 语言以及利用 JavaScript 开发的用于将 Less 样式转换成 CSS
  • 关于table的selectedRowKeys和selectedRows

    项目使用的组件库是antd 页面中有很多table 有的table有行前面的复选框 于是就有了selectedRowkeys和selectedRows的事 他们两个都是数组 selectedRowkeys存的是table的rowKey 也就
  • .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (C# DIY HttpWebClient)

    选择自 playyuer 的 Blog Net C 实现支持断点续传多线程下载的 Http Web 客户端工具类 C DIY HttpWebClient Reflector 了一下 System Net WebClient 重载或增加了若干
  • 论文阅读-NOLANet多模态伪造检测

    一 论文信息 题目 Deepfake Video Detection Based on Spatial Spectral and Temporal Inconsistencies UsingMultimodal Deep Learning
  • SQL学习笔记——limit用法(limit使用一个参数,limit使用两个参数)

    Product表 limit语法 select lt 列名 gt lt 列名 gt from lt 表名 gt limit lt 参数值 gt select from product limit 3 product id product n
  • 第三方平台代微信公众号开发

    第三方平台代微信公众号开发流程 一 准备工作 微信开放平台相关 申请微信开放平台账号后 需前往微信开放平台 创建第三方平台 填写开发相关配置 填写授权流程相关配置 注意事项 授权发起页域名 为项目开发使用域名 调用公众号二维码授权页时 必须
  • test is not a function (js正则表达式匹配问题)

    js中正则表达式匹配时 如果使用test函数 就必须不带引号 并且必须是 定义的规则变量 test 要测试的string 定义变量规则不要带引号 会错误的 如果不使用test 使用match则可以带引号 var re 1 9 d 4 10
  • Android 组件逻辑漏洞漫谈

    前言 随着社会越来越重视安全性 各种防御性编程或者漏洞缓解措施逐渐被加到了操作系统中 比如代码签名 指针签名 地址随机化 隔离堆等等 许多常见的内存破坏漏洞在这些缓解措施之下往往很难进行稳定的利用 因此 攻击者们的目光也逐渐更多地投入到逻辑
  • QT4信号连接与QT5的区别

    QT4信号连接与QT5的区别 QT4信号与槽 1 申明槽函数必须增加public slots 2 SIGNAL SLOT 将函数转为字符串 不进行错误检查 connect中信号和槽需要增加SIGNAL 和SLOT 3 槽函数和信号一致 参数
  • 常用的表格正则验证 + 省份选择 JS JQ

    常用的表格正则验证 轮子 let receiverNameReg u4e00 u9fa5 2 6 reg 收货人姓名 let receiverName receiverName val 收货人姓名 let phoneNumberReg d
  • TCP的几个状态 SYN, FIN, ACK, PSH, RST, URG

    2019独角兽企业重金招聘Python工程师标准 gt gt gt TCP的几个状态对于我们分析所起的作用 在TCP层 有个FLAGS字段 这个字段有以下几个标识 SYN FIN ACK PSH RST URG 其中 对于我们日常的分析有用
  • 数据挖掘技术-绘制散点图

    绘制散点图 前置步骤 准备数据guomin npz 下载数据guomin npz到Linux本地的 course DataAnalyze data目录 绘制散点图 绘制2000 2017年各季度的国民生产总值散点图 如代码 41所示 代码
  • 【华为OD机试真题 JAVA】执行时长

    JS版 华为OD机试真题 JS 执行时长 标题 执行时长 时间限制 1秒 内存限制 262144K 语言限制 不限 为了充分发挥GPU算力 需要尽可能多的将任务交给GPU执行 现在有一个任务数组 数组元素表示在这1秒内新增的任务个数且每秒都
  • Python脚本报错AttributeError: ‘module’ object has no attribute’xxx’解决方法

    最近在编写Python脚本过程中遇到一个问题比较奇怪 Python脚本完全正常没问题 但执行总报错 AttributeError module object has no attribute xxx 这其实是 pyc文件存在问题 问题定位
  • #C++矩阵类的实现

    C 矩阵类的实现 环境 Win10 VS2017 最近老师布置一个简单的C 作业 实现一个矩阵类 并且实现矩阵运算 主要实现运算为矩阵的加 减 乘 除以及求行列式 伴随矩阵 代数余子式和逆矩阵等 在参考网上的一些前辈的代码后 写出了这些运算