繁体   English   中英

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

[英]make efficient the copy of symmetric matrix in c#

我想在一个数组中存储一个对称矩阵

对于矩阵我正在这样做

    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]);
    }

如果我想存储在一个数组中

double[] mat = new double[size*size];

代替

 double[,] mat

什么是最有效的方式?

使用mat[i*n+j]

是。

按行存储元素,其中第i行和第j列存储在索引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

i = 0 .. N-1
j = 0 .. N-1

当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 |

所需的总元素是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行的最后一个元素具有index = k(i,N) = N*(i+1)-i*(i+1)/2-1 所以第3行的最后一个元素是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

为了检查上面的内容,我运行N=5k=0..14 ,得到以下结果:

索引表

哪个是对的! 校验

要制作副本,只需对Array.Copy()的元素使用Array.Copy() 另外,要进行添加和缩放等操作,只需要处理数组中的简化元素,而不是完整的N*N矩阵。 矩阵乘法有点棘手,但可行。 如果你愿意,也许你可以提出另一个问题。

关于选定的答案,除非我是一个完全白痴,否则代码不正确:

尝试这个:

i = 2, j = 1

therefore we use:

k(i,j) = j*N-j*(j-1)/2+i

to find the index k, solving:

k(i,j) = 1*5 - 1*(1-1)/2 + 2

k(i,j) = 5 - 0 + 2 = 7

从所选答案中的矩阵我们看到(2,1)不是7,它似乎是6.事实上(因为这似乎是0基),7发生在(3,1)或(1, 3)。 i> j的第二个公式似乎不准确,除非我遗漏了什么。

更新:

如果你改变i> j公式,这似乎有效:

k(i,j) = j*(N-1)-j*(j-1)/2+i

如果n是方阵的大小,则对称矩阵需要n *(n + 1)/ 2个总值。 这是1 + 2 + 3 + ...(n - 2)+(n - 1)+ n的总和。

但需要注意的是,总是试图计算给定行和列的正确索引将是一件很大的痛苦,如果矩阵将会是更加直观的二维数组,我只会离开它。大,记忆将是一个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM