2017-09-25 61 views
2

我目前正在編寫一個函數,將單元格數組轉換爲稀疏矩陣。優化單元格內的矩陣矢量化

我確實實現了我的目的,現在我正試圖優化代碼,但我似乎無法找到加速單元格內矩陣矢量化的方法。

目前,我已經設置了輸入作爲如下所示的柱細胞載體:

Input = cell(Blocks,1); 

裏面輸入每個單元具有不同大小的矩陣。

向量化矩陣中的細胞內,我目前使用此代碼:

V = cellfun(@(x) x(:), Input, 'un', 0); 

但我的探查不斷告訴我,我的這部分代碼佔用了大量的時間。

我也試圖改變成一個for循環:

Blks = size(Input,1); 

V = cell(Blks,1); 

for i = 1:Blks 
    V{i} = Input{i}(:); 
end 

然而,這不僅使我的代碼的運行速度比我以前的代碼慢。

是否有另一種方法來加速單元格內矩陣的矢量化過程?

非常感謝您提前!


我想添加其他信息。

我計算V.後,我串聯所有的細胞,並通過這樣做使他們成爲一個載體瓦爾:

Val = cat(1,V{:}); 

起初,我嘗試使用cell2mat而不是貓,但事實證明,貓快多了。

如果計算瓦爾不通過計算V去的方式,它會再次成爲更好:)

謝謝!

回答

0

這可能不是最有效的方式,但我得到的運行時間提高了50%:

% Time the two versions of the algorythm 
t1 = timeit(@test1) 
t2 = timeit(@test2) 
disp([num2str((t1 - t2)/t1 * 100) ' % improvement']) 

% Prepare the same input for the two functions, 5 cells 
% with random sized matrices 
Input = cell(1,5); 
for k = 1 : 5 
    Input(k) = {randn(abs(round(randn(1,2).*10)))}; 
end 

% Check if the results are the same 
disp(all(test1(Input) == test2(Input))) 



function Val = test1(varargin) 
    if isempty(varargin) 
    % Prepare three cells for testing 
     Input(1) = {randn(5,4)}; 
     Input(2) = {randn(8,3)}; 
     Input(3) = {randn(2,4)}; 
    else 
     Input = varargin{1}; 
    end 

    % Your current method 
    V = cellfun(@(x) x(:), Input, 'un', 0); 
    Val = cat(1,V{:}); 
end 


function Val = test2(varargin) 
    if isempty(varargin) 
    % Prepare three cells for testing 
     Input(1) = {randn(5,4)}; 
     Input(2) = {randn(8,3)}; 
     Input(3) = {randn(2,4)}; 
    else 
     Input = varargin{1}; 
    end 

    % Store size of all matrices in the cells. I am adding 
    % a 0 at the beginning of the array for the indexing of 
    % the following cycle 
    s = [0 , cellfun(@numel, Input)]; 

    % Pre-allocate variable 
    Val = zeros(sum(s) , 1); 
    % Fill variable 
    for k = 1:numel(Input) 
     Val(sum(s(1:k))+1 : sum(s(1:k+1))) = Input{k}(:); 
    end 
end 

我得到:

T1 =

1.2515e-04

t2 =

6.0825e -05

51。3965%的改善


編輯:更正索引錯誤在test2的


編輯:修正在TEST2第二索引錯誤,並修改了它是可檢驗的

+0

我想你的解決方案,但它似乎給出了錯誤的答案。 Val(sum(s(1))+ 1:sum(s(1:k + 1)))= Input { 我嘗試了修改後的解決方案,但它似乎沒有加快代碼:( –

+0

你是對的,我修改了索引並且功能是可測試的,現在我從兩個版本得到了相同的結果,並且我仍然得到了50-70%的改善!也許它是依賴於設置的? – Zep

+0

我不完全確定你的意思是'setup-dependent'。你是否指MATLAB版本?我的MATLAB版本是2016b,它如果發現這可能會導致速度的不同,順便提一下,這只是出於好奇,但是由於向量的排列,會有速度差嗎?也就是說,無論向量是列還是行vector?我的測試代碼將輸入變量作爲列單元格向量處理,我只是想知道這是否會影響速度。 –