使用矩阵运算代替FOR循环,将单元格数组与索引值

时间:2017-03-08 21:52:02

标签: arrays matlab performance for-loop optimization

我有一个函数,它接受一个向量作为输入,使用另一个函数从输入创建一个导数向量,然后比较两个向量以产生其输出向量。我目前正在使用for循环,如下所示:

原始数组nameVec用作以下函数的输入:

% INPUT: nameVec = ''  'a'  'b'  'aa'  'ab'  'ba'  'aba'  'abb'

首先,名为computeParentName的函数从nameVec的每个数组元素中删除最后一个字符并生成此单元格数组:

% OUTPUT: parentNameVec = ''  ''  ''  'a'  'a'  'b'  'ab'  'ab

接下来,函数computeParentIndex找到parentNameVecnameVec中每个元素的位置索引:

function [parentIndexVec] = computeParentIndex(nameVec)
    parentNameVec = computeParentName(nameVec);
    [~,parentIndexVec] = ismember(parentNameVec, nameVec);
end    
% OUTPUT: parentIndexVec = 1     1     1     2     2     3     5     5

我现在正在尝试开发一个本质上反向运行的函数,因为它需要nameVec并输出一个单元格数组,该数组在每个索引处包含parentNameVec中所有索引的数组,其中value是输出数组(' daughterIndexVec`)当前索引的值

function [daughterIndexVec] = computeDaughterIndex(nameVec)
    parentIndexVec = computeParentIndex(nameVec);
    for i=1:length(parentIndexVec)
        daughterIndexVec{i} = find(parentIndexVec==i); 
    end
end
% OUTPUT: daughterIndexVec = {[1,2,3] [4,5] [6] [] [7,8] [] [] []}

在不使用for循环的情况下,是否有更简单(更有效)的方法来实现这一目标?

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

您可以使用ismember的第二个输出来获取parentNameVecnameVec中每个值的位置,然后使用accumarray对所有共享相同的索引进行分组单元格数组中的nameVec中的索引。

[~, ind] = ismember(parentNameVec, nameVec);
daughterIndexVec = accumarray(ind(:), 1:numel(ind), [numel(ind) 1], @(x){x.'});
%   {[1,2,3] [4,5] [6] [] [7,8] [] [] []}