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

使用C计算稀疏矩阵每列的和,c,sparse-matrix,C,Sparse Matrix,我有一个大小为(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;

我有一个大小为(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]
有人能就如何处理这个问题提出建议吗? 请注意,这是一个示例矩阵,在实践中,我有大量的尺寸矩阵(15000行x 25000列)

有人能就如何处理这个问题提出建议吗

您可以创建一个列表来存储矩阵中的非零元素。为此,您需要一个结构来定义这样一个列表中的元素的外观:

struct sparseElement{
    int n;
    int m;
    int value;
}
然后,通过循环计算非零元素,将矩阵转换为这种稀疏形式。现在您知道有多少内存,可以分配内存:

sparseElement* sparse = malloc(n * sizeof(sparseElement))
其中
n
是非零元素的数量。然后你可以填写这个清单

使用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]
在列表中循环,并对列索引等于要计算总和的行的所有元素求和。如果您想一次性对所有列执行此操作,您可以创建一个列表,每个列有一个条目,然后将每个元素添加到相应的索引中

当然,这只是一个可能的实现。大型的、已建立的库使用更精细、更高效的结构/算法

有人能就如何处理这个问题提出建议吗

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

    许多操作需要行或列数据访问。一些操作(如有效的朴素矩阵乘法)要求两者兼而有之;特定的一个取决于矩阵在乘法运算符的哪一侧。一些操作得益于简单的转置。收集操作并按它们的需求对它们进行排序,可以为您提供选择“最佳”(最适合您的用例)实现的标准。

  • 选择适当的类型来描述矩阵中的值

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

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

  • 选择将用于实现稀疏矩阵的数据结构

    维基百科关于的文章描述了一些典型的结构(DOK、LIL、COO、CSR、CSC、耶鲁)。如果您实现了多个,那么您不仅需要对每个应用程序编写所有低级操作,还需要编写算术操作的所有组合。(例如,如果稀疏矩阵使用压缩稀疏行(CSR)或压缩稀疏列(CSC)格式,则需要四个矩阵乘法例程,具体取决于两个参数矩阵的类型(CSR×CSR、CSC×CSR、CSR×CSC、CSC×CSC),因为矩阵乘法是不可交换的。)

    若性能很重要,那个么应该仔细考虑各种数据结构的缓存效应。您需要在一个或多个阵列中按顺序检查内存,以利用CPU预取和缓存。如果有大量数据,您将希望尽可能地“打包”所有内容(因为内存带宽往往是矩阵操作的限制瓶颈),但要将处理每个矩阵元素所需的操作保持在最低限度。

  • 编写基本矩阵输入/输出例程和单元测试,以检查数据结构是否正常工作

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

  • 编写一个函数,给定稀疏矩阵M,返回行向量v,其中vi=∑ Mj,我

    换句话说,v中的元素i是i列中M的所有元素之和。

  • 为您的函数编写一个测试程序,并对其进行测试

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


  • “转换为稀疏矩阵”是什么意思?这看起来已经像是一个稀疏矩阵研究“稀疏矩阵实现”或类似的东西;这是最重要的结果之一,似乎非常有用。您现在在矩阵中使用的数据结构是什么?对于(我想是高效的)稀疏表示,您有什么想法?wikipedia页面提供了一些关于如何存储这些对象的建议。要编写转换函数,您还应该知道/告诉起始密集矩阵是如何实现的。@meowgoesthedog太棒了!这很有帮助,但因为我使用的是一个非常稀疏的矩阵,其中矩阵中的零的数量是非零元素数量的10倍,所以我正在寻找其他更好的选择。一个好的稀疏矩阵仍然具有良好的访问速度。这意味着节点是水平和垂直链接的,而不是一个简单的链接列表。@AnttiHaapala我使用的是一个非常稀疏的矩阵。每10个1,我就有近100个0。因为我正在处理原始问题中提到的巨大矩阵(大约15000行x 25000列),所以这种方法可行吗?或者我应该考虑使用其他方法吗?请为非常稀疏的矩阵推荐一个最好的。