6

我拼命地试图避免forMatlab 中的循环,但我不知道该怎么做。情况如下:

我有两个m x n矩阵AB两个向量vw长度d。我想进行外乘Av这样我就得到了一个m x n x d矩阵,其中(i,j,k)条目是,对于andA_(i,j) * v_k也是类似的。Bw

之后,我想添加结果m x n x d矩阵,然后mean沿着最后一个维度取回一个m x n矩阵。

我很确定我可以处理后一部分,但第一部分让我完全卡住了。我尝试使用bsxfun无济于事。有人知道这样做的有效方法吗?非常感谢!

编辑:此修订版是在以下三个很好的答案之后进行的。毫无疑问,gnovice 对我提出的问题有最佳答案。但是,我要问的问题涉及在取平均值之前对每个条目进行平方。我最初忘记提及这部分。鉴于这种烦恼,其他两个答案都很好,但是这次在编码之前做代数的聪明技巧并没有帮助。谢谢大家的帮助!

4

4 回答 4

7

编辑:

即使问题中的问题已经更新,仍然可以使用代数方法来简化问题。您仍然不必为 3-D 矩阵而烦恼。你的结果将是这样的:

output = mean(v.^2).*A.^2 + 2.*mean(v.*w).*A.*B + mean(w.^2).*B.^2;

如果您的矩阵和向量很大,与使用BSXFUNREPMAT的解决方案相比,由于所需的内存量减少,此解决方案将为您提供更好的性能。


解释:

假设M是在沿第三维取平均值之前得到的 m×n×d 矩阵,这就是沿第三维的跨度将包含的内容:

M(i,j,:) = A(i,j).*v + B(i,j).*w;

换句话说,v按比例缩放A(i,j)的向量加上按比例缩放的w向量B(i,j)。这就是你应用元素平方时得到的结果:

M(i,j,:).^2 = (A(i,j).*v + B(i,j).*w).^2;
            = (A(i,j).*v).^2 + ...
              2.*A(i,j).*B(i,j).*v.*w + ...
              (B(i,j).*w).^2;

现在,当您在第三个维度上取平均值时,每个元素的结果output(i,j)将如下所示:

output(i,j) = mean(M(i,j,:).^2);
            = mean((A(i,j).*v).^2 + ...
                   2.*A(i,j).*B(i,j).*v.*w + ...
                   (B(i,j).*w).^2);
            = sum((A(i,j).*v).^2 + ...
                  2.*A(i,j).*B(i,j).*v.*w + ...
                  (B(i,j).*w).^2)/d;
            = sum((A(i,j).*v).^2)/d + ...
              sum(2.*A(i,j).*B(i,j).*v.*w)/d + ...
              sum((B(i,j).*w).^2)/d;
            = A(i,j).^2.*mean(v.^2) + ...
              2.*A(i,j).*B(i,j).*mean(v.*w) + ...
              B(i,j).^2.*mean(w.^2);
于 2011-06-15T18:59:46.010 回答
1

尝试重塑向量vw成为1 x 1 x d

  mean (bsxfun(@times, A, reshape(v, 1, 1, [])) ...
        + bsxfun(@times, B, reshape(w, 1, 1, [])), 3)

在这里,我[]在参数中使用reshape来告诉它根据所有其他维度的乘积和向量中的元素总数来填充该维度。

于 2011-06-15T19:02:40.293 回答
1

用于repmat在第三维中平铺矩阵。

A =

     1     2     3
     4     5     6

>> repmat(A, [1 1  10])

ans(:,:,1) =

     1     2     3
     4     5     6


ans(:,:,2) =

     1     2     3
     4     5     6

等等

于 2011-06-15T19:45:36.483 回答
1

您仍然不必求助于任何显式循环或使用bsxfun et al的间接循环。为您更新的要求。您可以通过一个简单的矢量化解决方案来实现您想要的,如下所示

output = reshape(mean((v(:)*A(:)'+w(:)*B(:)').^2),size(A));

由于 OP 仅表示v并且w是长度向量d,因此上述解决方案应该适用于行向量和列向量。如果已知它们是列向量,v(:)则可以替换为v,同样为w


您可以检查这是否与Lambdageek 的答案(修改为平方条件)匹配,如下所示

outputLG = mean ((bsxfun(@times, A, reshape(v, 1, 1, [])) ...
        + bsxfun(@times, B, reshape(w, 1, 1, []))).^2, 3);

isequal(output,outputLG)

ans =

     1
于 2011-06-15T21:53:08.003 回答