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

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

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

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

代替

 double[,] mat

什么是最有效的方法?

使用 mat[i*n+j]?

最佳答案

是的。

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

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 . Check

i -th 对角线有索引 k(i,i) = i*(N+1)-i*(i+1)/2 .所以第 3 行 ( i=2 ) 有对角索引 k(2,2) = 2*(5+1)-2*(2+1)/2 = 9 . Check

i 的最后一个元素-th 行的索引 = k(i,N) = N*(i+1)-i*(i+1)/2-1 .所以第 3 行的最后一个元素是 k(2,4) = 5*(2+1)-2*(2+1)/2-1 = 11 . Check

您可能需要的最后一部分是如何从数组索引 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=5 运行了这个, k=0..14得到如下结果:

Table of indexes

这是正确的! Check

要制作副本,只需使用 Array.Copy()在超快的元素上。此外,要执行加法和缩放等操作,您只需处理数组中减少的元素,而不是完整的 N*N。矩阵。矩阵乘法有点棘手,但可行。如果你愿意,也许你可以为此问另一个问题。

关于c# - 在 C# 中高效地复制对称矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9039189/

相关文章:

c# - 使用 C++ 和 C# 的 Visual Studio 2017 单元测试以及未发现的 C++ 测试

c# - 在 C# 中找不到 ExtractToDirectory

c# - uwp 中的 Wi-Fi 直连

c# - 单元测试顺序约定?

php - 多个 WordPress 循环

R 对 n 列中的每 n 行求和

java - 在集合中搜索同一对象的不同实例

java - 在 Wicket 口中创建带有循环的链接列表

matlab - 没有for循环的矩阵赋值元素

c++ - 指向特征矩阵的指针数组