想象一下你有一个很长的序列。找到序列全为零的间隔(或更准确地说,序列下降到接近零值的间隔)的最有效方法是什么abs(X)<eps
):
为简单起见,我们假设以下顺序:
sig = [1 1 0 0 0 0 1 1 1 1 1 0 1 0 0 0 1 1 1 1 1 1 1 1 0 0 1 1 1 0];
我正在尝试获取以下信息:
startIndex EndIndex Duration
3 6 4
12 12 1
14 16 3
25 26 2
30 30 1
然后使用这些信息,我们找到持续时间 >= 某个指定值的间隔(例如3
),并返回所有这些区间组合中的值的索引:
indices = [3 4 5 6 14 15 16];
最后一部分与之前的问题相关:
MATLAB:矢量化数组创建
来自开始/结束索引列表 https://stackoverflow.com/questions/2807270/matlab-vectorized-array-creation-from-a-list-of-start-end-indices
这是我到目前为止所拥有的:
sig = [1 1 0 0 0 0 1 1 1 1 1 0 1 0 0 0 1 1 1 1 1 1 1 1 0 0 1 1 1 0];
len = length(sig);
thresh = 3;
%# align the signal with itself successively shifted by one
%# v will thus contain 1 in the starting locations of the zero interval
v = true(1,len-thresh+1);
for i=1:thresh
v = v & ( sig(i:len-thresh+i) == 0 );
end
%# extend the 1's till the end of the intervals
for i=1:thresh-1
v(find(v)+1) = true;
end
%# get the final indices
v = find(v);
我正在寻求矢量化/优化代码,但我对其他解决方案持开放态度。
我必须强调,空间和时间效率非常重要,因为我正在处理大量长生物信号。
这些是我将采取的以向量化方式解决您的问题的步骤,从给定的向量开始sig
:
-
首先对向量进行阈值处理,得到向量tsig
零和一(信号绝对值足够接近零的零,其他地方的零):
tsig = (abs(sig) >= eps); %# Using eps as the threshold
-
接下来,使用函数查找每个零字符串的起始索引、结束索引和持续时间DIFF http://www.mathworks.com/access/helpdesk/help/techdoc/ref/diff.html and FIND http://www.mathworks.com/access/helpdesk/help/techdoc/ref/find.html:
dsig = diff([1 tsig 1]);
startIndex = find(dsig < 0);
endIndex = find(dsig > 0)-1;
duration = endIndex-startIndex+1;
-
然后,找到持续时间大于或等于某个值(例如示例中的 3)的零字符串:
stringIndex = (duration >= 3);
startIndex = startIndex(stringIndex);
endIndex = endIndex(stringIndex);
-
最后,使用我对链接问题的回答中的方法 https://stackoverflow.com/questions/2807270/matlab-vectorized-array-creation-from-a-list-of-start-end-indices/2807994#2807994生成最终的索引集:
indices = zeros(1,max(endIndex)+1);
indices(startIndex) = 1;
indices(endIndex+1) = indices(endIndex+1)-1;
indices = find(cumsum(indices));
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)