Performance MATLAB中的矢量整形

Performance MATLAB中的矢量整形,performance,matlab,Performance,Matlab,我正在尝试用MATLAB中的单for循环实现。为此,给定一个向量u,我试图创建一个表格 U = [u(k) u(k+1) u(k+2) ... u(k+n) u(k-1) u(k) ... ... u(k+n-1) ... ... ... ... ... u(k-n) u(k-n+1) ... ... u(k)] 其中,n是一个常数,k是一个随每个fo

我正在尝试用MATLAB中的单for循环实现。为此,给定一个向量u,我试图创建一个表格

U = [u(k)     u(k+1)     u(k+2)  ...    u(k+n)
     u(k-1)   u(k)       ...     ...    u(k+n-1)
     ...      ...        ...     ...    ...
     u(k-n)   u(k-n+1)   ...     ...    u(k)]
其中,n是一个常数,k是一个随每个for循环而变化的变量,假设
k>n
。到目前为止,我所取得的成就是:

index = meshgrid(0:-1:1-n)' + meshgrid(1:n);
for i = 2:q
    % calculate k
    U = u(k + index);
    % rest of code goes here
end
虽然它能工作,但很遗憾,速度很慢,不适合我的需要。有没有更有效的方法来实现这一结果?

这应该可以:

k=20;%例k
n=5;%例n

如您所见,左上角是元素编号
k
,右上角是元素编号
k+n
,左下角是
k-n
,右下角是元素
k

您可以使用内置的
toeplitz

 toeplitz(20:-1:15,20:25)

ans =

20    21    22    23    24    25
19    20    21    22    23    24
18    19    20    21    22    23
17    18    19    20    21    22
16    17    18    19    20    21
15    16    17    18    19    20
或者,以更一般的方式:

f = @(k,n)toeplitz(k:-1:k-n,k:k+n)
然后你可以写
U=U(f(k,n))
来得到问题的一般形式。 但请检查这是否确实比for循环快


编辑:
toeplitz
的内部机制是
bsxfun
,因此我想除非您在较低级别的c\fortran中实现它,否则这是最好的。检查
编辑toeplitz
并查看它是如何实现的

该操作有大量复制。所以,为了利用这种特性,这里有一种方法,使用掩蔽功能,并从中得到一些帮助-

mask = bsxfun(@ge,(1:2*n+1)',n+1:-1:1) & bsxfun(@ge,(2*n+1:-1:1)',1:n+1)
sliced_u = u(k+n:-1:k-n)
repvals = repmat(sliced_u(:),1,n+1)
out = reshape(repvals(mask),n+1,[])
可以描述这种方法的方式是,当输入
u
的列版本沿列复制时,我们向右移动时,将所需输出的列视为向上移动的一个位置。剩下的工作是补偿沿列的一个位置偏移,这是通过
bsxfun
的屏蔽来完成的,以切断上部和下部三角形区域,从而获得最终输出

性能:这一想法以前曾被用于解决中的类似问题,我希望这里也有类似的性能数字


作为另一种方法,我们可以直接使用
bsxfun
来获得2D索引,然后索引到
u
中以获得最终输出,如下所示-

out = u(bsxfun(@plus,(k:-1:k-n)',0:n))

看起来你只需要一个Toeplitz矩阵,谢谢你的回答。在采样后,为了只保留每个循环所需的值,使用toeplitz肯定会使循环运行得更快。感谢您的回答。这个实现与我的实现完全相同,尽管你的实现更加优雅,遗憾的是没有给循环带来任何提升。尽管我没有预料到这一点,但是你的第二个简单的方法更好。不过,更好的方法是在
for loop
之外创建一个常量索引矩阵,对向量
u
进行采样,获取每个循环所需的值,然后通过对采样向量进行索引来构造矩阵。既然你的帖子帮助我达到了这个结果,我接受这个答案。谢谢。@naltipar很高兴听到这很有帮助!祝你好运