Performance 在圆上选择邻居

Performance 在圆上选择邻居,performance,matlab,Performance,Matlab,假设我们在一个圆上有N个点。为每个点分配一个索引i=(1,2,…,N)。现在,对于随机选择的点,我想要一个向量,包括5点的索引,[两个左邻域,点本身,两个右邻域] 请参见下图 一些示例如下: N = 18; selectedPointIdx = 4; sequence = [2 3 4 5 6]; selectedPointIdx = 1 sequence = [17 18 1 2 3] selectedPointIdx = 17 sequence = [15 16 17 18 1];

假设我们在一个圆上有
N个
点。为每个点分配一个索引
i=(1,2,…,N)
。现在,对于随机选择的点,我想要一个向量,包括
5
点的索引,
[两个左邻域,点本身,两个右邻域]

请参见下图

一些示例如下:

N = 18;

selectedPointIdx = 4;
sequence = [2 3 4 5 6];

selectedPointIdx = 1
sequence = [17 18 1 2 3]

selectedPointIdx = 17
sequence = [15 16 17 18 1];
(p - m - 1) mod N + 1
...
(p - 4) mod N + 1
(p - 3) mod N + 1
(p - 2) mod N + 1
p
(p + 1) mod N + 1
(p + 2) mod N + 1
(p + 3) mod N + 1
...
(p + m - 1) mod N + 1
对此进行编码的传统方法是将异常视为
if-else
语句,正如我所做的:

if ii == 1
    lseq = [N-1 N ii ii+1 ii+2];
elseif ii == 2
    lseq = [N ii-1 ii ii+1 ii+2];
elseif ii == N-1
    lseq=[ii-2 ii-1 ii N 1];
elseif ii == N
    lseq=[ii-2 ii-1 ii 1 2];
else
    lseq=[ii-2 ii-1 ii ii+1 ii+2];
end
其中
ii
selectedPointIdx

如果考虑代码<> 7 /代码>点,而不是<代码> 5 < /代码>,则效率不高。什么方法更有效?

这个怎么样-

off = -2:2
out = mod((off + selectedPointIdx) + 17,18) + 1
对于大小为
7
的窗口,请将
关闭
编辑为
-3:3

它使用了
减去1
+
修改
+
加回1
的策略

样本运行-

>> off = -2:2;
for selectedPointIdx = 1:18
    disp(['For selectedPointIdx =',num2str(selectedPointIdx),' :'])
    disp(mod((off + selectedPointIdx) + 17,18) + 1)
end
For selectedPointIdx =1 :
    17    18     1     2     3
For selectedPointIdx =2 :
    18     1     2     3     4
For selectedPointIdx =3 :
     1     2     3     4     5
For selectedPointIdx =4 :
     2     3     4     5     6
For selectedPointIdx =5 :
     3     4     5     6     7
For selectedPointIdx =6 :
     4     5     6     7     8
....
For selectedPointIdx =11 :
     9    10    11    12    13
For selectedPointIdx =12 :
    10    11    12    13    14
For selectedPointIdx =13 :
    11    12    13    14    15
For selectedPointIdx =14 :
    12    13    14    15    16
For selectedPointIdx =15 :
    13    14    15    16    17
For selectedPointIdx =16 :
    14    15    16    17    18
For selectedPointIdx =17 :
    15    16    17    18     1
For selectedPointIdx =18 :
    16    17    18     1     2
这个怎么样-

off = -2:2
out = mod((off + selectedPointIdx) + 17,18) + 1
对于大小为
7
的窗口,请将
关闭
编辑为
-3:3

它使用了
减去1
+
修改
+
加回1
的策略

样本运行-

>> off = -2:2;
for selectedPointIdx = 1:18
    disp(['For selectedPointIdx =',num2str(selectedPointIdx),' :'])
    disp(mod((off + selectedPointIdx) + 17,18) + 1)
end
For selectedPointIdx =1 :
    17    18     1     2     3
For selectedPointIdx =2 :
    18     1     2     3     4
For selectedPointIdx =3 :
     1     2     3     4     5
For selectedPointIdx =4 :
     2     3     4     5     6
For selectedPointIdx =5 :
     3     4     5     6     7
For selectedPointIdx =6 :
     4     5     6     7     8
....
For selectedPointIdx =11 :
     9    10    11    12    13
For selectedPointIdx =12 :
    10    11    12    13    14
For selectedPointIdx =13 :
    11    12    13    14    15
For selectedPointIdx =14 :
    12    13    14    15    16
For selectedPointIdx =15 :
    13    14    15    16    17
For selectedPointIdx =16 :
    14    15    16    17    18
For selectedPointIdx =17 :
    15    16    17    18     1
For selectedPointIdx =18 :
    16    17    18     1     2

您可以使用模运算:设p为编号为1到N的N个点中的点。假设您希望每边有m个邻居,您可以得到如下结果:

N = 18;

selectedPointIdx = 4;
sequence = [2 3 4 5 6];

selectedPointIdx = 1
sequence = [17 18 1 2 3]

selectedPointIdx = 17
sequence = [15 16 17 18 1];
(p - m - 1) mod N + 1
...
(p - 4) mod N + 1
(p - 3) mod N + 1
(p - 2) mod N + 1
p
(p + 1) mod N + 1
(p + 2) mod N + 1
(p + 3) mod N + 1
...
(p + m - 1) mod N + 1
代码:

运行代码


我希望您注意到,避免使用if语句可能不一定能提高性能。可能需要一个基准来解决这个问题。但是,这只有在处理成千上万个数字时才有意义。

您可以使用模运算:让p成为编号为1到N的N个点之间的点。假设您希望每边有m个邻居,您可以按如下方式获得它们:

N = 18;

selectedPointIdx = 4;
sequence = [2 3 4 5 6];

selectedPointIdx = 1
sequence = [17 18 1 2 3]

selectedPointIdx = 17
sequence = [15 16 17 18 1];
(p - m - 1) mod N + 1
...
(p - 4) mod N + 1
(p - 3) mod N + 1
(p - 2) mod N + 1
p
(p + 1) mod N + 1
(p + 2) mod N + 1
(p + 3) mod N + 1
...
(p + m - 1) mod N + 1
代码:

运行代码


我希望您注意到,避免使用if语句可能不一定能提高性能。可能需要一个基准来解决这个问题。然而,只有在处理成千上万的数字时,这才有意义。

非常优雅的oneliner!不需要样品,答案很好,谢谢!也可以写:
out=mod(off+selectedPointIdx-1,18)+1
。我觉得更清楚。值18被硬编码一次。@Tarik啊,是的,这更直观!谢谢非常优雅的一行!不需要样品,答案很好,谢谢!也可以写:
out=mod(off+selectedPointIdx-1,18)+1
。我觉得更清楚。值18被硬编码一次。@Tarik啊,是的,这更直观!谢谢现在我想起来了,时钟运算或者像你说的模运算,谢谢+1现在我想起来了,时钟运算或如您所说的模运算,谢谢+1只需指出,因为你已经对点进行了索引,它们在2-空间中的位置是不相关的。如果你没有索引,你可能不得不计算,比如说,它们在ρθ空间中的角度。@CarlWitthoft是的,这个图只是一个简单的例子,可以让问题更容易理解。只是指出,既然你已经索引了点,它们在2-空间中的位置是不相关的。如果你没有指数,你可能不得不计算,比如说,它们在ρθ空间中的角度。@CarlWitthoft是的,这个图只是一个简单的例子,可以让问题更容易理解。