有没有办法将这个循环简化为没有任何循环的向量形式?
data = randn(1000,1);
center1 = [1,2,3];
for i=1:size(data,1)
A(i,(i-1)*3+1:i*3) = 2*(data(i,:)-center1);
end
SEU:
我复制了您的代码,并使用A=[]
运行它,只是为了确定数组大小。结果是1000 X 3000
。我端的数组A
被证明是某种带有偏移的稀疏三对角矩阵。
无论如何,考虑到这一点,我能够为这些波段制定线性索引矢量化(参见下面的vec1
、vec2
和vec3
(。如果习惯于使用双索引表示法(也称为行和列(,这些可能很难理解。在代码下面,我解释了线性索引矢量化背后的一些直觉。
N = 1000; %Number of random points to generate.
A = zeros(N,3*N); %The ensuing matrix has these dimensions.
data = randn(N,1); %random point generation.
center1 = [1,2,3]; %"Offsets..." ???
vec1 = 1:3*N+1:3*N^2 - 2*N; %Vectorization for the first band. (left-most)
vec2 = N+1:3*N+1:3*N^2 - N; %Vectorization for the second band. (middle)
vec3 = 2*N+1:3*N+1:3*N^2; %Vectorization for the third band. (right-most)
A([vec1,vec2,vec3]) = 2*[(data-center1(1)),...
(data-center1(2)),...
(data-center1(3))]; %Assignment of values.
在线性索引中,每个元素在数组中的位置都由一个数字表示。例如,数组的左上角具有线性索引1
,左下角具有线性指数N
,其中N
是数组中的行数。数组的右上角具有线性索引1+N*(C-1)
,其中C
是列数。在上面的例子C = 3*N
中,最后,右下角的线性索引为N*C
。对于给定的数组元素,通过分别加上N
或减去N
来引用其右侧和左侧的元素。类似地,为了对某个元素上方和下方的垂直相邻元素执行此操作,可以分别减去1
并相加1
。要在主对角线方向上移动,请加上或减去N+1
。要在反对角线方向上移动,请加上或减去N-1
。希望这能说明这些矢量化是如何工作的。