【问题标题】:Make efficient - A symmetric matrix multiplication with two vectors in c#提高效率 - c# 中两个向量的对称矩阵乘法
【发布时间】:2012-05-29 22:27:46
【问题描述】:

按照cMinor的初始线程make efficient the copy of symmetric matrix in c-sharp

我会对如何使用矩阵的数组实现而不是经典的矩阵来构建具有一个线向量和一个列向量的对称方阵乘法的一些输入非常感兴趣

long s = 0;
List<double> columnVector = new List<double>(N); 
List<double> lineVector = new List<double>(N); 
//- init. vectors and symmetric square matrix m

for (int i=0; i < N; i++)
{
    for(int j=0; j < N; j++){
        s += lineVector[i] * columnVector[j] * m[i,j];
    }
}

感谢您的意见!

【问题讨论】:

    标签: c# performance vector matrix matrix-multiplication


    【解决方案1】:

    您可以使用不安全的代码快速进行矩阵乘法。我有blogged about it

    【讨论】:

    • 正确。如果目标是速度,那么不安全就是要走的路。如果对象是缩小尺寸的,那么 OP 中引用的缩小元素方法就是要走的路。
    • 我想知道 unsafe 与我帖子中的打包数组相比如何。您博客中的幼稚方法使用 2D 数组,该数组速度非常慢,应避免使用。最快的方法是交错数组,然后是打包数组,然后是原生二维数组。
    【解决方案2】:

    尽可能快地进行矩阵乘法很容易:使用知名库。大量的性能工作已进入此类库。你无法与之竞争。

    【讨论】:

      【解决方案3】:

      线向量乘以对称矩阵等于矩阵的转置乘以列向量。所以只需要考虑列向量的情况。

      原来y=A*xi-th元素被定义为

      y[i] = SUM( A[i,j]*x[j], j=0..N-1 )
      

      但由于A 是对称的,总和被分成总和,一个在对角线下方,另一个在对角线上方

      y[i] = SUM( A[i,j]*x[j], j=0..i-1) + SUM( A[i,j]*x[j], j=i..N-1 )
      

      从其他帖子来看,矩阵索引是

      A[i,j] = A[i*N-i*(i+1)/2+j]  // j>=i
      A[i,j] = A[j*N-j*(j+1)/2+i]  // j< i
      

      对于N×N 对称矩阵A = new double[N*(N+1)/2];

      C# 代码中,上面是:

      int k;
      for(int i=0; i<N; i++)
      {
          // start sum with zero
          y[i]=0;
          // below diagonal
          k=i;
          for(int j=0; j<=i-1; j++)
          {                    
              y[i]+=A[k]*x[j];
              k+=N-j-1;
          }
          // above diagonal
          k=i*N-i*(i+1)/2+i;
          for(int j=i; j<=N-1; j++)
          {
              y[i]+=A[k]*x[j];
              k++;
          }
      }
      

      供您尝试的示例:

      | -7  -6  -5  -4  -3 | | -2 |   | -5 |
      | -6  -2  -1   0   1 | | -1 |   | 21 |
      | -5  -1   2   3   4 | |  0 | = | 42 |
      | -4   0   3   5   6 | |  1 |   | 55 |
      | -3   1   4   6   7 | |  7 |   | 60 |
      

      要获得二次形式,请与乘法结果向量x·A·y = Dot(x,A*y)进行点积

      【讨论】:

      • 感谢您提供如此详细的答案并提供代码,我在几行代码中学到了很多东西。
      • 只是对我理解的一个小小的确认。在这种使用方形对称矩阵的特殊情况下,我们可以将两个向量都视为列向量(我们可以将其命名为 x 和 x')。这意味着如果我想获得两个向量的乘法结果,我可以通过使用“对角线下方”代码作为 y[i]+=A[k]*x[j]*x'[j] 一次性完成;等等“对角线以上”。我说的对吗?!
      • 你不会在同一个操作中同时考虑xx'。所以声明y[i]+=A[k]*x[j]*x'[j]not 有效的。也许您需要在原始帖子中包含一个示例,说明您正在尝试做什么。通常你会做类似scalar = x'*A*x的事情。
      • 还要考虑两个对称矩阵的乘积不是对称的。
      猜你喜欢
      • 2014-10-23
      • 1970-01-01
      • 1970-01-01
      • 2014-11-06
      • 2016-03-15
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多