2015-10-17 68 views
0

我有一个名为'r'的201个实数值的向量,另一个名为'knots'的向量是21个实数值。 我想为每个'r'值找到比'r'值大的最小'结'值的索引i。我是否必须在'for'循环中通过'r'向量执行该操作,还是有一种方法可以对代码进行向量化,以便避免for循环?矢量化MATLAB中最小索引的检查

回答

1

不可以避免循环。您可以使用bsxfun加上max。我不知道rknots是什么形状......如果它们是行或列向量,那么我将使代码独立于此事实。请注意,我要写的是假设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的调用创建了2D布尔矩阵checkcheck中的每列均为knots中的每个值。具体而言,每列将告诉您哪些值knots大于r中的值。对于每列,false表示r中的对应值不大于您正在查看的knots中的值,否则为true。一旦你找到这个矩阵,你可以拨打max并单独检查每一列。当致电max时,仅返回第一个时间的最大值。由于布尔矩阵只包含零和1,因此这会首次有效地为每行遇到一个值true,这表示r可能的最大可能索引大于knots中的每个值。

你并不需要看实际的最大值,但你想要的指数的这个最大发生,因此,在创建变量indices,距离max秒输出的地方


这里有一个简单的例子有一些测试数据:

r = [-1 0]; 
knots = [3 -1 1 0 -3]; 

通过上面的代码运行,我得到这个对我的指数:

indices = 

    4 
    3 

这是有道理的。r的第一个值为-1,并且knots中的值knots大于-1的最小可能值为值0,位于位置4.第二个值r为0,值为knotsknots大于1的最小可能值为1,并且位于位置3.