0

我有两个向量表示边缘和水平一些连续数据(目前是模拟的)。

edges = [50, 120, 170, 200, 220, 224, 250]
levels = [24,3,30,0,36,0]

我将如何创建一个向量,其中前 50 个条目有 24 个,后续 120 个有 3 个等?

我试过了

psd = zeros(1,250)
psd(edges) = levels

但这只是在相关位置放置一个值 - 这不是我想要的。

4

5 回答 5

1

您的描述和代码不完全匹配。你想要 psd 有 250 个元素还是 1234 ( sum(edges),正如你对后续的使用所暗示的那样)?如果是后者,你可以简单地修改edges = cumsum(edges). 其次,对于给定的边缘,您没有足够的级别。

这是一个不使用循环的解决方案。

edges = [50, 120, 170, 200, 220, 224, 250];
levels = [24,3,30,0,36,0,nan]; % padded with nan for equal length
idxs = length(levels) - sum(bsxfun(@(x,y) x < y,1:max(edges),edges'+1))+1;
pds = levels(idxs)

或者更简单:

idxs = zeros(1,max(edges));
idxs(edges(1:end-1)+1) = 1;
psd = levels(cumsum(idxs)+1)
于 2013-08-19T16:28:04.693 回答
1

这是一个小解决方案,如果edges真的是间隔的边缘:

levels以 0 作为第一个元素展开向量:

levels = [0, 24, 3, 30, 0, 36, 0];

然后您可以执行以下操作:

psd = zeros(1,250);
psd(edges(2:end)-1) = diff(levels);
psd = cumsum(psd);

您将间隔限制为两个连续值之间的偏移量,其他地方为 0。总结时,你有你所期望的。

于 2013-08-19T16:34:27.707 回答
0

涉及一个循环,但应该没问题。此外,您的edgeslevels需要等长。

v = [];
for i = 1:numel(edges)
    v = [v;level(i)*ones(edges(i),1)];
end

这是一个更有效的版本,可以处理分配开销。

v = zeros(sum(edges),1);
c = [0 cumsum(edges)];
for i = 1:numel(edges)-1
    v( c(i)+1:c(i+1) ) = levels(i)*ones(edges(i),1);
end

只记得 ; 在今天的 MATLAB 中,循环并不总是邪恶的。有时,这是最简单(也是最清晰)的解决方案。

于 2013-08-19T16:25:43.647 回答
0

gnovice回答的启发,您可以使用它:

psd = levels(cumsum(sparse(1,cumsum([1 edges(1:end-1)]),1,1,sum(edges))));

为了更容易,您可以创建一个匿名函数并重新使用它:

populate = @(L,E) L(cumsum(sparse(1,cumsum([1 E(1:end-1)]),1,1,sum(E))));
psd = popultae(levels, edges);
于 2013-08-19T20:13:44.423 回答
0

您可以使用这个运行长度解码实用程序FEXrude(),它实现了Bentoy13展示的方法:

% example inputs
edges  = [2, 3, 1];
levels = [24,3,30];

结果

rude(edges, levels)
ans =
    24    24     3     3     3    30
于 2013-08-19T17:19:50.133 回答