我不确定这是否正是你想要的,因为它会产生 31626x2092 数据点,但既然你说要取列的差异......
data=ceil(rand(7,5)*10); % some sample data, works with any matrix(at least 2 columns of course)
N = size(data,2);
%b=cell(N-1,1);
c=NaN(size(data,1),N*(N-1)/2); % preallocate result matrix
kk=0;
for ii=1:N-1
%b{ii} = bsxfun(@minus,data(:,ii),data(:,ii+1:end));
c(:,kk+(1:N-ii)) = bsxfun(@minus,data(:,ii),data(:,ii+1:end));
kk=kk+N-ii;
end
这里的关键是,在每个循环步骤中,您只选择要对其执行minus
操作的矩阵部分,即:data(:,ii)
(= 第 ii 列)和data(:,ii+1:end)
(= 从第 ii 到第矩阵的末尾)
bsxfun函数描述说:
Apply-by-element binary operation to two arrays with singleton expansion enabled
单例扩展是我在这里使用的,bsxfun 看到两个输入是一列和一个具有相同大小列的矩阵,并将列扩展为与矩阵相同的大小(=单例扩展(行维度得到扩展))
因此,如果您希望将行相互减去,您只需提供一行和与以前相同的矩阵,它也会知道该怎么做,即沿列维度扩展行向量:
N = size(data,1);
%b=cell(N-1,1);
c=NaN(N*(N-1)/2,size(data,2)); % preallocate result matrix
kk=0;
for ii=1:N-1
%b{ii} = bsxfun(@minus,data(ii,:),data(ii+1:end,:));
c(kk+(1:N-ii),:) = bsxfun(@minus,data(ii,:),data(ii+1:end,:));
kk=kk+N-ii;
end
如您所见,所有矩阵的索引交换了位置:A(i,j)
更改为A(j,i)
.
在循环的每个步骤中使用单元格作为结果矩阵可以更轻松地访问结果,但是由于您希望将结果放在一个变量中(我假设是矩阵),所以我将它们注释掉了。
编辑
关于预分配:http: //www.mathworks.nl/help/techdoc/matlab_prog/f8-784135.html
c(:,kk+(1:N-ii));
kk=kk+N-ii
是索引,这是最棘手的:
当 ii=1 时,您有 251 列要插入:输出变量中的列 1->251
ii=2 -> 250 列,输出中的列 252->501
ii=3 -> 249 列,输出中的列 502->750
ii=4 => 248 列,输出中的列 751->999
等。
kk+(1:N-ii)
本质上是这样做的:为bsxfun
.
该变量kk
是已保存到输出变量中的列数c
,因此显然它从零开始。如果将其更改为另一个值,例如kk_init
, 的第一kk_init
列c
将保持为空,并且生成的c
矩阵将具有N*(N-1)/2+kk_init
列而不是N*(N-1)/2
。