Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.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
C 稀疏多维数据表示_C_Matrix_Sparse Matrix - Fatal编程技术网

C 稀疏多维数据表示

C 稀疏多维数据表示,c,matrix,sparse-matrix,C,Matrix,Sparse Matrix,我正在开发一个心脏模拟工具,它使用四维数据,即三维空间中的几个(3-30)变量 我现在添加了一些组织几何体,这些几何体将在组织外部的包含3D框中保留超过2/3的点进行模拟,因此我需要一种有效存储活动点而不是其他点的方法 关键是,我需要能够: 在受约束的三维长方体中迭代所有活动点(可能是迭代器?) 访问一个点后,找到它的正交邻域(x,y,z)+/-1 这可能不止一个问题!我主要关心的是如何有效地表示稀疏数据 我用的是C.你多久加一次纸巾,需要多长时间 一个简单的解决方案是使用链表+散列以及从一

我正在开发一个心脏模拟工具,它使用四维数据,即三维空间中的几个(3-30)变量

我现在添加了一些组织几何体,这些几何体将在组织外部的包含3D框中保留超过2/3的点进行模拟,因此我需要一种有效存储活动点而不是其他点的方法

关键是,我需要能够:

  • 在受约束的三维长方体中迭代所有活动点(可能是迭代器?)
  • 访问一个点后,找到它的正交邻域(x,y,z)+/-1
这可能不止一个问题!我主要关心的是如何有效地表示稀疏数据


我用的是C.

你多久加一次纸巾,需要多长时间

一个简单的解决方案是使用链表+散列以及从一个指向另一个的指针

意思是:

  • 保存包含所有相关点及其数据的链接列表
  • 保存一个散列以轻松获取此数据:键=坐标,数据=指向链接列表的指针
  • 操作的实施将是:
    添加一个框:浏览完整的链接列表,只将相关元素放入“工作”链接列表
    迭代:浏览“工作”链接列表
    查找邻居:查找哈希中的每个邻居

    复杂性:

    Add:O(n),迭代O(1)以查找下一个元素,邻居O(1)平均值(由于散列)

    如果要使用普通数组索引,可以使用mmap()在POSIX系统上创建稀疏数组:

    然后,您可以随意访问[x][y][z],它实际上只为每个被触摸的页面分配实际内存。数组将初始化为零字节

    如果您的系统没有MAP_ANONYMOUS,您可以通过从/dev/zero映射来实现相同的效果


    请注意,在许多系统上,将为整个阵列保留交换空间(尽管未使用)。

    首先,我认为值得考虑您的实际需求是什么。我怀疑这不仅仅是“以尽可能节省空间的方式存储活动点和其他点”,还包括一定数量的“将相邻点存储在附近的内存位置,以便获得良好的缓存行为”和“以可以高效执行查找的方式存储点”

    话虽如此,以下是我的建议。将整个3D区域划分为大小相同的立方体块。对于每个块,将块中的所有点存储在密集阵列中,包括用于确定每个点是否位于组织区域的布尔isTissue阵列。仅分配包含点的块。创建一个指向块的指针(密集)数组,对于未分配的块使用空指针

    因此,要找到(i,j)处的点,首先计算ii=i/blockside,jj=j/blocksize,然后在(ii,jj)处的块指针表中查找包含点的块。如果该指针为空,则您的点不在组织中。如果它是非空的,你看那个块中的(i mod blocksize,j mod blocksize),这就是你的(i,j)点。您可以检查它的isTissue标志,查看它是否为“当前”点

    您需要在最小化跨块边界的相邻点计算次数和最小化块中但不在组织区域中的点数量之间选择块大小作为平衡。我猜,至少您希望一行块成为缓存线的长度。可能最佳值要比这个大得多,尽管它至少在某种程度上取决于您的几何体

    要迭代三维长方体中的所有点,您可以只查找每个点,或者(更有效地)找出长方体接触的块,然后迭代长方体中这些块中的区域,跳过Istisue为false的区域

    如果您正在执行大量块的释放和重新分配,您可能希望通过将块放入“未使用”的池中,然后将块从该池中拉出,而不是重新分配来“释放”块。这还有一个优点,即这些块的所有点都已设置为“不存在”(因为这就是解除分配块的原因),因此不需要初始化它们


    有经验的读者可能会认识到这与并行计算数据布局方式之间的相似性;如果您有一个非常大的模拟,您可以轻松地将块分布在多个节点上,并且只需要为跨块计算进行跨节点通信。对于这类应用程序,您可能会发现嵌套级别的块非常有用,其中有元块(用于跨节点通信)包含较小的块(用于几何体)。

    我只是好奇。。。你会使用组织几何体数据进行某种渲染吗?我不完全清楚你的几何体是什么。您提到每个点都有正交的邻居,这意味着点的规则网格,但随后您提到的是稀疏数据。我的理解正确吗?你的点集本质上是规则网格上点的一个(连接的)子集?作为补充,如果你的几何体是强各向异性的——即,大部分由对齐的线或板组成的东西——你可能需要非立方体块。嗨,布鲁克斯,碰巧,大多数媒体访问不需要邻居。我怀疑这些点的访问时间的增加对总体运行时间几乎没有影响,只要它保持不变。谢谢你的回答。它帮助我澄清了我试图解决的问题,并让我以不同的方式思考。非常感谢。嗨,安娜,这似乎是最简单的解决方案,因此我最有可能实现它!再看看代码访问当前密集数组的方式,似乎
    float (*a)[500][500];
    
    a = mmap(0, (size_t)500 * sizeof a[0], PROT_READ | PROT_WRITE,
        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    
    if (a && (void *)a != MAP_FAILED)
    {
        /* a is now 500 x 500 x 500 sparse array of floats */