【问题标题】:Check if x is in interval without looping检查 x 是否在没有循环的区间内
【发布时间】:2013-10-17 03:41:25
【问题描述】:

我在避免 Matlab 中的循环时遇到了麻烦。我被告知循环会导致性能不佳,所以我正在重新编写已经使用循环的代码。

我有一个包含值的向量大向量 x 和一个较小的 X,也包含值。对于每个值 x,我必须知道它在哪个区间 i。我将第 i 个区间定义为 X_i-1 和 X_i 之间的值。目前,我正在这样做:

len = length(x);
is = zeros(len, 1); % Interval for each x
for j=1:len
    i=1; % Start interval
    while(x(j)<X(i-1) || x(j)>X(i)) % Please consider accessing X(0) won't crash it's a simplification to make the code clearer for you.
         i = i + 1;
    end
    is(j) = i;
end

没有这些循环怎么办?

编辑:为了帮助您了解情况,这是我在这里尝试做的一个真实示例。有了这些输入

X = [1 3 4 5]
x = [1 1.5 3.6 4.7 2.25]

我希望 is 成为

% The 2 first and the 5th are in the first interval [1, 3]
% The 3rd is in [3, 4] and the 4th is in [4, 5]
is = [1 1 2 3 1] 

【问题讨论】:

  • 你说错了,循环不会(无条件地)导致性能下降。与等效向量化代码的性能相比,最近发布的 Matlab 稳定地提高了循环的性能(通常)。既然你已经被告知,你还想重新编写代码吗?
  • 其实我会被认为循环不好的同一个人评分,所以我不得不重做它,即使它不是真的必要......
  • 所以编辑你的问题,有人可能会同情你的情况。但不是我。不是我不在乎,我真的,真的在乎,但现在是啤酒点。
  • 哈哈,干杯伙伴! @francoisr - 高性能标记没有错。
  • 请给出预期的输出。

标签: matlab for-loop while-loop intervals


【解决方案1】:

我正在使用掩码,然后我移动第二个掩码,然后我使用find 返回一个的索引:

ranges = [1,2,3,4]; %<br>
a = 1.5; %<br>
m1 = (a >= ranges); % will be [1, 0, 0, 0] <br>
m2 = (a <= ranges); % will be [0, 1, 1, 1] <br>
m2(1:end-1) = m2(2:end); % will be [1, 1, 1, 1], I am trying to shift this mask <br>
m2(end) = 0; % will be [1, 1, 1, 0], the mask shift is completed <br>
b = find( m1 & m2); % this will return 1 so your value is between 1 and 2 <br>

【讨论】:

    【解决方案2】:

    很明显的作业,所以我只会指出两个可能对你有帮助的功能:

    • 如果您的区间列表具有恒定间距,请查看 floor 并了解如何直接计算索引。

    • 如果间隔不规则,请查看histc,尤其是查看带有 2 个输出参数的表单。

    您的示例代码还有一个问题:尝试了解当x(j) 超出任何间隔时会发生什么。

    【讨论】:

    • 感谢您的回复。我查看了histc,但我无法使用它,因为我的 x 向量没有按升序排序,我无法对其进行排序。在这种情况下,也许循环是唯一的选择?我只是在寻找一种更聪明的方法来做我已经用循环做的事情:/
    • 为什么不能对x进行排序?
    • 如果我对它进行排序,它将在脚本的其余部分中没有任何意义。我可以对其进行排序,但在计算 is 之后,我必须“取消排序”才能使脚本的其余部分正常工作。 ://
    • 所以只需在脚本开头对xx 链接到的任何其他变量进行排序。保存排序索引,然后您可以在 histc 步骤之后重新应用它们。正确准备数据以进行处理是编写任何代码的重要部分。
    • 我愿意这样做,但它会改进我已经工作的代码吗?因为这是一个相当大的变化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    相关资源
    最近更新 更多