问题描述
我想在一个数组中存储一个对称矩阵
I want to store in an array a symmetric matrix
对于我正在做的矩阵
double[,] mat = new double[size,size];
for (int i = 0; i < size; i++)
{
for (int j = 0; j <= i; j++)
mat[i, j] = mat[j, i] = (n * other_matrix[i,j]);
}
如果我想存储在一个数组中
If I want to store in an array
double[] mat = new double[size*size];
代替
double[,] mat
最有效的方法是什么?
使用mat[i*n+j]
?
推荐答案
是.
按行存储元素,其中i
-th行和j
-th列存储在索引k=i*NC+j
与 NC
列数.这适用于非对称一般矩阵.
Store the elements by row, where the i
-th row and j
-th column is stored in index k=i*NC+j
with NC
the number of columns. This applies to a non-symmetric general matrix.
要存储大小为 N
的对称矩阵,您只需要数组中的 N*(N+1)/2
个元素.你可以假设 i 使得数组索引像这样:
To store a symmetric matrix of size N
you only need N*(N+1)/2
elements in the array. You can assume that i<=j
such that the array indexes go like this:
k(i,j) = i*N-i*(i+1)/2+j i<=j //above the diagonal
k(i,j) = j*N-j*(j+1)/2+i i>j //below the diagonal
与
i = 0 .. N-1
j = 0 .. N-1
例如当 N=5 时,数组索引是这样的
Example when N=5, the array indexes go like this
| 0 1 2 3 4 |
| |
| 1 5 6 7 8 |
| |
| 2 6 9 10 11 |
| |
| 3 7 10 12 13 |
| |
| 4 8 11 13 14 |
所需的总元素为 5*(5+1)/2 = 15
,因此索引从 0..14
开始.
The total elements needed are 5*(5+1)/2 = 15
and thus the indexes go from 0..14
.
i
-th 对角线具有索引 k(i,i) = i*(N+1)-i*(i+1)/2
.所以第三行 (i=2
) 的对角线索引 k(2,2) = 2*(5+1)-2*(2+1)/2 = 9代码>.
The i
-th diagonal has index k(i,i) = i*(N+1)-i*(i+1)/2
. So the 3rd row (i=2
) has diagonal index k(2,2) = 2*(5+1)-2*(2+1)/2 = 9
.
i
-th 行的最后一个元素有 index = k(i,N) = N*(i+1)-i*(i+1)/2-1
.所以第三行的最后一个元素是k(2,4) = 5*(2+1)-2*(2+1)/2-1 = 11
.
The last element of the i
-th row has index = k(i,N) = N*(i+1)-i*(i+1)/2-1
. So the last element of the 3rd row is k(2,4) = 5*(2+1)-2*(2+1)/2-1 = 11
.
您可能需要的最后一部分是如何从数组索引 k
到行 i
和列 j
.再次假设 i(在对角线上)答案是
The last part that you might need is how to go from the array index k
to the row i
and column j
. Again assuming that i<=j
(above the diagonal) the answer is
i(k) = (int)Math.Floor(N+0.5-Math.Sqrt(N*(N+1)-2*k+0.25))
j(k) = k + i*(i+1)/2-N*i
为了检查上面的内容,我为 N=5
, k=0..14
运行了这个并得到以下结果:
To check the above I run this for N=5
, k=0..14
and got the following results:
这是对的!
要进行复制,只需在超快的元素上使用 Array.Copy()
即可.同样要进行加法和缩放等操作,您只需要处理数组中减少的元素,而不是完整的 N*N
矩阵.矩阵乘法有点棘手,但可行.如果你愿意,也许你可以问另一个问题.
To make the copy then just use Array.Copy()
on the elements which is super fast. Also to do operations such as addition and scaling you just need to work on the reduced elements in the array, and not on the full N*N
matrix. Matrix multiplication is a little tricky, but doable. Maybe you can ask another question for this if you want.
这篇关于在 C# 中有效地复制对称矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!