Finding runs of a signal where enabling conditions are met.
1 回表示 (過去 30 日間)
古いコメントを表示
Dear all,
I have two long data vectors which are slightly delayed.
I am trying to find the delay time each time, a third variable of TRUE (1). In the picture below a screenshot of the data, where the grey signal is slightly delayed, and the pink signal the enabling condition.

To find the delay time, I am thinking of finding the gradient of the two signals and compare them. I then want to find the maximum value of the signal and find the 63% value which will give me tau.
Finding the gradient of the signals:
signal_1_gradient = diff(signal_1)./diff(time)
signal_2_gradient = diff(signal_1)./diff(time)
For filtering the gradient signal:
b = (1/6)*ones(1,6);
a = 1;
signal_1_gradient_filt = filter(b,a,signal_1);
signal_2_gradient_filt = filter(b,a,signal_2);
And finding the index where enabling conditions are met:
index = find(enabling_conditions == 1)
signal_1_gradient_filt = signal_1_gradient_filt(index)
signal_1_gradient_filt = signal_1_gradient_filt(index)
It would be easiest for me, if I get multiple short vectors (in a structure) with all the periods where the enabling conditions were met. But I cannot find out how to split the vectors once I found the total index where enabling conditions were met.
From this I think it's not so hard to find the gradients for each phase.
Thanks a lot, and please ask me if something is not clear.
0 件のコメント
採用された回答
Guillaume
2015 年 5 月 11 日
First, in your example, you don't need the find. A logical array would work just as well:
index = enabling_conditions == 0; %shouldn't it be == 1?
If I understood correctly, you want to find the start and end of each run of 1 (or is it 0?) in your enabling_conditions, and split the signals arrays into each run:
transitions = diff([0 enabling_conditions 0]); %assuming enabling_conditions is a row vector, and you want to find the runs of 1
%transitions is 1 when going from false to true and -1 when going from true to false. 0 otherwise
startruns = find(transitions == 1);
endruns = find(transitions == -1);
%because enabling_conditions was flanked with 0 in the diff, startruns and endruns are guaranteed to have the same number of elements.
%now split the signal according to start and end of each run:
subsignals_1 = arrayfun(@(s, e) signal_1_gradient_filt(s:e), startruns, endruns, 'UniformOutput', false)
subsignals_2 = arrayfun(@(s, e) signal_2_gradient_filt(s:e), startruns, endruns, 'UniformOutput', false)
Note that I put the vectors into a cell array rather than a structure. I think it makes more sense. You can convert the cell array into a structure with cell2struct but naming the fields is going to be an issue.
2 件のコメント
Guillaume
2015 年 5 月 13 日
編集済み: Guillaume
2015 年 5 月 13 日
No, that's not how it works. The
@(s, e) dosomethingwith(s, e)
is an anonymous function. s and e are just variable names, i could have used any other valid name. So when I write
@(s, e) signal(s:e)
I define a function with two input arguments s and e that returns the elements s to e of signal. It would be similar as writing
function out = myfun(s, e)
out = signal(s:e); %except that a normal function does not have access to signal, so this wouldn't work
end
And calling arrayfun with:
subsignal = arrayfun(@myfun, startruns, endruns, ...)
What arrayfun does is pass the first element of each array it's given to the anonymous function, then the second element, and so on. Because I give it two arrays, the anonymous function has two inputs.
You could replace the whole arrayfun with a loop. For the first one, this would be:
assert(size(startruns) == size(endruns)); %arrayfun checks the arrays are the same size
subsignals_1 = cell(size(startruns)); %array fun does the allocation for you and creates a cell array because of the 'UniformOutput', false
for index = 1:numel(startruns)
s = startruns(index);
e = endruns(index);
subsignals_1{index} = signal_1_gradient_filt(s:e);
end
I like arrayfun and its brothers( cellfun, etc.) as it allows some functional programming in matlab. arrayfun clearly means "transform these arrays into some other(s) array(s) using this function". A for loop does not have this expressiveness.
その他の回答 (0 件)
参考
カテゴリ
Help Center および File Exchange で Array Geometries and Analysis についてさらに検索
製品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!