我拼命想避免在Matlab中使用for
循环,但我无法弄清楚如何做到这一点。情况如下:
我有两个m x n
矩阵A
和B
以及两个长度为v
的{{1}}和w
个向量。我希望外部乘以d
和A
,以便我得到一个v
矩阵,其中m x n x d
条目为(i,j,k)
,类似于A_(i,j) * v_k
和B
。
之后,我想添加生成的w
矩阵,然后沿最后一维获取m x n x d
以获取mean
矩阵。
我很确定我可以处理后一部分,但第一部分让我完全陷入困境。我尝试使用m x n
无济于事。有人知道这样做的有效方法吗?非常感谢!
编辑:此修订版位于以下三个最佳答案之后。毫无疑问,gnovice对我提出的问题有最好的答案。但是,我打算提出的问题涉及在取平均值之前对每个条目进行平方。我最初忘了提这个部分。鉴于这种烦恼,其他两个答案都运作良好,但在编码之前进行代数的聪明伎俩并没有帮助。感谢大家的帮助!
答案 0 :(得分:7)
修改强>
即使问题中的问题已经更新,仍然可以使用代数方法来简化问题。您仍然不必费心使用3-D矩阵。你的结果就是这样:
output = mean(v.^2).*A.^2 + 2.*mean(v.*w).*A.*B + mean(w.^2).*B.^2;
如果您的矩阵和向量很大,与使用BSXFUN或REPMAT的解决方案相比,此解决方案可以提供更好的性能,因为所需的内存量会减少。
的说明:强>
假设M
是在沿着第三维度取平均值之前得到的m-by-by-by-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);
答案 1 :(得分:1)
尝试将向量v
和w
重新整形为1 x 1 x d
:
mean (bsxfun(@times, A, reshape(v, 1, 1, [])) ...
+ bsxfun(@times, B, reshape(w, 1, 1, [])), 3)
我在[]
的参数中使用reshape
告诉它根据所有其他维度的乘积和向量中元素的总数来填充该维度。
答案 2 :(得分: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
等
答案 3 :(得分:1)
您仍然不必使用bsxfun
等来使用任何显式循环或间接循环。为了您的更新要求。您可以通过简单的矢量化解决方案实现您想要的目标,如下所示
output = reshape(mean((v(:)*A(:)'+w(:)*B(:)').^2),size(A));
由于OP仅表示v
和w
是长度为d
的向量,因此上述解决方案应适用于行和列向量。如果知道它们是列向量,v(:)
可以替换为v
,w
也可以替换。{/ p>
您可以检查这是否与Lambdageek's answer匹配(修改为方括号),如下所示
outputLG = mean ((bsxfun(@times, A, reshape(v, 1, 1, [])) ...
+ bsxfun(@times, B, reshape(w, 1, 1, []))).^2, 3);
isequal(output,outputLG)
ans =
1