矩阵求逆的快速算法[通俗易懂]

矩阵求逆的快速算法[通俗易懂]                                                                                                  作者:龚敏敏算法介绍矩阵求逆在3D程序中很常见,主要应用于求Billboard矩阵。按照定义的计算方法乘法运算,严重影响了性能。在需要大量Billboard矩阵运算时,矩阵求逆的优化能极大提高性

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

                                                                                                   作者:龚敏敏

算法介绍

矩阵求逆在3D程序中很常见,主要应用于求Billboard矩阵。按照定义的计算方法乘法运算,严重影响了性能。在需要大量Billboard矩阵运算时,矩阵求逆的优化能极大提高性能。这里要介绍的矩阵求逆算法称为全选主元高斯-约旦法。

高斯-约旦法(全选主元)求逆的步骤如下:

首先,对于 k 从 0 到 n – 1 作如下几步:

  1. 从第 k 行、第 k 列开始的右下角子阵中选取绝对值最大的元素,并记住次元素所在的行号和列号,在通过行交换和列交换将它交换到主元素位置上。这一步称为全选主元。
  2. m(k, k) = 1 / m(k, k)
  3. m(k, j) = m(k, j) * m(k, k),j = 0, 1, …, n-1;j != k
  4. m(i, j) = m(i, j) – m(i, k) * m(k, j),i, j = 0, 1, …, n-1;i, j != k
  5. m(i, k) = -m(i, k) * m(k, k),i = 0, 1, …, n-1;i != k

最后,根据在全选主元过程中所记录的行、列交换的信息进行恢复,恢复的原则如下:在全选主元过程中,先交换的行(列)后进行恢复;原来的行(列)交换用列(行)交换来恢复。

实现(4阶矩阵)

float Inverse(CLAYMATRIX& mOut, const CLAYMATRIX& rhs) 

Jetbrains全家桶1年46,售后保障稳定


{ 

	CLAYMATRIX m(rhs); 

	DWORD is[4]; 

	DWORD js[4]; 

	float fDet = 1.0f; 

	int f = 1; 


	for (int k = 0; k < 4; k ++) 

	{ 

		// 第一步,全选主元 

		float fMax = 0.0f; 

		for (DWORD i = k; i < 4; i ++) 

		{ 

			for (DWORD j = k; j < 4; j ++) 

			{
  
  

				const float f = Abs(m(i, j));

				if (f > fMax)

				{
					fMax	= f;

					is[k]	= i;

					js[k]	= j;

				}

			}

		}

		if (Abs(fMax) < 0.0001f)

			return 0;

		
		if (is[k] != k)

		{
  
  

			f = -f;

			swap(m(k, 0), m(is[k], 0));

			swap(m(k, 1), m(is[k], 1));

			swap(m(k, 2), m(is[k], 2));

			swap(m(k, 3), m(is[k], 3));

		}

		if (js[k] != k)

		{
  
  

			f = -f;

			swap(m(0, k), m(0, js[k]));

			swap(m(1, k), m(1, js[k]));

			swap(m(2, k), m(2, js[k]));

			swap(m(3, k), m(3, js[k]));

		}


		// 计算行列值

		fDet *= m(k, k);


		// 计算逆矩阵


		// 第二步

		m(k, k) = 1.0f / m(k, k);	

		// 第三步

		for (DWORD j = 0; j < 4; j ++)

		{
  
  

			if (j != k)

				m(k, j) *= m(k, k);

		}

		// 第四步

		for (DWORD i = 0; i < 4; i ++)

		{
  
  

			if (i != k)

			{
  
  

				for	(j = 0; j < 4; j ++)

				{
  
  

					if (j != k)

						m(i, j) = m(i, j) - m(i, k) * m(k, j);
				}

			}

		}

		// 第五步

		for (i = 0; i < 4; i ++)

		{
  
  

			if (i != k)

				m(i, k) *= -m(k, k);

		}

	}


	for	(k = 3; k >= 0; k --)

	{
  
  

		if (js[k] != k)

		{
  
  

			swap(m(k, 0), m(js[k], 0));

			swap(m(k, 1), m(js[k], 1));

			swap(m(k, 2), m(js[k], 2));

			swap(m(k, 3), m(js[k], 3));

		}

		if (is[k] != k)

		{
			swap(m(0, k), m(0, is[k]));

			swap(m(1, k), m(1, is[k]));

			swap(m(2, k), m(2, is[k]));

			swap(m(3, k), m(3, is[k]));

		}

	}


	mOut = m;

	return fDet * f;

}


比较

  原算法 原算法(经过高度优化) 新算法
加法次数 103 61 39
乘法次数 170 116 69
需要额外空间 16 * sizeof(float) 34 * sizeof(float) 25 * sizeof(float)

结果不言而喻吧。
 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/234476.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • FileInputStream概述[通俗易懂]

    FileInputStream概述[通俗易懂]一FileInputStream概述FileInputStream:从文件系统中的文件获取输入字节。可用的文件取决于主机环境。FileInputStream用于读取诸如图像数据的原始字节流。要读取字符流,请考虑使用FileReader。二FileInputStream的构造方法1.FileInputStream(Filefile)通过打开与实际文件的连接来创建FileInputStream,该文件由文件系统中的File对象file命名。2.FileInputSt…

    2022年6月4日
    42
  • 矩阵的秩(Rank)[通俗易懂]

    矩阵的秩(Rank)[通俗易懂]定义一个矩阵A的列秩是A的线性无关的纵列的极大数目。类似地,行秩是A的线性无关的横行的极大数目。矩阵的列秩和行秩总是相等的,因此它们可以简单地称作矩阵A的秩。通常表示为r(A),rank(A)或rk(A)。可替代定义用行列式定义设A为m*n矩阵,若A至少有一个r阶非零子式,而其所有r+1阶子式全为零,则称r为A的秩。性质m×n矩阵的秩不大于m且不大于n的一个非负整数,表示为rk(A)≤min(m,n)。有尽可能大的秩的.

    2022年5月7日
    217
  • EVE-NG模拟器升级并添加H3C设备

    EVE-NG模拟器升级并添加H3C设备EVE-NG模拟器升级并添加H3C系列模板和镜像欢迎使用Markdown编辑器你好!这是你第一次使用Markdown编辑器所展示的欢迎页。如果你想学习如何使用Markdown编辑器,可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。新的改变我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它…

    2022年5月23日
    221
  • 十大滤波算法总结

    十大滤波算法总结由于MPU6050的深入,我也学会了一些滤波算法,自己写了一些算法,收集了一些算法,供大家一起学习分享,我的代码都是经过反复试验,复制到Arduino中就能开跑的成品代码,移植到自己的程序中非常方便。而且都仔细研究了各个算法,把错误都修正了的,所以也算个小原创吧,在别人基础上的原创。1、限幅滤波法(又称程序判断滤波法)2、中位值滤波法3、算术平均滤波法4、递推平均滤波法(又称滑动平

    2022年6月14日
    66
  • android软件开发工具(WiFi破解)

    做为一个多年奋战在Android应用开发一线的程序员来说,程序调试的苦是不言而喻的,在过去的很长一段时间里,我们如果要调试Android应用只能通过USB数据线,一头连着手机,一头联着电脑,不敢让手机离开电脑半步。、         曾经有一段时间,我总是担心天天这样高强度的调试别把手机的USB口给磨坏了。也许有朋友问了,那怎么不用模拟器呢?事实上,不是不想用,而是电脑上开个模似器可能需

    2022年4月13日
    57
  • 协同过滤推荐算法详解「建议收藏」

    协同过滤推荐算法详解「建议收藏」一、什么是协同过滤?协同过滤是利用集体智慧的一个典型方法。要理解什么是协同过滤(CollaborativeFiltering,简称CF),首先想一个简单的问题,如果你现在想看个电影,但你不知道具体看哪部,你会怎么做?大部分的人会问问周围的朋友,看看最近有什么好看的电影推荐,而我们一般更倾向于从口味比较类似的朋友那里得到推荐。这就是协同过滤的核心思想。协同过滤一般是在海量的用户中发掘

    2022年6月29日
    25

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号