【发布时间】:2015-10-18 03:36:07
【问题描述】:
我有一个名为“r”的向量,包含 201 个实数值,另一个向量名为“结”,包含 21 个实数值。 我想为每个“r”值找到大于“r”值的最小“结”值的索引 i。我是否必须在 'r' 向量上的 'for' 循环中执行此操作,还是有一种方法可以对代码进行矢量化以便避免 for 循环?
【问题讨论】:
标签: matlab vectorization
我有一个名为“r”的向量,包含 201 个实数值,另一个向量名为“结”,包含 21 个实数值。 我想为每个“r”值找到大于“r”值的最小“结”值的索引 i。我是否必须在 'r' 向量上的 'for' 循环中执行此操作,还是有一种方法可以对代码进行矢量化以便避免 for 循环?
【问题讨论】:
标签: matlab vectorization
不,您可以避免循环。您可以将bsxfun 与max 结合使用。我不知道r 和knots 是什么形状……如果它们是行向量或列向量,那么我将让代码独立于这个事实。请注意,我要写的内容假定r 中至少有一个元素,其中knots 中的值大于r。如果不是,则此代码将不起作用。
我的想法是这样的:
rs = r(:).'; %// Make sure r a row vector '
[knotss,indk] = sort(knots(:)); %// Make sure knots a column vector
%// Make sure that the values are sorted
%// For each value in knots, find all values that are greater than r
check = bsxfun(@gt, knotss, rs);
%// Determine the right indices for each value of knots in sorted array
[~,indc] = max(check, [], 1);
%// Get the original indices
indices = indk(indc);
前两行代码确保r 是行向量,knots 是列向量。我们还对knots 中的值进行排序,因为您希望找到大于r 中的值的knots 的最小值。它使我们能够使事情变得更有效率。我还返回了knots 的实际排序,因为当我们在knots 中找到大于某个值r 的最小值的位置时,我们必须返回原始排序。
接下来,对bsxfun 的调用会创建一个二维布尔矩阵check。 check 中的每一列对应knots 中的每个值。具体来说,每一列都会告诉您knots 的哪些值大于r 中的值。对于每一列,false 表示r 中的相应值不大于您正在查看的knots 中的值,而true 则不然。一旦你找到这个矩阵,你调用max 并独立检查每一列。调用max 时,仅返回第一次 遇到最大值的时间。因为布尔矩阵只包含 0 和 1,所以这有效地为您提供了每行第一次遇到 true 值,这表示r 可能大于knots 中的每个值的最小可能索引.
您不需要查看实际的最大值,但您需要此最大值发生位置的索引,因此创建了变量 indices,它是 @987654355 的第二个输出@。
这是一个包含一些测试数据的简单示例:
r = [-1 0];
knots = [3 -1 1 0 -3];
运行上面的代码,我的索引得到了这个:
indices =
4
3
这是有道理的。 r 的第一个值是 -1,knots 中的值是knots 大于 -1 的最小可能值是值 0,它位于位置 4。@987654361 的第二个值@ 为 0,knots 中的值是 knots 大于 1 时可能出现的最小值为 1,并且位于位置 3。
【讨论】: