Как отобразить линии 3d-матрицы - PullRequest
0 голосов
/ 09 июня 2019

Я хочу передать все линии (в определенном измерении) 3d-матрицы через функцию, которая принимает массивы.Я знаю, что могу сделать это с двумя циклами for, но это не идея.

Я пытался использовать arrayfun, но не мог заставить его работать.

linemean=@(x) mean(x)  %it's just an example of fucntion
m=rand(3,3,3)

, чтобы я могиметь в конце матрицу 3x3, элементы которой соответствуют значению строки, примененному к каждой строке m (i, j, :).Любая помощь будет отличной.Спасибо.

Ответы [ 2 ]

1 голос
/ 09 июня 2019

Специально для функции mean:

A = rand(3,3,3);
result = mean(A,3);

Для произвольной функции:

A = rand(3,3,3);
func = @(x) mean(x);
C = mat2cell(A,ones(1,size(A,1)),ones(1,size(A,2)),size(A,3));
result = cellfun(func,C);

Примечание 1: mat2cell разбивает матрицу на отдельные меньшие матрицы, сохраняя их в массиве ячеек. Как я это назвал выше, он рассекает матрицу по 1-му и 2-му измерениям, создавая массив ячеек (3x3), содержащий матричный массив (1x1x3) в каждой ячейке.

Примечание 2: mean вычисляет среднее значение по первому не-одиночному измерению, следовательно, в каждой ячейке с измерениями (1x1x3) вдоль 3-го измерения. Если ваш произвольный функционал работает иначе, например. Суммы строго по 1-му измерению, вы можете изменить свою произвольную функцию на что-то вроде func = @(x) arbitrFunc(squeeze(x)). squeeze удалит одноэлементные измерения, превращая каждую ячейку в матрицу (3x1).

0 голосов
/ 09 июня 2019

Если вы просто хотите векторизовать вычисления, вы можете сделать это следующим образом:

Измените m на 3 на size(m,1)*size(m,2) (каждый столбец является "линией" в 3-мерном измерении). Выполните вычисления для каждого из столбцов и измените форму на 2D матрицу:

M = reshape(permute(m, [3, 1, 2]), [size(m,3), size(m,1)*size(m,2), 1]);
m_means = reshape(mean(M, 1), [size(m,1), size(m,2)]);

В случае, если вы должны использовать arrayfun, у меня есть решение, но оно немного неловко:

Решение предполагает, что m является константой (не параметром для arrayfun).

% %Prepare 3x4x3 natrix for testing
m = cat(3, [1 2 3 4; 5, 6, 7, 8; 9, 10, 11, 12], [21 22 23 24; 25, 26, 27, 28; 29, 30, 31, 32], [41 42 43 44; 45, 46, 47, 48; 49, 40, 41, 42]);

%For testing:
%linemean=@(x) disp(num2str(m(floor(x/size(m,2))+1, mod(x, size(m,1))+1, :)));

%Use floor and mod for computing indices (ind2sub did't work)
linemean = @(x) mean(m(mod(x, size(m,1))+1, floor(x/size(m,1))+1, :));

%Apply arrayfun on array of indices 0:11
m_means = arrayfun(linemean, 0:size(m,1)*size(m,2)-1);

%Reshape to size of m
m_means = reshape(m_means, size(m,1), size(m,2))

Результат:

m_means =

21.0000 22.0000 23.0000 24.0000
25.0000 26.0000 27.0000 28.0000
29.0000 26.6667 27.6667 28.6667

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...