Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Graph 压缩稀疏行(CSR)稀疏矩阵元素的快速访问_Graph_Fortran_Sparse Matrix_Circuit_Pardiso - Fatal编程技术网

Graph 压缩稀疏行(CSR)稀疏矩阵元素的快速访问

Graph 压缩稀疏行(CSR)稀疏矩阵元素的快速访问,graph,fortran,sparse-matrix,circuit,pardiso,Graph,Fortran,Sparse Matrix,Circuit,Pardiso,我想测试一些较新的稀疏线性解算器,我想知道是否有一种快速填充矩阵的方法。我感兴趣的格式是CSR(http://goo.gl/hLXYd). 假设CSR格式的矩阵如下所示: values(num non-zero elements) columns(num non-zero elements) rowIndex(num rows + 1) 所考虑的稀疏矩阵来自网络。所以,我有数千个节点,其中一些通过线连接在它们之间。因此,矩阵在结构上是对称的。每个连接(i,j)向对角项(i,i)和(j,j)以及

我想测试一些较新的稀疏线性解算器,我想知道是否有一种快速填充矩阵的方法。我感兴趣的格式是CSR(http://goo.gl/hLXYd). 假设CSR格式的矩阵如下所示:

values(num non-zero elements)
columns(num non-zero elements)
rowIndex(num rows + 1)
所考虑的稀疏矩阵来自网络。所以,我有数千个节点,其中一些通过线连接在它们之间。因此,矩阵在结构上是对称的。每个连接(i,j)向对角项(i,i)和(j,j)以及非对角项(i,j)和(j,i)添加一些内容。我可以在相同的节点(I,j,1),(I,j,2)之间有几个连接。。。因此,我可能需要不止一次地重温2个对角元素和2个非对角元素

我知道我可以通过执行rowIndex(I)来获得行的开头。然后,我必须遍历元素列(rowIndex(I):rowIndex(I+1)-1)以找到j所在的位置

问题:

是否有一种方法可以在CSR格式下更快地访问元素,而无需每次更新元素时都进行搜索

一些澄清: 我只需要从头开始填写矩阵。矩阵在结构上是对称的,而不是真正对称的。保存的值与网络数据(阻抗、电阻等)有关,它们具有真实值。一般值(i,j)值(j,i)。我有以下形式的元组(name1、i1、j1、value1)、(name2、i2、j2、value2)等。这些元组没有排序,2个元组可以引用相同的I、j值,这意味着需要添加它们


提前谢谢

您的问题似乎混淆了两个截然不同的问题:

  • 以CSR形式创建矩阵的快速方法是什么
  • 是否有更快的方法从已存储在CSR表单中的矩阵中读取值?(即比您描述的直接方法更快)
  • 以下是两个答案:

  • 一般来说,将网络数据从任何形式读入类似a的内容中(其他中间形式可用,并且可能出于速度或其他原因对您更具吸引力);然后将中间结构转换为矩阵的CSR形式。下面将对此进行详细介绍
  • 我不这么认为,不是以CSR形式存储的矩阵。这种相对缓慢的访问是您为节省空间而付出的代价的一部分。你用时间换空间,或者用空间换时间,这取决于你的观点

  • 你对输入数据的描述表明,你应该考虑设计自己的中间格式来编组原始数据。因为你的邻接矩阵是对称的,你只需要以任何形式存储它的一半。此外,您可能不需要沿主对角线存储元素——我猜节点

    I
    总是连接到节点
    I
    ,或者从不连接,因此网络的性质决定了存储在
    (I,I)
    的值。我有点不确定要在矩阵的每个节点上存储的信息,是
    I
    j
    之间的连接数还是其他什么?

    您拥有的是所谓的三重稀疏格式。CRS的创建,包括删除重复条目和求和值,可以非常有效地实现。在自己编写程序之前,先看一下。它是用C写的,但我相信你会理解它的原理。您感兴趣的是
    cholmod_triplet.c
    文件,它实现了您需要的功能

    本质上,转换是使用行和列索引上的两阶段桶排序来执行的。该算法具有线性复杂度,如果您对处理大型数据集感兴趣,这一点很重要

    编辑如果要同时跳过三元组格式的显式创建,可以通过动态生成
    (行,列)
    连接并将其添加到动态稀疏结构中来完成。我通常使用插入排序和排序列表,这在实践中是最快的。它也比三重态到CRS的转换快,并且使用更少的内存。方法如下:

    • 如果您大致知道每行中有多少个非零条目,那么对于每一行,您将预分配一个(空)列索引数组,以及一个单独的数组,用于该大小的值(不是链表,而是一个简单数组)。差不多

      static\u list\u cols[row]=malloc(sizeof(int)*预期的非零数量)
      static\u list\u vals[row]=malloc(sizeof(double)*预期的非零数量)

    • 如果您不知道这一点,您可以选择一个初始大小,并在行列表已满时根据需要重新分配(使用一些足够大的块大小以避免重新分配开销)

    • 对于每个
      (行,列)
      对,使用插入排序将
      插入到与
      对应的排序列表中。对于小的(多达几百个)非零每行线性搜索是最快的。对于每行非零的较大数量,可以使用二分法找到插入
      列的正确位置
    • col
      通过移动排序列表中具有较高列索引的非零项,插入到排序列表的
      行中。这是对缓存友好的,因为实际上这些行很小,可以放入当前的任何缓存中
    • 完成后,您需要通过将单个行列表复制到最后的
      列中,将单个排序列表组装到有效的CRS结构中。价值观也是如此
    • 如果您确定某些行可以有零个条目,那么可以通过预分配静态“列表数组”来避免最后一步。因此,每行的条目数是恒定的,其中一些条目可能为零。有时候也可以
    这种方法比使用三重态到稀疏态的转换要快,至少对于FEM mod来说是这样