四面体面大,大部分是空的数据结构(Large, mostly empty data structur

2019-09-23 12:26发布

我试图与它的相应的四id来每个人脸上的节点ID四面体链接。

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

对于四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任何特定面部的四ID(1):

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的坏习惯。

有任何想法吗?

Answer 1:

有点稀疏阵列(只能是一维或二维,三维不)打球,而不是在任何地方得到之后,我决定去与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


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);

现在,提取你需要,你可以通过按住你正在寻找的面部信息的矢量乘以信息:

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

请注意,这只是一个例子。 您可以提取更多的有用信息,这样一来,你可以执行使用矩阵的矩阵乘法,而不是矩阵向量乘法更复杂的搜索。



文章来源: Large, mostly empty data structure for tetrahedron faces