三重加权和

phd*_*ent 3 matlab vectorization weighted-average

我试图对某个加权和进行矢量化,但却无法弄清楚如何去做.我在下面创建了一个简单的最小工作示例.我想这个解决方案涉及bsxfun或reshape和kronecker产品,但我仍然没有设法让它工作.

rng(1);
N = 200;
T1 = 5;
T2 = 7;
T3 = 10;


A = rand(N,T1,T2,T3);
w1 = rand(T1,1);
w2 = rand(T2,1);
w3 = rand(T3,1);

B = zeros(N,1);

for i = 1:N
 for j1=1:T1
  for j2=1:T2
   for j3=1:T3
    B(i) = B(i) + w1(j1) * w2(j2) * w3(j3) * A(i,j1,j2,j3);
   end
  end
 end
end

A = B;
Run Code Online (Sandbox Code Playgroud)

对于二维情况下,有一个聪明的答案在这里.

Sue*_*ver 5

您可以使用额外的乘法来修改w1 * w2'前一个答案中的网格,然后再乘以w3.然后,您可以再次使用矩阵乘法乘以"扁平"版本A.

W = reshape(w1 * w2.', [], 1) * w3.';
B = reshape(A, size(A, 1), []) * W(:);
Run Code Online (Sandbox Code Playgroud)

您可以将权重的创建包装到它自己的函数中,并使其可以推广到N权重.由于这使用递归,N因此仅限于当前的递归限制(默认为500).

function W = createWeights(W, varargin)
    if numel(varargin) > 0
        W = createWeights(W(:) * varargin{1}(:).', varargin{2:end});
    end
end
Run Code Online (Sandbox Code Playgroud)

并使用它:

W = createWeights(w1, w2, w3);
B = reshape(A, size(A, 1), []) * W(:);
Run Code Online (Sandbox Code Playgroud)

更新

使用@ CKT的一个非常好的建议来使用kron,我们可以createWeights稍微修改一下.

function W = createWeights(W, varargin)
    if numel(varargin) > 0
        W = createWeights(kron(varargin{1}, W), varargin{2:end});
    end
end
Run Code Online (Sandbox Code Playgroud)