乘以存储在一维数组算法中的上三角矩阵

Posted

技术标签:

【中文标题】乘以存储在一维数组算法中的上三角矩阵【英文标题】:Multiplying upper triangular matrix stored in 1D array alogrithm 【发布时间】:2016-01-15 04:03:54 【问题描述】:

我正在用 C++ 做上三角矩阵乘法。这些矩阵存储在一维数组而不是普通的二维数组中。该值逐行存储在数组中,底部的 0 被忽略。我做了很多数学,试图找出一个模式,但我仍然想不出一个算法。假设我有 2 个矩阵,每个矩阵都是正方形,并且这两个值都存储在一维数组 A 和 B 中。我想将结果存储在数组 C 中。我认为最难的部分是添加不同数量的在 for 循环运行时更改元素。

谁能给我一些启发?

【问题讨论】:

【参考方案1】:

假设整个矩阵的大小为N x N

在第一行row = 0,有N 元素。 在第二行 row = 1 中有 N - 1 元素。

...

在第 k 行,row = k,有 N - k 元素。

这是一个 ASCII 图表:

|<-               N                    ->|

+--+--+--+       ---            +--+--+--+
|  |  |  |                      |  |  |  |  row = 0, N elements
+--+--+--+       ---            +--+--+--+
   |  |  |                      |  |  |  |  row = 1, N-1 elements
   +--+--+       ---            +--+--+--+
      |  |                      |  |  |  |  row = 2, N-2 elements
      +--+       ---            +--+--+--+


                 ---            +--+--+--+
                                |  |  |  |  row = k, N-k elements
                 ---            +--+--+--+


                                +--+--+--+
                                |  |  |  |  row = N-3, 3 elements
                                +--+--+--+
                                   |  |  |  row = N-2, 2 elements
                                   +--+--+
                                      |  |  row = N-1, 1 element
                                      +--+

一维数组中存储这样一个矩阵所需的元素个数是:

1 + 2 + ... + N = N*(N+1)/2

要访问矩阵的元素,我们需要将行索引和列索引映射到一维数组中的索引。

获取第一行的j-th 列(行索引=0,列索引=j),

index = j

要获取第二行的j-th 列(行索引=1,列索引=j),

index = N + (j-1)

获取第三行的j-th 列(行索引=2,列索引=j),

index = N + (N-1) + (j-2)

...

获取i-th 行的j-th 列(行索引=i,列索引=j),

index = N + (N-1) + ... + (N-(i-1)) + (j-i)
      = N + N     +  .. + N
          - ( 1   +        + (i-1) )  + j-i
      = N * i - (i-1)*i/2 + (j-i)

有了上面的信息,你可以写出这样的函数:

    为上三角矩阵分配适量的内存 在给定行索引 (i) 和列索引 (j) 的情况下设置矩阵的值。 在给定行索引 (i) 和列索引 (j) 的情况下获取矩阵的值。

这应该足以将一个上三角矩阵与另一个上三角矩阵以及一个正则矩阵相乘。

【讨论】:

【参考方案2】:

我解决这个问题的方法是从索引形式的矩阵乘法的定义开始

(A B)i,j = sum_k Ai,k Bk, j

现在您需要一种方法将索引从 i,j 映射到您的一维数组中

int toArrayIndex(tuple<int,int> ij); // return -1 if not in array
tuple<int,int> toMatrixIndex(int arrayIndex);

那么你的函数看起来就像

for(int arrayIndex=0; i<maxArrayIndex; ++arrayIndex ) 
  tuple<int,int> ij = toArrayIndex(arrayIndex);
  for(int k=0; k<matrixSize; ++k) 
    tuple<int,int> ik = make_tuple( std::get<0>(ij), k );
    tuple<int,int> kj = make_tuple( k, std::get<1>(ij) );
    int ik_index = toMatrixIndex(ik);
    int kj_index =  toMatrixIndex(kj);
    if(ik_index < 0 || kj_index < 0) continue;
    ab[arrayIndex] += a[ik_index] * b[kj_index];
  

这不是最佳的,因为内部k 循环可以减小大小。

【讨论】:

以上是关于乘以存储在一维数组算法中的上三角矩阵的主要内容,如果未能解决你的问题,请参考以下文章

矩阵和串

.数据结构与算法基础(重点)

特殊矩阵的压缩存储

C语言一维数组转二维数组

408数据结构与算法—数组和特殊矩阵的压缩存储(二十五)

408数据结构与算法—数组和特殊矩阵的压缩存储(二十五)