在c#中高效复制对称矩阵

cMi*_*nor 3 c# loops 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]);
    }
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]

ja7*_*a72 6

是.

按行存储元素,其中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矩阵.矩阵乘法有点棘手,但可行.如果你愿意,也许你可以提出另一个问题.