简单的 3x3 矩阵逆码 (C++)
计算 3x3 矩阵逆的最简单方法是什么?
我只是在寻找一个简短的代码片段,可以使用克莱默规则来解决非奇异矩阵的问题。 它不需要高度优化。 我更喜欢简单而不是速度。 我不想链接其他库。
What's the easiest way to compute a 3x3 matrix inverse?
I'm just looking for a short code snippet that'll do the trick for non-singular matrices, possibly using Cramer's rule. It doesn't need to be highly optimized. I'd prefer simplicity over speed. I'd rather not link in additional libraries.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
我还推荐 Ilmbase,它是 OpenEXR 的一部分。 这是一组很好的模板化 2,3,4 向量和矩阵例程。
I would also recommend Ilmbase, which is part of OpenEXR. It's a good set of templated 2,3,4-vector and matrix routines.
大多数 OpenGL 工具包都提供了一个相当不错的(我认为)头文件,其中包含大多数 2x2、3x3 和 4x4 矩阵运算的宏。 不是标准的,但我在不同的地方见过它。
你可以在这里查看。 最后你会发现 2x2、3x3 和 4x4 的逆。
A rather nice (I think) header file containing macros for most 2x2, 3x3 and 4x4 matrix operations has been available with most OpenGL toolkits. Not as standard but I've seen it at various places.
You can check it out here. At the end of it you will find both inverse of 2x2, 3x3 and 4x4.
复制上述代码并将其保存为 Matrix.h,然后尝试以下代码:
Copy and save the above code as Matrix.h then try the following code:
这是巴蒂答案的一个版本,但这计算出正确的逆。 batty 的版本计算逆矩阵的转置。
Here's a version of batty's answer, but this computes the correct inverse. batty's version computes the transpose of the inverse.
恕我直言,我对我们未知的(雅虎)发布者表示敬意,我看着这样的代码,心里有点死了。 字母汤实在是太难调试了。 任何地方的一个拼写错误都会毁掉你的一整天。 遗憾的是,这个特定的示例缺少带下划线的变量。 当我们有 a_b-c_d*e_f-g_h 时,会更有趣。 特别是当使用 _ 和 - 具有相同像素长度的字体时。
根据 Suvesh Pratapa 的建议,我注意到:
(A) 当取 3x3 数组的次要值时,我们有 4 个感兴趣的值。 较低的 X/Y 索引始终为 0 或 1。较高的 X/Y 索引始终为 1 或 2。始终! 因此:
(B) 行列式现在是:(注意减号!)
(C) 倒数现在是:
用一些质量较低的测试代码将其四舍五入:
事后思考:
您可能还想检测非常大的行列式四舍五入误差会影响您的准确性!
With all due respect to our unknown (yahoo) poster, I look at code like that and just die a little inside. Alphabet soup is just so insanely difficult to debug. A single typo anywhere in there can really ruin your whole day. Sadly, this particular example lacked variables with underscores. It's so much more fun when we have a_b-c_d*e_f-g_h. Especially when using a font where _ and - have the same pixel length.
Taking up Suvesh Pratapa on his suggestion, I note:
(A) When taking a minor of a 3x3 array, we have 4 values of interest. The lower X/Y index is always 0 or 1. The higher X/Y index is always 1 or 2. Always! Therefore:
(B) Determinant is now: (Note the minus sign!)
(C) And the inverse is now:
And round it out with a little lower-quality testing code:
Afterthought:
You may also want to detect very large determinants as round-off errors will affect your accuracy!
你为什么不尝试自己编码呢? 把它当作一个挑战。 :)
对于 3×3 矩阵
(来源:wolfram.com)
矩阵的逆矩阵是
(来源:wolfram.com)
我假设您知道矩阵 |A| 的行列式是什么 是。
Why don't you try to code it yourself? Take it as a challenge. :)
For a 3×3 matrix
(source: wolfram.com)
the matrix inverse is
(source: wolfram.com)
I'm assuming you know what the determinant of a matrix |A| is.
这段代码计算矩阵 A 的转置逆矩阵 A:
虽然问题规定了非奇异矩阵,但您可能仍然想检查行列式是否等于零(或非常接近零)并将其标记为某些确保安全的方法。
This piece of code computes the transposed inverse of the matrix A:
Though the question stipulated non-singular matrices, you might still want to check if determinant equals zero (or very near zero) and flag it in some way to be safe.
如果您真的想正确处理边缘情况,请不要尝试自己这样做。 因此,虽然许多朴素/简单的方法在理论上是精确的,但对于近乎奇异的矩阵,它们可能会产生令人讨厌的数值行为。 特别是,您可能会遇到取消/舍入错误,导致您得到任意糟糕的结果。
一种“正确”的方法是使用行和列旋转的高斯消除法,以便您始终除以最大的剩余数值。 (这对于 NxN 矩阵也是稳定的。)。 请注意,仅行旋转并不能捕获所有不良情况。
然而,在我看来,正确而快速地实现这一点并不值得你花时间——使用一个经过良好测试的库,并且有一堆只有标头的库。
Don't try to do this yourself if you're serious about getting edge cases right. So while they many naive/simple methods are theoretically exact, they can have nasty numerical behavior for nearly singular matrices. In particular you can get cancelation/round-off errors that cause you to get arbitrarily bad results.
A "correct" way is Gaussian elimination with row and column pivoting so that you're always dividing by the largest remaining numerical value. (This is also stable for NxN matrices.). Note that row pivoting alone doesn't catch all the bad cases.
However IMO implementing this right and fast is not worth your time - use a well tested library and there are a heap of header only ones.
我刚刚创建了一个 QMatrix 类。 它使用内置的向量> 容器。 QMatrix.h
它使用 Jordan-Gauss 方法来计算方阵的逆。
您可以按如下方式使用它:
inverse 函数的实现如下:
给定一个具有以下字段的类:
inverse() 函数:
I have just created a QMatrix class. It uses the built in vector > container. QMatrix.h
It uses the Jordan-Gauss method to compute the inverse of a square matrix.
You can use it as follows:
The inverse function is implemented as follows:
Given a class with the following fields:
the inverse() function: