У меня есть матрица материалов, где значения указывают тип материала (значение от 1 до 8). Каждое значение ниже 5 указывает на «интересный» материал. Теперь в определенный момент я хочу подвести итог неинтересным соседским материалам. Таким образом, в 3D-матрице результат в одной точке может быть в диапазоне от 0 до 6. Одна из проблем заключается в том, что «текущая» точка находится на краю 3D-матрицы. Я могу решить эту проблему, используя 3 очень дорогих цикла for:
materials; % given 3D matrix i.e. 97*87*100
matrixSize = size(materials);
n = matrixSize(1)*matrixSize(2)*matrixSize(3); * total number of points
materialsFlattened = reshape(materials, [n 1]); % flattened materials matrix from a 3D matrix to a 1D matrix
pageSize = matrixSize(1)*matrixSize(2); % size of a page in z-direction
interestingMaterials = materialsFlattened(:) < 5; % logical vector indicating if the materials are interesting
n_bc = zeros(obj.n, 1); % amount of neighbour non-interesting materials
for l = 1:matrixSize(3) % loop over all z
for k = 1:matrixSize(2) % loop over all y
for j = 1:matrixSize(1) % loop over all x
n_bc(sub2ind(matrixSize,j,k,l)) = ...
~interestingMaterials(sub2ind(matrixSize,j,k,max(1, l-1)))...
+ ~interestingMaterials(sub2ind(matrixSize,j,max(1,k-1),l))...
+ ~interestingMaterials(sub2ind(matrixSize,max(1, j-1),k,l))...
+ ~interestingMaterials(sub2ind(matrixSize,min(matrixSize(1),j+1),k,l))...
+ ~interestingMaterials(sub2ind(matrixSize,j,min(matrixSize(2),k+1),l))...
+ ~interestingMaterials(sub2ind(matrixSize,j,k,min(matrixSize(3),l+1)));
end
end
end
Так что обратите внимание, что сначала я сглаживаю матрицу в 1D матрицу, используя форму. Операторы min
и max
гарантируют, что я не go выйду за пределы матрицы; вместо этого я беру ценность материала, где я в настоящее время нахожусь. Для моего приложения важна скорость, и я надеялся, что смогу избавиться от этой уродливой структуры l oop в l oop. Часто это возможно в MATLAB, так как поэлементная индексация удивительна, а иногда и своего рода волхвы c.