如何存储对称矩阵?
在内存中存储对称矩阵的最佳方式是什么?
如果能节省一半的空间,而又不会过多地影响速度和结构的复杂性,那就太好了。这是一个与语言无关的问题,但如果您需要做出一些假设,只需假设它是一种很好的老式普通编程语言,例如 C 或 C++
。当矩阵本身很大时,我是对的吗?
只是为了正式起见,我的意思是这个断言对于我想要存储的数据总是正确的
matrix[x][y] == matrix[y][x]
Which is the best way to store a symmetric matrix in memory?
It would be good to save half of the space without compromising speed and complexity of the structure too much. This is a language-agnostic question but if you need to make some assumptions just assume it's a good old plain programming language like C or C++..
It seems a thing that has a sense just if there is a way to keep things simple or just when the matrix itself is really big, am I right?
Just for the sake of formality I mean that this assertion is always true for the data I want to store
matrix[x][y] == matrix[y][x]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这是存储对称矩阵的好方法,它只需要 N(N+1)/2 内存:
对于某些三角矩阵
一维表示(例如,存储在
std::vector
中)看起来像如下:并且调用 fromMatrixToVector(1, 2, 4) 返回 5,因此矩阵数据为 vector[5] -> 5.
有关详细信息,请参阅 http://www.codeguru.com/cpp/cpp/algorithms/general/article.php/c11211/TIP-Half-Size-Triangle-Matrix.htm
Here is a good method to store a symmetric matrix, it requires only N(N+1)/2 memory:
For some triangular matrix
1D representation (stored in
std::vector
, for example) looks like as follows:And call fromMatrixToVector(1, 2, 4) returns 5, so the matrix data is vector[5] -> 5.
For more information see http://www.codeguru.com/cpp/cpp/algorithms/general/article.php/c11211/TIP-Half-Size-Triangular-Matrix.htm
我发现许多高性能包只存储整个矩阵,但只读取上三角形或下三角形。然后,他们可能会在计算期间使用额外的空间来存储临时数据。
但是,如果存储确实是一个问题,那么只需将构成上三角形的
n(n+1)/2
元素存储在一维数组中即可。如果这使您的访问变得复杂,只需定义一组辅助函数即可。在 C 中,要访问矩阵
matA
,您可以定义一个宏:然后您几乎可以正常访问数组。
I find that many high performance packages just store the whole matrix, but then only read the upper triangle or lower triangle. They might then use the additional space for storing temporary data during the computation.
However if storage is really an issue then just store the
n(n+1)/2
elements making the upper triangle in a one-dimensional array. If that makes access complicated for you, just define a set of helper functions.In C to access a matrix
matA
you could define a macro:then you can access your array nearly normally.
好吧,我会尝试一个三角矩阵,如下所示:
但是当有人想要访问“另一边”时,您将不得不面对问题。例如,他想访问 [0][10],但在你的情况下,这个 val 存储在 [10][0] 中(假设 10x10)。
可能“最好”的方法是懒惰的方法 - 在用户请求之前不执行任何操作。因此,如果用户键入 print(matrix[4]) 之类的内容,您可以加载特定行。
Well I would try a triangular matrix, like this:
But then you wil have to face the problem when someone wants to access the "other side". Eg he wants to access [0][10] but in your case this val is stored in[10][0] (assuming 10x10).
The probably "best" way is the lazy one - dont do anything until the user requests. So you could load the specific row if the user types somethin like print(matrix[4]).
如果你想使用一维数组,代码将如下所示:
如果你创建一个额外的查找表,你可以摆脱乘法:
If you want to use a one dimensional array the code would look something like this:
You can get rid of the multiplications if you create an additional look-up table:
如果您使用的是支持运算符重载的东西(例如C++),那么透明地处理这个问题非常容易。只需创建一个矩阵类来检查两个下标,如果第二个下标大于第一个下标,则交换它们:
目前我跳过了其他所有内容,只介绍了下标。实际上,为了正确处理左值和右值的使用,您通常需要返回代理而不是直接返回 T。您需要一个将
data
创建为三角形的 ctor(即,对于 NxN 矩阵,第一行将有 N 个元素,第二行有 N-1 个元素,依此类推 - 或者,相当于 1 , 2, ...N)。您还可以考虑将data
创建为单个向量
——您必须计算出正确的偏移量,但这并不是非常困难,而且它会使用更少的内存,运行得更快一些,等等。我会在第一个版本中使用简单的代码,并在必要时进行优化。If you're using something that supports operator overloading (e.g. C++), it's pretty easy to handle this transparently. Just create a matrix class that checks the two subscripts, and if the second is greater than the first, swap them:
For the moment I've skipped over everything else, and just covered the subscripting. In reality, to handle use as both an lvalue and an rvalue correctly, you'll typically want to return a proxy instead of a T directly. You'll want a ctor that creates
data
as a triangle (i.e., for an NxN matrix, the first row will have N elements, the second N-1, and so on -- or, equivalantly 1, 2, ...N). You might also consider creatingdata
as a singlevector
-- you have to compute the correct offset into it, but that's not terribly difficult, and it will use a bit less memory, run a bit faster, etc. I'd use the simple code for the first version, and optimize later if necessary.如果您的语言支持交错数组,并且当 x < 时,您可以使用交错数组(或任何名称)。 y,交换x和y的位置。所以......
nxn 矩阵的伪代码(有点Python风格,但不是真的):
然后当引用值时......
You could use a staggered array (or whatever they're called) if your language supports it, and when x < y, switch the position of x and y. So...
Pseudocode (somewhat Python style, but not really) for an n x n matrix:
And then when referring to values....