Октава: как реализовать внешний продукт для произвольных функций и произвольного числа аргументов? - PullRequest
0 голосов
/ 01 июля 2018

Теперь я могу сказать, что в 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})
...