执行数组操作而不循环涉及2个向量的函数

时间:2017-03-08 20:15:26

标签: arrays matlab loops optimization

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

function [parentIndexVec] = computeParentIndex(nameVec)

    parentNameVec = computeParentName(nameVec);
    for i=1:length(parentNameVec)
        parentIndexVec(i) = find(strcmp(nameVec, parentNameVec{i}));
    end

end

computeParentName函数实际上返回nameVec的副本,删除了最后一个字母。然后,循环前面的单元格数如下所示:

nameVec       = ''    'a'    'b'    'aa'    'ab'    'ba'    'aba'    'abb'
parentNameVec = ''    ''     ''     'a'     'a'     'b'     'ab'     'ab'

此函数的目标是查找parentNameVec中每个元素在nameVec中出现的位置的索引,其输出如下:

parentIndexVec = 1     1     1     2     2     3     5     5

我试图制作一个cellfun来完成此任务,但无法让它运作,因为必须在每个点比较两个向量。

我的问题如下:

  1. 有没有办法通过消除循环来做到这一点?
  2. 在大多数情况下,使用矩阵运算而不是循环真的更快吗?
  3. 如果是这样,cellfun速度与纯矩阵运算相比还是会像循环一样慢吗?
  4. 感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

  1. 您可以使用ismember查找parentNameVecnameVec内字符串的出现次数

    nameVec = {''    'a'    'b'    'aa'    'ab'    'ba'    'aba'    'abb'};
    parentNameVec = {''    ''     ''     'a'     'a'     'b'     'ab'     'ab'};
    
    [~, parentIndexVec] = ismember(parentNameVec, nameVec)
    %   1   1   1   2   2   3   5   5
    
  2. 对于矩阵运算,操作几乎肯定会比for循环更快。两种方法之间的差异随着时间的推移而减少,但仍然存在。不幸的是,在您的示例中,您使用的是不具有矩阵运算的单元阵列。

  3. cellfun几乎总是比for循环慢,因为MATLAB的JIT编译器能够更好地优化for循环的内容。在较新版本的MATLAB(R2015b +)中尤其如此,其中重新执行了执行引擎并提供了更好的加速。

  4. 所有这一切,内置函数几乎总是优于您自己的算法实现(for循环或其他),因为它已被Mathworks优化以产生良好的性能,强大的错误检查,有时它是在较低级别实施的。