Performance MATLAB中的矢量整形
我正在尝试用MATLAB中的单for循环实现。为此,给定一个向量u,我试图创建一个表格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
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很高兴听到这很有帮助!祝你好运