Индексы граничных элементов 3D матрицы - PullRequest
1 голос
/ 13 марта 2020

У меня есть 3D-матрица 65x76x100, где каждый элемент содержит тип материала. Я назначил динамику каждому элементу, но динамика пограничных элементов (или границы, или экстерьера, или периметра, или как вы хотите это называть) неверна и должна быть удалена. Мне требуются все линейные индексы граничных элементов, в настоящее время я делаю это так (и это работает):

    materials; % given 65x76x100 3D-matrix;
    [nxgrid, nygrid, nzgrid] = size(materials);
    n = nxgrid*nygrid*nzgrid;
    N2 = nxgrid*nygrid;
    borderIndices = zeros(n, 1); % initialize an oversized matrix that contains the border indices
        for l = 1:nzgrid % loop over zgrid
            for k = 1:nygrid % loop over ygrid
                for j = 1:nxgrid % loop over xgrid
                    if (j==1)||(j==nxgrid)||(k==1)||(k==nygrid)||(l==1)||(l==nzgrid)
                        i = (l-1)*N2 +(k-1)*nxgrid+j; % subscript to linear index
                        borderIndices(i) = i;
                    end
                end
            end
        end

Эти вложенные циклы for кажутся мне немного избыточными. Есть ли более оптимальный / лучший / более чистый способ решить эту проблему?

1 Ответ

1 голос
/ 14 марта 2020

Вы можете сделать это легко следующим образом:

  1. Создать трехмерный массив с true на границе и false в противном случае, используя or (|) с неявное расширение .
  2. Применить find с одним выходом, чтобы получить линейные индексы этого.

indices = find([1; zeros(size(materials,1)-2,1); 1] | ...
               [1, zeros(1,size(materials,2)-2), 1] | ...
               reshape([1, zeros(1,size(materials,3)-2), 1], 1, 1, []));

Если вы хотите получить результат, как в вашем коде (с нулями между индексами):

indices_with_zeros(indices) = indices;
...