使用 C 计算稀疏矩阵每一列的总和

Calculate the sum of each column of a sparse matrix using C

我有一个大小为 (8 x 8) 的矩阵,如下所示,我必须将其转换为一种稀疏矩阵形式,并使用 C 语言计算每一列的非零元素之和。

 Matrix =   [1 2 0 4 0 0 0 0;
             0 1 3 0 2 0 0 0;
             1 0 4 7 0 0 0 0;
             0 6 0 0 1 8 0 0;
             0 0 0 0 4 0 0 0;
             0 0 0 0 8 1 1 0;
             0 0 0 0 9 0 2 0;
             0 0 0 0 0 0 7 1]

有人可以建议如何处理这个问题吗? 请注意,这是一个样本矩阵,实际上我有大约(15,000 行 x 25,000 列)

的巨大维度矩阵

Could someone please advise on how to proceed on this problem?

你创建了一个列表来存储矩阵的非零元素。为此,您需要一个结构来定义此类列表的元素的外观:

struct sparseElement{
    int n;
    int m;
    int value;
}

然后通过循环遍历矩阵,计算非零元素,将矩阵转换为这种稀疏形式。既然知道有多少,就可以分配内存了:

sparseElement* sparse = malloc(n * sizeof(sparseElement))

其中 n 是非零元素的数量。然后就可以填写列表了。

compute the sum of non-zero elements for each column using C language.

您遍历列表并对列索引等于您为其计算总和的行的所有元素求和。如果您想一次性对所有列执行此操作,您可以制作一个列表,每列一个条目,然后将每个元素添加到相应的索引中。

当然,这只是一种可能的实现方式。大型、成熟的图书馆使用更精细和高效的 structures/algorithms.

Could someone please advise on how to proceed on this problem?

  1. 找出稀疏矩阵上的所有必需和可选操作。

    许多操作需要按行或按列访问数据。一些操作(如高效的朴素矩阵乘法)需要两者;特定的取决于矩阵在乘法运算符的哪一侧。一些操作受益于简单的转置。收集操作并根据它们的要求对它们进行排序,为您提供了可用于选择 "best"(最接近您的用例的最佳)实施的标准。

  2. 选择合适的类型来描述矩阵中的值。

    特别是,我建议考虑 float、double、unsigned char、signed char、uintN_t 和 intN_t 类型(对于 N = 8、16、32 或 64)。

    您需要精度和范围来描述您拥有的值,而不是为了您不需要的精度或范围而浪费内存。

  3. 选择您将用于实现稀疏矩阵的数据结构。

    sparse matrix 上的维基百科文章描述了一些典型的结构(DOK、LI​​L、COO、CSR、CSC、Yale)。如果您实现多个,则不仅需要为每个编写所有低级操作,还需要为算术运算编写所有组合。 (例如,如果您的稀疏矩阵使用压缩稀疏行 (CSR) 或压缩稀疏列 (CSC) 格式,那么根据两个参数矩阵的类型(CSR×CSR, CSC×CSR, CSR×CSC, CSC×CSC), 因为矩阵乘法不可交换。)

    如果性能很重要,则应仔细考虑各种数据结构的缓存效果。您需要在一个或多个数组中按顺序检查内存,以利用 CPU 预取和缓存。如果有大量数据,您将希望 "pack" 一切都尽可能紧凑(因为内存带宽往往是矩阵运算的限制瓶颈),但将处理每个矩阵元素所需的运算保持在最低限度.

  4. 编写基本矩阵 input/output 例程和单元测试以检查您的数据结构是否正常工作。

    通常,您需要读取和写入这些矩阵 from/to 文件或流(如标准输入和输出)。先写这些。然后,编写一些描述矩阵数据存储方式的调试函数。至少,您需要编写一个测试程序来读取矩阵(从标准输入)、打印它(到标准输出)和存储格式(到标准错误);您可以为它提供一些测试用例输入(至少一个带有随机数据)以查看往返是否保留了正确的数据。我经常使用 awk 来生成测试数据集,并将数值输出与预期的数值输出进行比较。

  5. 写一个给定稀疏矩阵M,returns一个行向量v的函数,其中vi = ∑Mj,i

    也就是说v中的元素iM[=68=所有元素的和] 在列 i.

  6. 为你的功能编写一个测试程序,并进行测试。

    通常,您会希望程序读取矩阵(从标准输入),并将向量写入标准输出。