【问题标题】:Large, mostly empty data structure for tetrahedron faces用于四面体面的大型、大部分为空的数据结构
【发布时间】:2012-10-04 09:57:27
【问题描述】:

我正在尝试将四面体中每个面的节点 ID 与其对应的四面体 ID 链接起来。

tetras = [1 2 3 4  % Tetra 1
          5 6 7 8] % Tetra 2

对于 tetra 1,有四个面:

faces = [1 2 3; 1 2 4; 1 3 4; 2 3 4] % Notice these are sorted

然后我想将这些存储在数据结构中:

tet_for_face = cell(8,8,8) % 8 allows for the maximum node id

tet_for_face{1,2,3} = 1;
tet_for_face{1,2,4} = 1;
tet_for_face{1,3,4} = 1;
tet_for_face{2,3,4} = 1;

这意味着我可以在 O(1) 中找到任何特定面孔的 tetra ID:

tet_for_face{2,3,3}
ans = []
tet_for_face{2,3,4}
ans = 1

这种方法的问题在于它需要连续的内存。随着我的网格变大,我的内存不足:

cell(1000, 1000, 1000)
??? Error using ==> cell
Out of memory. Type HELP MEMORY for your options.

我也尝试过使用嵌套单元格:

tet = cell(num_nodes, 1);
tet2 = cellfun(@(x) cell(num_nodes, 1), tet, 'UniformOutput', 0);
tet3 = cellfun(@(x) cellfun(@(y) cell(num_nodes, 1), x, 'UniformOutput', 0), tet2, 'UniformOutput', 0);

tet3{2}{3}{4} = 1;
...

虽然这适用于小网格,并且不需要连续内存 (AFAIK),但它有一个令人讨厌的习惯,即在 N=1000 时使 MATLAB 崩溃。

有什么想法吗?

【问题讨论】:

  • 你有没有想过使用sparse数组?
  • @HighPerformanceMark 我去看看,干杯!
  • 键的字符串/哈希表示如何,并使用containers.Map

标签: matlab data-structures tetrahedra


【解决方案1】:

在玩了一些稀疏数组(只能是 1D 或 2D,而不是 3D)之后,我决定使用containers.Map (HashMap)。

我使用了字符串键,我发现生成它们的最快方法是使用 sprintf(而不是 int2str 或 mat2str)

示例代码:

tet = containers.Map;
for tetra_id in tetras 
    for face in faces
        face_key = sprintf('%d ', face);
        tet(face_key) = tetra_id;

这给了我一张这样的地图:

tet('1 2 3') = 1

【讨论】:

  • +1:通过 MATLAB 高效使用数据结构,并通过 post & answer 进行演示。
【解决方案2】:

您可以使用稀疏矩阵来处理网格产生的许多问题。这取决于您在实践中要如何使用此数据结构,但这里有一个示例:

% tetras and faces are transposed - column-wise storage
tetras = [1 2 3 4; 5 6 7 8]';
faces = [1 2 3; 1 2 4; 1 3 4; 2 3 4]';

ntetras    = size(tetras, 2);
nfaces     = size(faces, 2);
nfacenodes = size(faces, 1);

% construct face definitions for all tetras
tetras_faces = reshape(tetras(faces, :), nfacenodes, ntetras*nfaces);

% assign the faces to tetras keeping the face id within the tetra, if you need it
enum_faces  = repmat(1:ntetras*nfaces, nfacenodes, 1);

% create a sparse matrix connecting tetra faces to tetras.
% Every column contains 3 non-zeros - 1 for every node in a face
% The number of matrix columns is ntetras*nfaces - 4 columns for every element.
A = sparse(tetras_faces, enum_faces, 1);

现在要提取您需要的信息,您可以将 A 乘以包含您要查找的面部信息的向量:

v = sparse(ntetras*nfaces, 1);
v([1 2 3]) = 1;
tetra_id = ceil(find(A*v==nfacenodes)/nfaces)

请注意,这只是一个示例。您可以通过这种方式提取更多有用的信息,并且可以使用矩阵-矩阵乘法而不是矩阵-向量乘法执行更复杂的搜索。

【讨论】:

  • 谢谢 - 我玩得很开心,但决定改用 container.Map。
猜你喜欢
  • 2017-12-04
  • 1970-01-01
  • 2021-06-04
  • 2016-05-24
  • 1970-01-01
  • 2022-10-17
  • 2015-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多