首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >matlab复杂的末端循环,带bsxfun.

matlab复杂的末端循环,带bsxfun.
EN

Stack Overflow用户
提问于 2012-05-31 17:43:24
回答 2查看 517关注 0票数 2

我有一个2092x252的double矩阵,需要创建一个使用bsxfunfor循环。让我们在这个例子中使用bsxfun(@minus)。我需要循环来完成的是使用每一列作为索引来运行bsxfun(@minus)。例如,将第1列指定为索引,将得到第2列的差异(使用bsxfun(@minus)):252。然后将列2设置为索引,并获得与列3:252的差异(同样使用bsxfun(@minus))。循环必须继续运行,直到bsxfun(@minus, 251, 252)

输出将是一个变量,而不是251个变量。总共有31626个数据点。

另外,你能解释一下代码吗。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-31 18:56:41

我不确定这是否是您想要的,因为它产生了31626x2092个数据点,但既然您说要取列的差值……

代码语言:javascript
复制
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 function描述是这样写的:

对启用了单例扩展的两个数组应用逐个元素的二进制操作

单例扩展就是我在这里使用的,bsxfun看到两个输入是一列和一个具有相同大小列的矩阵,并将列扩展为与矩阵相同的大小(=单例扩展(行维度扩展))

因此,如果你想让行彼此相减,你只需提供一行和之前相同的矩阵,它也会知道要做什么,即沿列维度展开行向量:

代码语言:javascript
复制
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

代码语言:javascript
复制
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,则c的第一个kk_init列将保持为空,并且结果c矩阵将具有N*(N-1)/2+kk_init列而不是N*(N-1)/2列。

票数 3
EN

Stack Overflow用户

发布于 2012-06-01 09:17:00

为了避免跟踪索引,您可以计算结果并将结果存储在单元数组中,然后将所有单元连接到一个矩阵中:

代码语言:javascript
复制
data = rand(2092,252);
C = arrayfun(@(k) bsxfun(@minus, data(:,k), data(:,k+1:end)), ...
        1:size(data,2)-1, 'UniformOutput',false);
C = horzcat(C{:});

生成的矩阵:

代码语言:javascript
复制
>> whos C
  Name         Size                   Bytes  Class     Attributes

  C         2092x31626            529292736  double   
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10831122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档