我想在一个数组中存储一个对称矩阵
对于矩阵我正在这样做
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]);
}
Run Code Online (Sandbox Code Playgroud)
如果我想存储在一个数组中
double[] mat = new double[size*size];
Run Code Online (Sandbox Code Playgroud)
代替
double[,] mat
Run Code Online (Sandbox Code Playgroud)
什么是最有效的方式?
用mat[i*n+j]
?
是.
按行存储元素,其中i
-th row和j
-th列存储在k=i*NC+j
具有NC
列数的索引中.这适用于非对称通用矩阵.
要存储大小对称的矩阵,N
您只需要N*(N+1)/2
数组中的元素.您可以假设i<=j
数组索引如下所示:
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
Run Code Online (Sandbox Code Playgroud)
同
i = 0 .. N-1
j = 0 .. N-1
Run Code Online (Sandbox Code Playgroud)
当N = 5时,数组索引就像这样
| 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 |
Run Code Online (Sandbox Code Playgroud)
所需的总元素是5*(5+1)/2 = 15
因此索引来自0..14
.
该i
个对角线具有指标k(i,i) = i*(N+1)-i*(i+1)/2
.所以第3行(i=2
)有对角线索引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
.
您可能需要的最后一部分是如何从数组索引k
转到行i
和列j
.再次假设i<=j
(在对角线上方)答案是
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
Run Code Online (Sandbox Code Playgroud)
要检查上面的内容,请执行此操作N=5
,k=0..14
并获得以下结果:
哪个是对的!
要制作副本,然后只使用Array.Copy()
超快的元素.另外,要进行添加和缩放等操作,您只需要处理数组中的简化元素,而不是整个N*N
矩阵.矩阵乘法有点棘手,但可行.如果你愿意,也许你可以提出另一个问题.