Теперь я могу сказать, что в Mathematica вы можете использовать общий внешний продукт , действующий на заданную функцию f
и некоторые списки l1
, l2
, l3
, ..., ln
такой, что вывод out
представляет собой n
-D-массив / список с элементами out(i1,i2,...,in) = f(l1(i1),l2(i2),...,ln(in))
. Функция может делать все что угодно.
Как вы делаете то же самое в Octave / Matlab? Можете ли вы указать мне на существующую функцию и как ее использовать?
Я знаю о arrayfun
, cellfun
и bsxfun
, но, может быть, я не совсем понимаю, как их использовать.
Моя попытка до сих пор следующая
%% outer product for anonymous function returning a cell
function out = outerf2(f,c1,c2)
l1 = length(c1);
l2 = length(c2);
out = {};
for i = 1:l1 for j = 1:l2
out{i,j} = f(c1{i},c2{j});
endfor endfor
endfunction
function out = outerf3(f,c1,c2,c3)
l1 = length(c1);
l2 = length(c2);
l3 = length(c3);
out = {};
for i = 1:l1 for j = 1:l2 for k = 1:l3
out{i,j,k} = f(c1{i},c2{j},c3{k});
endfor endfor endfor
endfunction
Функция outerf2
принимает любой дескриптор функции или анонимную функцию и оценивает ее для всех комбинаций элементов ячеек c1
и c2
. Функция outerf3
делает то же самое, но для 3 ячеек.
Тест 1 (см. Код ниже): анонимная функция с матричным произведением.
Каждый из элементов выходной ячейки temp1
представляет собой матрицу 3x5 (результат соответствующего матричного произведения).
Тест 2 (см. Код ниже): анонимная функция с использованием тензорного произведения
Каждый из элементов выходной ячейки temp2
представляет собой 4-D-массив с размерами [3,4,4,5] (результаты соответствующего тензорного произведения и скалярного умножения элемента c3
). Норма Фробениуса (квадратный корень из суммы квадратов всех элементов массива) просто используется для проверки того, что результаты совпадают, см. этот вопрос , если вы хотите знать определения, но конкретные функции не важны.
%% Generate example cells
c1 = cellfun(@(i) rand(3,4),{1,2,3,4},"UniformOutput",false);
c2 = cellfun(@(i) rand(4,5),{1,2,3},"UniformOutput",false);
c3 = cellfun(@(i) rand(),{1,2,3,4,5,6},"UniformOutput",false);
%% Test 1
temp1 = outerf2(@(a1,a2) a1*a2,c1,c2);
size(temp1)
norm(temp1{2,3}-c1{2}*c2{3})
%% Test 2
% Tensor product
function out = tp(a,b)
da = size(a);
db = size(b);
out = reshape(a(:)*(b(:)'),[da,db]);
endfunction
% Frobenius norm
function out = normf(a)
out = sqrt(sum(a(:).*a(:)));
endfunction
temp2 = outerf3(@(a1,a2,a3) tp(a1,a2)*a3,c1,c2,c3);
size(temp2)
size(temp2{2,3,5})
normf(temp2{2,3,5}-tp(c1{2},c2{3})*c3{5})