我正在尝试将四面体中每个面的节点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)中找到任何特定面部的四维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。
有什么想法吗?
答案 0 :(得分:2)
在玩了一些稀疏数组(只能是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 :(得分:1)
您可以使用稀疏矩阵来处理网格出现的许多问题。这取决于你在实践中想要对这个数据结构做什么,但这里有一个例子:
% 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)
请注意,这只是一个例子。您可以通过这种方式提取更多有用的信息,并且可以使用矩阵 - 矩阵乘法而不是矩阵向量乘法来执行更复杂的搜索。