如何把一个向量与矩阵的每一列最有效?

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
马特Tearle 2011年5月9日
第一个问题已经解决,所以我就扔了几点关于第二个问题。
  • 较新的版本你跑步,你会看到更多的利益从JIT增强,所以循环不慢和一般邪恶。
  • 方法2和4都需要更多的内存和内存操作有关。假设变量是很大的,这是一个很多的计算开销。(还记得,MATLAB需要连续的内存地址数组)。
  • 方法3不仅会带来相同的memory-monkeying点球,但也需要更多的计算。
6个评论
Teja Muppirala
Teja Muppirala 2011年6月20日
还应该提到在使用诊断接头很坏,使用稀疏对角矩阵是速度比循环方法,但仍比BSXFUN慢一点。
稀疏(1:m, 1: m t) *
0.0304秒

登录置评。

更多的答案(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)
4评论
埃克
埃克 2011年5月9日
我还真想不到prealloc: - p
和谢谢你的bsxfun提示,甚至不知道这个函数!
自从我发现非常高方差的计时结果,我做了一些500年运行(代码我无耻地复制)和归一化结果。
输出如下:
循环- 1.0(最好的)
Repmat - 1.9152
诊断接头- 60.6682
bsxfun - 1.4830
索引- 2.2796
事实上,循环似乎是最好的解决这个问题。非常有趣的!:-)

登录置评。


1月
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评论
1月
1月 2011年5月10日
@James:澄清:你UNINIT功能工作正常。我之前玩mxCreateUninitNumericMatrix,但没有成功。最有可能我拉开了一些从内存使用坏的指针。

登录置评。


安德鲁·纽厄尔
安德鲁·纽厄尔 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
安德烈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
安德斯Munk-Nielsen 2012年3月23日
我有类似的问题,我有一个NxM矩阵,其中N是非常大的(500万)和M相当小(低于100)和我有一个1 xm向量,我想乘到所有N行。我想改进一个实现使用repmat在我的直觉非常缓慢,这是由于巨大的内存占用。
我的问题:为什么不是bsxfun比它快?我希望它是那样的快,但这只是有点快。如果我要实现一个墨西哥人函数(multiplyVectorToMatrix函数),什么是重要的特征建成的吗?多线程'ness吗?
3评论
肖恩·德Wolski
肖恩·德Wolski 2012年3月23日
您的设置对于timign这并不是公平的。看马特的框架,一个更公平的比较。

登录置评。

类别

找到更多的在循环和条件语句帮助中心文件交换

下载188bet金宝搏

社区寻宝

找到宝藏在MATLAB中央,发现社区如何帮助你!

开始狩猎!