[討論] 請問有沒有比較快的寫法

看板MATLAB作者 (尚恩)時間9年前 (2015/05/28 23:31), 編輯推噓9(9059)
留言68則, 3人參與, 最新討論串1/2 (看更多)
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://www.ptt.cc/bbs/MATLAB/M.1432827101.A.BA5.html

05/28 23:34, , 1F
因為迴圈內的每一圈都處理不同大小的空間,所以不行用
05/28 23:34, 1F

05/28 23:34, , 2F
parfor 求比較快的方法
05/28 23:34, 2F

05/28 23:59, , 3F
sub2ind
05/28 23:59, 3F

05/29 00:33, , 4F
意思是用兩層for然後用sub2ind找位置嗎?
05/29 00:33, 4F

05/29 00:45, , 5F
其實用一層loop也可以,我加速了快兩倍,可是和預期
05/29 00:45, 5F

05/29 00:45, , 6F
的速度還是有落差,請問還有更快的寫法嗎?
05/29 00:45, 6F

05/29 00:56, , 7F
我測試了一下,A,B如果都是兩萬乘兩萬的矩陣
05/29 00:56, 7F

05/29 00:57, , 8F
idx是長度10000,也只要2.345秒而已
05/29 00:57, 8F

05/29 00:57, , 9F
這樣還是不夠快嗎?
05/29 00:57, 9F

05/29 01:26, , 10F
cpu是i5 跑出來大概1.X秒
05/29 01:26, 10F

05/29 01:27, , 11F
看文獻 Pentium 4 跑這段code再加上很多有的沒的 1秒
05/29 01:27, 11F

05/29 01:28, , 12F
我猜文獻應該有用更快的方法 or我的演算法太爛了
05/29 01:28, 12F

05/29 01:29, , 13F
對不起,忘記說明A和B都是sparse的
05/29 01:29, 13F

05/29 01:30, , 14F
A(sub_index)=B(sub_index)是不是比較慢呢?
05/29 01:30, 14F

05/29 01:31, , 15F
因為matlab建議使用sparse(I,J,V,m,m)
05/29 01:31, 15F

05/29 02:16, , 16F
文獻也是用MATLAB? 而且你矩陣大小多少?
05/29 02:16, 16F

05/29 03:41, , 17F
05/29 03:41, 17F

05/29 03:41, , 18F
05/29 03:41, 18F

05/29 03:41, , 19F
我稍微試了一下,迴圈應該是MATLAB中最快的了
05/29 03:41, 19F

05/29 03:41, , 20F
要再加速就要靠MEX了,還不能複製input才做得到
05/29 03:41, 20F

05/29 03:42, , 21F
環境: MATLAB 2015a, windows 7 64bit,
05/29 03:42, 21F

05/29 03:42, , 22F
i7-3770K@4.4GHz
05/29 03:42, 22F

05/29 05:18, , 23F
文獻也是用MATLAB,我的矩陣5000乘5000
05/29 05:18, 23F

05/29 05:18, , 24F
謝謝你提供方法,我會研究一下的
05/29 05:18, 24F

05/29 05:22, , 25F
想請問您 為什麼matlab的速度會與C差這麼多?
05/29 05:22, 25F

05/29 05:23, , 26F
因為MATLAB都會先判斷一些性質(矩陣、函數)的關係嗎?
05/29 05:23, 26F

05/29 06:08, , 27F
對不起,我跑你的C++檔會出現bug,code沒問題呀XD
05/29 06:08, 27F

05/29 09:21, , 28F
celestialgod太厲害了,可以想出這麼多寫法。
05/29 09:21, 28F

05/29 09:22, , 29F
我實際用c大給的code稍稍profile了一下。發現實際做出idx的
05/29 09:22, 29F

05/29 09:23, , 30F
方法(2~4),其實在真正assign的那行A(idx)=B(idx)並沒有比
05/29 09:23, 30F

05/29 09:24, , 31F
迴圈省下太多時間,所以算出idx的時間成本反而蓋過了直接
05/29 09:24, 31F

05/29 09:24, , 32F
assign的效益。
05/29 09:24, 32F

05/29 09:26, , 33F
另外method 3中,應為triu(....,1),下面的 2:end可以去掉
05/29 09:26, 33F

05/29 09:27, , 34F
我昨天沒有想到一個可以直接產生idx的方法
05/29 09:27, 34F

05/29 09:27, , 35F
如果把(idx3>0)改成triu(true(mat_size,mat_size),1)會快
05/29 09:27, 35F

05/29 09:28, , 36F
一點,但仍比不上迴圈。
05/29 09:28, 36F

05/29 09:29, , 37F
我等等試試看,感謝
05/29 09:29, 37F

05/29 09:30, , 38F
另外我的經驗是,sparse在這種大量不規則assign的情況下
05/29 09:30, 38F

05/29 09:31, , 39F
原PO,我的c code,自己跑是沒問題的,我編譯的指令
05/29 09:31, 39F

05/29 09:31, , 40F
也在上面,你可能需要再研究一下。
05/29 09:31, 40F

05/29 09:32, , 41F
速度是慢了點,因為要一直改non-zero element很麻煩。
05/29 09:32, 41F

05/29 09:33, , 42F
所以官方才會建議用sparse一起解決。
05/29 09:33, 42F

05/29 09:34, , 43F
這裡sparse matrix不會比較快
05/29 09:34, 43F

05/29 09:36, , 44F
原po, c的速度會快本來就不意外.....
05/29 09:36, 44F

05/29 09:38, , 45F
這題只要想到怎樣產生(1, 1, 2, 1, 2, 3, 1, 2, 3,
05/29 09:38, 45F

05/29 09:38, , 46F
4, 1, 2, 3, 4, 5,... )的方法就會很快(不用矩陣
05/29 09:38, 46F

05/29 09:38, , 47F
取上三角... 這個會用到太多記憶體還是會慢)
05/29 09:38, 47F

05/29 09:55, , 48F
沒錯,不過true只要1byte,所以還好。XD
05/29 09:55, 48F

05/29 10:43, , 49F
剛發現不錯的寫法
05/29 10:43, 49F

05/29 10:43, , 50F
A(idx,idx)=tril(B(idx,idx),-1)+triu(A(idx,idx));
05/29 10:43, 50F

05/29 10:44, , 51F
但如果idx很大,B(idx,idx)這個sparse有可能會吃很多記憶體
05/29 10:44, 51F

05/29 10:57, , 52F
我測試的結果是assign反而比較久
05/29 10:57, 52F

05/29 10:57, , 53F
我算idx的時間大概0.5秒,assign要花2.1秒
05/29 10:57, 53F

05/29 10:59, , 54F
我也試著用gpuArray去算idx,但是還是卡在assign
05/29 10:59, 54F

05/29 11:04, , 55F
你矩陣是5000*5000,idx長度是10000嗎?
05/29 11:04, 55F

05/29 11:04, , 56F
這樣你矩陣還會是 "sparse" 嗎?
05/29 11:04, 56F

05/29 11:08, , 57F
5000*5000, 10000也只占0.04%..不過我用15000*15000
05/29 11:08, 57F

05/29 11:10, , 58F
我錯了XD,idx長度10000,要改將近5000萬個值
05/29 11:10, 58F

05/29 11:12, , 59F
我是問原作者啦。不確定他想加速到什麼程度,所以想確定
05/29 11:12, 59F

05/29 11:12, , 60F
問題的size
05/29 11:12, 60F

05/29 11:13, , 61F
剛剛有發現XDD
05/29 11:13, 61F

05/29 11:14, , 62F
如果assign的成本比算idx的成本還貴,這問題無解
05/29 11:14, 62F

05/29 11:14, , 63F
只能用C去更動矩陣的值才會快上不少
05/29 11:14, 63F

05/29 11:15, , 64F
再回樓上,我的意思不是assign比算idx久,而是一行assign
05/29 11:15, 64F

05/29 11:16, , 65F
比迴圈assign省不了多少時間,而算idx會超過省下的時間。
05/29 11:16, 65F

05/29 11:17, , 66F
喔喔,我懂了
05/29 11:17, 66F

05/29 11:18, , 67F
一行assign省下的時間沒有比算idx的時間短
05/29 11:18, 67F

05/29 12:54, , 68F
對不起,K大概4800,謝謝兩位的幫忙
05/29 12:54, 68F
文章代碼(AID): #1LPpJTkb (MATLAB)
文章代碼(AID): #1LPpJTkb (MATLAB)