如何把一个向量与矩阵的每一列最有效?
64(30天)
显示旧的评论
嘿,
我有一个向量t(资料片),一个矩阵(nxm)。我需要乘element-wise t和每一列。
例如:t = [1;2);= (1 - 2;3 4]= > Res = (1 * 1 * 2;2 * 3 * 4)
到目前为止我已经尝试4版本:
% 1。循环
为j = 1: m
res (j) = t。* (:, j);
结束
% 2。Repmat
尸= repmat (t 1米)
res =尸。*;
% 3。诊断接头
res =诊断接头(t) *;
% 4。索引
= (:);
t = t (:, (1, m));
t = t (:);
res =。* t;
res =重塑(res, n, m);
对这些我做了一些测试,发现# 1(到目前为止)最快的一个,其次是# 2和# 4慢(约2到3倍),然后其次是# 3(慢8到9倍)。这种让我吃惊,因为# 1是唯一的版本没有以某种方式利用矩阵运算。
有人知道一个更快的方法?或者有人能给结果我发现一些原因吗?
接受的答案
马特Tearle
2011年5月9日
第一个问题已经解决,所以我就扔了几点关于第二个问题。
- 较新的版本你跑步,你会看到更多的利益从JIT增强,所以循环不慢和一般邪恶。
- 方法2和4都需要更多的内存和内存操作有关。假设变量是很大的,这是一个很多的计算开销。(还记得,MATLAB需要连续的内存地址数组)。
- 方法3不仅会带来相同的memory-monkeying点球,但也需要更多的计算。
6个评论
更多的答案(5)
大卫
2017年6月21日
我自己就遇到了这个问题,发现所有这些答案是非常有用的。然而,戳一点后,我发现MATLAB 2016 b和后允许隐式乘法bsxfun做同样的事情,稍快。
res = A。* t或res = t。*是等价的,解决这个问题,只要t是一个向量与相同数量的行或列。
其他答案当然正确时被问到的问题。这个页面还在浏览~ 1000次/月,所以我想获取当前最好的答案。
clearvars;
一个=兰德(1 e4, 2 e4);
(Nr、数控)= (A)大小;
v =兰德(Nr, 1);
抽搐;
%的答案= 0(大小(A));
为我= Nc: 1:1
回答(:,i) = (:, i)。* v;
结束
toc
抽搐;
回答= a * (v *的(Nc));
toc
抽搐;
回答= a * (repmat (v, 1, Nc));
toc
抽搐;
回答= bsxfun (@times, v);
toc
抽搐;
回答= a * v;
toc
抽搐;
回答= v *;
toc
收益率以下时间
运行时间是0.915789秒。
运行时间是0.863713秒。
运行时间是0.911458秒。
运行时间是0.685757秒。
运行时间是0.302117秒。
运行时间是0.285025秒。
最后两个,我是检查如果顺序很重要。它不;哪个是第一个总是略快,但是把“回答= v。*“早让它稍慢。
2的评论
乔纳森
2019年2月26日
“可移动”回答= v。*“早让它稍微慢”——在MATLAB如果你多次运行相同的计算提高了后续运行速度,限制。随着v。* A和A。* v在本质上是一样的那么一个运行第二个应该会更快。
马特无花果
2011年5月9日
我觉得我赢了Vista的循环选择最快的32位。使用r2007b。
> > more_loop_timings
运行时间是0.017479秒。
运行时间是0.037864秒。
运行时间是0.376887秒。
运行时间是0.030641秒。
运行时间是0.022277秒。
%
%
%
%
函数[]= more_loop_timings
%更多这些....
t = (1:1000)”;
一个=兰德(长度(t), 1000);%大广场
[n m] =大小(一个);
% % 1。循环
抽搐
为jj = m: 1:1
res (:, jj) = t。* (:, jj);%动态预先分配
结束
toc
% % 2。Repmat
抽搐
它= repmat (t 1米)。*;
toc
% % 3。诊断接头
抽搐
res3 =诊断接头(t) *;%呀! !
toc
%显而易见的选择…
抽搐
res4 = bsxfun (@times, t);
toc
% % 4。索引
抽搐
t = t(:,(1米“单一”));
res5 =重塑((:)。* t (:), n, m);
toc
% isequal (res,它、res3 res4, res5)
1月
2011年5月9日
简化:
% 4。索引
res = t (:, (1, m)) *一个;
这是表现在REPMAT完全相同的效果。2009在我的Matlab在单一核心BSXFUN是人工繁殖最快的。它非常靠近天真C-Mex实现版本(单线程的,没有SSE)。
编辑:马特的预先分配是快。Matlab 2009 a, WinXP 32岁的1.5 ghz迅驰(单芯)
t = (1:1000)”;
一个=兰德(1000、200);
抽搐;为代表= 1:10 0;R = func1 (t);结束;toc
函数R = func1 (t)% 0.78秒
[n m] =大小(一个);
R = 0 (n, m);
为i = 1: m
R (:, i) = t。* (:, i);
结束
函数R = func2 (t)% 0.54秒
[n m] =大小(一个);
为我= m: 1:1
R (:, i) = t。* (:, i);
结束
函数R = func3 (t)% 0.54秒
R = bsxfun (@times t);
函数= func4 (t))% 0.75秒
[n m] =大小(一个);
为i = 1: m
(:,i) = t。* (:, i);
结束
7评论
安德鲁·纽厄尔
2011年5月8日
我不发现。如果我输入
清晰的
t = (1:1000)”;一个=兰德(长度(t), 200);
[n m] =大小(一个);
% % 1。循环
抽搐
为j = 1: m
res (:, j) = t。* (:, j);%你有一个错误在这方面
结束
toc
% % 2。Repmat
抽搐
尸= repmat (t 1 m);
res =尸。*;
toc
% % 3。诊断接头
抽搐
res =诊断接头(t) *;
toc
% % 4。索引
抽搐
= (:);
t = t (:, (1, m));
t = t (:);
res =。* t;
res =重塑(res, n, m);
toc
输出是
运行时间是0.300359秒。
运行时间是0.003952秒。
运行时间是0.035276秒。
运行时间是0.004409秒。
1评论
安德烈Bobrov
2011年5月8日
我的研究结果
清晰的
一个= 0 (5100);
jj = 1:10 0
t =兰德(1000 1);一个=兰德(长度(t), 200);
[n m] =大小(一个);
% 1。循环
抽搐
j = 1: m
res (:, j) = t。* (:, j);
结束
(1,jj) = toc;
% 2。Repmat
抽搐
尸= repmat (t 1 m);
res =尸。*;
(2,jj) = toc;
% 3。诊断接头
抽搐
res =诊断接头(t) *;
(3,jj) = toc;
% 4。索引
抽搐
A1 = (:);
t1 = t (:, (1, m));
t1 = t1 (:);
res = A1。* t1;
res =重塑(res, n, m);
(4,jj) = toc;
% 5。bsxfun
抽搐
res = bsxfun (@times t);
(5,jj) = toc;
结束
AA =意味着(2)
AA =
0.0006
0.0023
0.0413
0.0031
0.0015
安德斯Munk-Nielsen
2012年3月23日
我有类似的问题,我有一个NxM矩阵,其中N是非常大的(500万)和M相当小(低于100)和我有一个1 xm向量,我想乘到所有N行。我想改进一个实现使用repmat在我的直觉非常缓慢,这是由于巨大的内存占用。
我的问题:为什么不是bsxfun比它快?我希望它是那样的快,但这只是有点快。如果我要实现一个墨西哥人函数(multiplyVectorToMatrix函数),什么是重要的特征建成的吗?多线程'ness吗?