作者sean791121 (尚恩)
看板MATLAB
标题[讨论] 请问有没有比较快的写法
时间Thu May 28 23:31:39 2015
indx是一个index的向量,A和B是矩阵,我想把B中的某些元素放到A内
举例来说:
for i = 2:10000
A(idx(i),idx(1:i-1))=B(idx(i),idx(1:i-1))
end
请问有比较快的写法吗?
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 111.184.40.155
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/MATLAB/M.1432827101.A.BA5.html
1F:→ sean791121: 因为回圈内的每一圈都处理不同大小的空间,所以不行用 05/28 23:34
2F:→ sean791121: parfor 求比较快的方法 05/28 23:34
3F:推 sunev: sub2ind 05/28 23:59
4F:→ sean791121: 意思是用两层for然後用sub2ind找位置吗? 05/29 00:33
5F:→ sean791121: 其实用一层loop也可以,我加速了快两倍,可是和预期 05/29 00:45
6F:→ sean791121: 的速度还是有落差,请问还有更快的写法吗? 05/29 00:45
7F:→ celestialgod: 我测试了一下,A,B如果都是两万乘两万的矩阵 05/29 00:56
8F:→ celestialgod: idx是长度10000,也只要2.345秒而已 05/29 00:57
9F:→ celestialgod: 这样还是不够快吗? 05/29 00:57
10F:→ sean791121: cpu是i5 跑出来大概1.X秒 05/29 01:26
11F:→ sean791121: 看文献 Pentium 4 跑这段code再加上很多有的没的 1秒 05/29 01:27
12F:→ sean791121: 我猜文献应该有用更快的方法 or我的演算法太烂了 05/29 01:28
13F:→ sean791121: 对不起,忘记说明A和B都是sparse的 05/29 01:29
14F:→ sean791121: A(sub_index)=B(sub_index)是不是比较慢呢? 05/29 01:30
15F:→ sean791121: 因为matlab建议使用sparse(I,J,V,m,m) 05/29 01:31
16F:→ celestialgod: 文献也是用MATLAB? 而且你矩阵大小多少? 05/29 02:16
19F:→ celestialgod: 我稍微试了一下,回圈应该是MATLAB中最快的了 05/29 03:41
20F:→ celestialgod: 要再加速就要靠MEX了,还不能复制input才做得到 05/29 03:41
21F:→ celestialgod: 环境: MATLAB 2015a, windows 7 64bit, 05/29 03:42
23F:→ sean791121: 文献也是用MATLAB,我的矩阵5000乘5000 05/29 05:18
24F:→ sean791121: 谢谢你提供方法,我会研究一下的 05/29 05:18
25F:→ sean791121: 想请问您 为什麽matlab的速度会与C差这麽多? 05/29 05:22
26F:→ sean791121: 因为MATLAB都会先判断一些性质(矩阵、函数)的关系吗? 05/29 05:23
27F:→ sean791121: 对不起,我跑你的C++档会出现bug,code没问题呀XD 05/29 06:08
28F:推 sunev: celestialgod太厉害了,可以想出这麽多写法。 05/29 09:21
29F:→ sunev: 我实际用c大给的code稍稍profile了一下。发现实际做出idx的 05/29 09:22
30F:→ sunev: 方法(2~4),其实在真正assign的那行A(idx)=B(idx)并没有比 05/29 09:23
31F:→ sunev: 回圈省下太多时间,所以算出idx的时间成本反而盖过了直接 05/29 09:24
32F:→ sunev: assign的效益。 05/29 09:24
33F:→ sunev: 另外method 3中,应为triu(....,1),下面的 2:end可以去掉 05/29 09:26
34F:→ celestialgod: 我昨天没有想到一个可以直接产生idx的方法 05/29 09:27
35F:→ sunev: 如果把(idx3>0)改成triu(true(mat_size,mat_size),1)会快 05/29 09:27
36F:→ sunev: 一点,但仍比不上回圈。 05/29 09:28
37F:推 celestialgod: 我等等试试看,感谢 05/29 09:29
38F:→ sunev: 另外我的经验是,sparse在这种大量不规则assign的情况下 05/29 09:30
39F:→ celestialgod: 原PO,我的c code,自己跑是没问题的,我编译的指令 05/29 09:31
40F:→ celestialgod: 也在上面,你可能需要再研究一下。 05/29 09:31
41F:→ sunev: 速度是慢了点,因为要一直改non-zero element很麻烦。 05/29 09:32
42F:→ sunev: 所以官方才会建议用sparse一起解决。 05/29 09:33
43F:→ celestialgod: 这里sparse matrix不会比较快 05/29 09:34
44F:→ celestialgod: 原po, c的速度会快本来就不意外..... 05/29 09:36
45F:推 celestialgod: 这题只要想到怎样产生(1, 1, 2, 1, 2, 3, 1, 2, 3, 05/29 09:38
46F:→ celestialgod: 4, 1, 2, 3, 4, 5,... )的方法就会很快(不用矩阵 05/29 09:38
47F:→ celestialgod: 取上三角... 这个会用到太多记忆体还是会慢) 05/29 09:38
48F:推 sunev: 没错,不过true只要1byte,所以还好。XD 05/29 09:55
49F:推 sunev: 刚发现不错的写法 05/29 10:43
50F:→ sunev: A(idx,idx)=tril(B(idx,idx),-1)+triu(A(idx,idx)); 05/29 10:43
51F:→ sunev: 但如果idx很大,B(idx,idx)这个sparse有可能会吃很多记忆体 05/29 10:44
52F:→ celestialgod: 我测试的结果是assign反而比较久 05/29 10:57
53F:→ celestialgod: 我算idx的时间大概0.5秒,assign要花2.1秒 05/29 10:57
54F:→ celestialgod: 我也试着用gpuArray去算idx,但是还是卡在assign 05/29 10:59
55F:推 sunev: 你矩阵是5000*5000,idx长度是10000吗? 05/29 11:04
56F:→ sunev: 这样你矩阵还会是 "sparse" 吗? 05/29 11:04
57F:→ celestialgod: 5000*5000, 10000也只占0.04%..不过我用15000*15000 05/29 11:08
58F:→ celestialgod: 我错了XD,idx长度10000,要改将近5000万个值 05/29 11:10
59F:推 sunev: 我是问原作者啦。不确定他想加速到什麽程度,所以想确定 05/29 11:12
60F:→ sunev: 问题的size 05/29 11:12
61F:→ celestialgod: 刚刚有发现XDD 05/29 11:13
62F:→ celestialgod: 如果assign的成本比算idx的成本还贵,这问题无解 05/29 11:14
63F:→ celestialgod: 只能用C去更动矩阵的值才会快上不少 05/29 11:14
64F:推 sunev: 再回楼上,我的意思不是assign比算idx久,而是一行assign 05/29 11:15
65F:→ sunev: 比回圈assign省不了多少时间,而算idx会超过省下的时间。 05/29 11:16
66F:→ celestialgod: 喔喔,我懂了 05/29 11:17
67F:→ celestialgod: 一行assign省下的时间没有比算idx的时间短 05/29 11:18
68F:→ sean791121: 对不起,K大概4800,谢谢两位的帮忙 05/29 12:54