使用带有匿名函数的bsxfun生成数组并逐元素减法-MATLAB [英] Generating arrays using bsxfun with anonymous function and for elementwise subtractions - MATLAB

查看:78
本文介绍了使用带有匿名函数的bsxfun生成数组并逐元素减法-MATLAB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

n = 10000; 
s = 100;
Z = rand(n, 2);
x = rand(s, 1);
y = rand(s, 1);
fun = @(a) exp(a);

原则上,匿名函数f可以具有其他形式.我需要创建两个数组.

In principle, the anonymous function f can have a different form. I need to create two arrays.

首先,我需要使用通用元素创建大小为n x s x s的数组

First, I need to create an array of size n x s x s with generic elements

fun(Z(i, 1) - x(j)) * fun(Z(i, 2) - y(k))

其中i=1,...nj,k=1,...,s.我可以轻松地做的是使用bsxfun构造矩阵,例如

where i=1,...n while j,k=1,...,s. What I can easily do, is to construct matrices using bsxfun, e.g.

bsxfun(@(x, y) fun(x - y), Z(:, 1), x');
bsxfun(@(x, y) fun(x - y), Z(:, 2), y');

但是接下来,我需要通过将这两个矩阵的每一列相乘,将它们组合为3D数组.

But then I would need to combine them into 3D array by multiplying element-wise each column of those two matrices.

第二步,我需要创建一个大小为n x 3 x s x s的数组,该数组从一侧看起来像下面的矩阵

In the second step, I need to create an array of size n x 3 x s x s, which would look from one side as the following matrix

[ones(n, 1), Z(:, 1) - x(i), Z(:, 2) - y(j);]

其中i=1,...sj=1,...s.我可以用类似的东西来遍历两个额外的维度

where i=1,...s, j=1,...s. I could loop over the two extra dimensions with something like

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

是否有避免循环的方法?

Is there a way to avoid loops?

在第三步中,假设在获得数组out1(第一步的输出)之后,我想创建一个尺寸为n x n x s x s的新数组out3,该数组在主数组中包含原始数组out1.对角线,即所有i~=jout3(i,i,s,s) = out1(i, s, s)out3(i,j,s,s)=0. diag是否有某种创建对角数组"的替代方法?另外,如果我创建一个由零组成的n x n x s x s数组,是否可以将out1放在主对角线上?

In the third step, suppose that after obtaining array out1 (output from first step), I want to create a new array out3 of dimension n x n x s x s, which contains the original array out1 on the main diagonal, i.e. out3(i,i,s,s) = out1(i, s, s) and out3(i,j,s,s)=0 for all i~=j. Is there some kind of alternative of diag for creating "diagonal arrays"? Alternatively, if I create n x n x s x s array of zeros, is there a way to put out1 on the main diagonal?

推荐答案

代码

exp_Z_x = exp(bsxfun(@minus,Z(:,1),x.')); %//'
exp_Z_y = exp(bsxfun(@minus,Z(:,2),y.')); %//'
out1 = bsxfun(@times,exp_Z_x,permute(exp_Z_y,[1 3 2]));

Z1 = [ones(n,1) Z(:,1) Z(:,2)];
X1 = permute([ zeros(s,1) x zeros(s,1)],[3 2 1]);
Y1 = permute([ zeros(s,1) zeros(s,1) y],[4 2 3 1]);
out2 = bsxfun(@minus,bsxfun(@minus,Z1,X1),Y1);

out3 = zeros(n,n,s,s); %// out3(n,n,s,s) = 0; could be used for performance
out3(bsxfun(@plus,[1:n+1:n*n]',[0:s*s-1]*n*n)) = out1; %//'

%// out1, out2 and out3 are the desired outputs

这篇关于使用带有匿名函数的bsxfun生成数组并逐元素减法-MATLAB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆