使这个matlab代码在没有for循环的情况下运行

时间:2015-09-06 20:22:17

标签: matlab vectorization

  1. 假设我有一个带有一些数据值的数组x。
  2. 我执行了一个聚类算法,该算法生成了一个带有标签名称 - labelMap的标签贴图。数据中的每个点现在都有一个与之关联的唯一群集标签。
  3. 然后我在每个子集上执行函数foo(subset,secondArg)。函数foo返回一个新数组,其结果与给定参数的大小相同(它的map()函数也接收第二个参数。)
  4. 以下是当前的实施:

        x = rand(1,1000);
        numClusters = 3; % specified in advance by the user, for example using a clustering algorithm such as K-Means, this is a given.
        fooSecondArg = [1,2,3]; % second argument for foo().
    
        labelMap = kmeans(x,numClusters);
        res = zeros(size(x));
    
        %% make me run without a for loop :)
        for ind = 1:numClusters
            res(labelMap == ind) = foo(x(labelMap == ind), fooSecondArg(ind));
        end
    

    我的问题如下:

    由于x foo()中的索引之间没有重叠,有没有办法在不使用for或parfor循环的情况下对x执行foo? (我不想使用parfor循环,因为启动额外的matlab进程需要很长时间,以后我不能将它作为独立的应用程序部署。)

    非常感谢!

    编辑: 我被问到foo()的一个例子,因为我被告知解决方案可能依赖于它。您可以在答案中使用的一个很好的可行示例:

        function out = foo(x,secondArg)
        out = x.^2/secondArg;
    

1 个答案:

答案 0 :(得分:1)

是否可以删除循环取决于您具有的功能。在你的情况下,函数是

  

function out = foo(x,secondArg)
  out = x.^2/secondArg;

其中secondArg取决于群集。

对于这个函数(以及类似的函数),您确实可以消除循环,如下所示:

res = x.^2 ./ fooSecondArg(labelMap);

下面

  • labelMapx的大小相同(表示x的每个条目的群集标签);
  • fooSecondArg是一个长度等于簇数的向量(表示每个簇的第二个参数)。

因此fooSecondArg(labelMap)是一个与x大小相同的数组,对于每个点,它给出了与该点的簇相对应的第二个参数。运算符./执行逐元素除法以产生所需的结果。