У меня такой код:
n = 10000;
s = 100;
Z = rand(n, 2);
x = rand(s, 1);
y = rand(s, 1);
fun = @(a) exp(a);
В принципе, анонимная функция f
может иметь другую форму. Мне нужно создать два массива.
Во-первых, мне нужно создать массив размером n x s x s
с общими элементами
fun(Z(i, 1) - x(j)) * fun(Z(i, 2) - y(k))
где i=1,...n
, а j,k=1,...,s
. Что я могу легко сделать, так это построить матрицы, используя bsxfun
, например.
bsxfun(@(x, y) fun(x - y), Z(:, 1), x');
bsxfun(@(x, y) fun(x - y), Z(:, 2), y');
Но тогда мне нужно было бы объединить их в массив 3D
, поэлементно умножая каждый столбец этих двух матриц.
На втором этапе мне нужно создать массив размером n x 3 x s x s
, который с одной стороны выглядел бы как следующая матрица
[ones(n, 1), Z(:, 1) - x(i), Z(:, 2) - y(j);]
где i=1,...s
, j=1,...s
. Я мог бы перебрать два дополнительных измерения с помощью чего-то вроде
A = [ones(n, 1), Z(:, 1) - x(1), Z(:, 2) - y(1)];
for i = 1:s
for j = 1:s
A(:, :, i, j) = [ones(n, 1), Z(:, 1) - x(i), Z(:, 2) - y(j);];
end
end
Есть ли способ избежать петель?
На третьем шаге предположим, что после получения массива out1
(результат первого шага) я хочу создать новый массив out3
размерности n x n x s x s
, который содержит исходный массив out1
по главной диагонали, то есть out3(i,i,s,s) = out1(i, s, s)
и out3(i,j,s,s)=0
для всех i~=j
. Есть ли альтернатива diag
для создания «диагональных массивов»? В качестве альтернативы, если я создам массив n x n x s x s
нулей, есть ли способ поместить out1
на главной диагонали?