一如既往地想要向您学习更多信息,我希望能通过以下代码获得一些帮助。
我需要完成以下任务:
1)我有一个矢量:
x = [1 2 3 4 5 6 7 8 9 10 11 12]
2)和矩阵:
A =[11 14 1
5 8 18
10 8 19
13 20 16]
我需要能够将each
的{{1}}值与x
的{{1}}值相乘,这意味着:
every
这会给我A
大小new_matrix = [1* A
2* A
3* A
...
12* A]
假设为new_matrix
。在这种情况下(12*m x n)
如何使用matlab中的A (mxn)
执行此操作?并且,这种方法会比(12*4x3)
更快吗?
关于我的bsxfun
,我在这里也需要一些帮助......当循环运行时,我无法存储每个for-loop
:(
for-loop
提前致谢!!
编辑:在解决方案之后
第一个解决方案
"new_matrix"
输出:
for i=x
new_matrix = A.*x(i)
end
第二个解决方案
clear all
clc
x=1:0.1:50;
A = rand(1000,1000);
tic
val = bsxfun(@times,A,permute(x,[3 1 2]));
out = reshape(permute(val,[1 3 2]),size(val,1)*size(val,3),[]);
toc
输出:
Elapsed time is 7.597939 seconds.
答案 0 :(得分:17)
将x
发送到第三维,以便当bsxfun
用于与A
进行相乘时,单例扩展生效,将产品结果扩展到第三维。然后,执行bsxfun
乘法 -
val = bsxfun(@times,A,permute(x,[3 1 2]))
现在,val
是3D
矩阵,期望的输出应该是沿着第三维列的列连接的2D
矩阵。这在下面实现 -
out = reshape(permute(val,[1 3 2]),size(val,1)*size(val,3),[])
希望有道理!传播bsxfun
字!呜! :)
答案 1 :(得分:10)
kron
函数就是这样:
kron(x.',A)
答案 2 :(得分:3)
以下是我目前提到的方法的基准,以及我自己的一些补充:
function [t,v] = testMatMult()
% data
%{
x = [1 2 3 4 5 6 7 8 9 10 11 12];
A = [11 14 1; 5 8 18; 10 8 19; 13 20 16];
%}
x = 1:50;
A = randi(100, [1000,1000]);
% functions to test
fcns = {
@() func1_repmat(A,x)
@() func2_bsxfun_3rd_dim(A,x)
@() func2_forloop_3rd_dim(A,x)
@() func3_kron(A,x)
@() func4_forloop_matrix(A,x)
@() func5_forloop_cell(A,x)
@() func6_arrayfun(A,x)
};
% timeit
t = cellfun(@timeit, fcns, 'UniformOutput',true);
% check results
v = cellfun(@feval, fcns, 'UniformOutput',false);
isequal(v{:})
%for i=2:numel(v), assert(norm(v{1}-v{2}) < 1e-9), end
end
% Amro
function B = func1_repmat(A,x)
B = repmat(x, size(A,1), 1);
B = bsxfun(@times, B(:), repmat(A,numel(x),1));
end
% Divakar
function B = func2_bsxfun_3rd_dim(A,x)
B = bsxfun(@times, A, permute(x, [3 1 2]));
B = reshape(permute(B, [1 3 2]), [], size(A,2));
end
% Vissenbot
function B = func2_forloop_3rd_dim(A,x)
B = zeros([size(A) numel(x)], 'like',A);
for i=1:numel(x)
B(:,:,i) = x(i) .* A;
end
B = reshape(permute(B, [1 3 2]), [], size(A,2));
end
% Luis Mendo
function B = func3_kron(A,x)
B = kron(x(:), A);
end
% SergioHaram & TheMinion
function B = func4_forloop_matrix(A,x)
[m,n] = size(A);
p = numel(x);
B = zeros(m*p,n, 'like',A);
for i=1:numel(x)
B((i-1)*m+1:i*m,:) = x(i) .* A;
end
end
% Amro
function B = func5_forloop_cell(A,x)
B = cell(numel(x),1);
for i=1:numel(x)
B{i} = x(i) .* A;
end
B = cell2mat(B);
%B = vertcat(B{:});
end
% Amro
function B = func6_arrayfun(A,x)
B = cell2mat(arrayfun(@(xx) xx.*A, x(:), 'UniformOutput',false));
end
我机器上的结果:
>> t
t =
0.1650 %# repmat (Amro)
0.2915 %# bsxfun in the 3rd dimension (Divakar)
0.4200 %# for-loop in the 3rd dim (Vissenbot)
0.1284 %# kron (Luis Mendo)
0.2997 %# for-loop with indexing (SergioHaram & TheMinion)
0.5160 %# for-loop with cell array (Amro)
0.4854 %# arrayfun (Amro)
(这些时间可能会在不同的运行之间略有变化,但这应该让我们知道方法的比较方式)
请注意,其中一些方法会导致较大输入的内存不足错误(例如,基于repmat
的解决方案很容易耗尽内存)。对于较大的尺寸,其他人会明显变慢,但由于耗尽的内存(例如kron
解决方案)不会出错。
我认为bsxfun
方法func2_bsxfun_3rd_dim
或简单的for循环func4_forloop_matrix
(感谢MATLAB JIT)是这种情况下的最佳解决方案。
当然,您可以更改上述基准参数(x
和A
的大小)并得出您自己的结论:)
答案 3 :(得分:2)
只是为了添加替代方案,您可以使用cellfun来实现您想要的效果。这是一个例子(稍微修改一下):
x = randi(2, 5, 3)-1;
a = randi(3,3);
%// bsxfun 3D (As implemented in the accepted solution)
val = bsxfun(@and, a, permute(x', [3 1 2])); %//'
out = reshape(permute(val,[1 3 2]),size(val,1)*size(val,3),[]);
%// cellfun (My solution)
val2 = cellfun(@(z) bsxfun(@and, a, z), num2cell(x, 2), 'UniformOutput', false);
out2 = cell2mat(val2); % or use cat(3, val2{:}) to get a 3D matrix equivalent to val and then permute/reshape like for out
%// compare
disp(nnz(out ~= out2));
两者都给出了相同的结果。
有关使用cellfun的更多信息和技巧,请参阅:http://matlabgeeks.com/tips-tutorials/computation-using-cellfun/
答案 4 :(得分:0)
如果你的向量x长度为12且你的矩阵大小为3x4,我不认为使用其中一个会改变很多时间。如果你正在使用更大尺寸的矩阵和向量,那么现在可能会成为一个问题。
首先,我们希望将向量与矩阵相乘。在for循环方法中,这将提供类似的东西:
s = size(A);
new_matrix(s(1),s(2),numel(x)) = zeros; %This is for pre-allocating. If you have a big vector or matrix, this will help a lot time efficiently.
for i = 1:numel(x)
new_matrix(:,:,i)= A.*x(i)
end
这将为您提供3D矩阵,每个第三维都是乘法的结果。如果这不是您正在寻找的,我将添加另一个解决方案,使用更大的矩阵和向量可能会提高效率。