矩阵乘法 - 在 Matlab 中创建和操作三维矩阵



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

我有两个m x n矩阵AB以及两个向量v和长度d w。我想将Av进行外部乘法,以便得到一个m x n x d矩阵,其中(i,j,k)条目A_(i,j) * v_kBw也是如此。

之后,我想添加生成的m x n x d矩阵,然后沿最后一个维度取mean以获得m x n矩阵。

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

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

编辑:

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

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

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


解释:

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

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

换句话说,向量vA(i,j) 缩放加上向量wB(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);

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

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

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

使用 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

等。

您仍然不必使用 bsxfun 人诉诸任何显式循环或间接循环来满足更新的要求。您可以通过简单的矢量化解决方案实现所需的目标,如下所示

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

只说vw是长度d的向量,所以上面的解决方案应该适用于行向量和列向量。如果已知它们是列向量,则可以将v(:)替换为 vw


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

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

相关内容

  • 没有找到相关文章

最新更新