优化单元内的矩阵矢量化

时间:2017-09-25 16:58:45

标签: matlab cell vectorization

我目前正在编写一个将单元格数组转换为稀疏块矩阵的函数。

我确实实现了我的目的,现在我正在尝试优化代码,但我似乎无法找到加速单元格内矩阵矢量化的方法。

目前,我已将输入设置为列单元格向量,如下所示:

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:

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

起初我尝试使用cell2mat而不是cat,但事实证明cat更快。

如果有办法计算Val而不经过计算V,那就更好了:)

再次感谢!

1 个答案:

答案 0 :(得分: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中的第二个索引错误,并将其修改为可测试