【问题标题】:Make this matlab code run without a for loop让这个 matlab 代码在没有 for 循环的情况下运行
【发布时间】:2015-09-07 05:12:31
【问题描述】:
  1. 假设我有一个包含一些数据值的数组 x。
  2. 我执行了一个聚类算法,该算法生成了一个带有标签名称的标签映射 - labelMap。数据中的每个点现在都有一个与之关联的唯一集群标签。
  3. 然后我对每个子集执行函数 foo(subset, secondArg)。函数 foo 返回一个新数组,其结果与给定参数的大小相同(它的 map() 函数也接收第二个参数)。

以下是当前的实现:

    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;

【问题讨论】:

  • 我认为没有自动方式(您可以尝试accumarray 使用返回元胞数组的匿名函数,但这必须更慢)。这一切都取决于foo 内部做什么
  • 一个拟合 foo(x,secondArg) 的例子可能是:return out = x.^2/secondArg
  • secondArg 如何依赖于集群标签?你有从集群标签到secondArg的某种映射吗?
  • 它不必依赖。它可以由用户给出,也可以计算出来。例如,它可以是集群值的平均值。如果没有第二个参数,并且 foo() 会在内部为每个集群计算这个值,你的答案会有所不同吗?
  • 我明白了。我误解了。无论如何,请参阅我上面的评论。我认为res = x.^2 ./ fooSecondArg(labelMap); 会做

标签: matlab vectorization


【解决方案1】:

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

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

secondArg 取决于集群。

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

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

这里

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-19
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 2017-03-25
    • 1970-01-01
    相关资源
    最近更新 更多