Logical indexing based on intervals

9 visualizzazioni (ultimi 30 giorni)
I have a matrix of time intervals (attached 'intervals') and time stamps (attached 'times'). I want to logical index for all the time stamps contained in the intervals.
Please let me know if this needs clarification. I have attached example matrices.

Risposta accettata

Bruno Luong
Bruno Luong il 10 Ott 2018
any(EMG_times>=t_comb_5(:,1)' & EMG_times<=t_comb_5(:,2)',2)
Or if you run for old matlab release:
any(bsxfun(@ge,EMG_times,t_comb_5(:,1)') & bsxfun(@le,EMG_times,t_comb_5(:,2)'),2)
  9 Commenti
Systematically Neural
Systematically Neural il 10 Ott 2018
@Matt J sorry for the lack of clarity. Please let me know if you believe you have a faster way, I am more than willing to post another question similar to the one above that is answering it in a quicker manner.
Matt J
Matt J il 10 Ott 2018
The approach with discretize will be faster, again assuming that your intervals are sequential and disjoint.

Accedi per commentare.

Più risposte (3)

Matt J
Matt J il 9 Ott 2018
Modificato: Matt J il 10 Ott 2018
I want to logical index for all the time stamps contained in the intervals. Please let me know if this needs clarification.
Yes, almost certainly. Do you mean the result should be a logical matrix L such that L(i,j)=true if the i-th time stamp lies in the j-th interval. If so, then it would be as follows:
intervals=sparse(t_comb_5).';
L= intervals(1,:)<=EMG_times & intervals(2,:)>=EMG_times;
  4 Commenti
Matt J
Matt J il 10 Ott 2018
Modificato: Matt J il 10 Ott 2018
Yes, but it's type logical so it's not so bad. If the intervals are sequential and disjoint, then you could do
edges= reshape(t_comb_5.',[],1);
J = (discretize(EMG_times, edges)+1)/2;
I=(1:numel(EMG_times)).';
idx = abs(J-round(J))<.1;
L=sparse(I(idx),J(idx),true, numel(EMG_times), numel(t_comb_5)/2);
Bruno Luong
Bruno Luong il 10 Ott 2018
Modificato: Bruno Luong il 10 Ott 2018
It's not a question of bad or not, it's just using SPARSE would not be benefit if the result is used once afterwards, will all the dangerous subtlety details of MAXNNZ.
Another observation: SPARSE stores the internal Ir array like command FIND() applied on each input interval.
So one can do that to build sparse without passing by full matrix with FIND on for-loop of interval, and doesn't require the requirement of sorted/non-overlap intervals (where the OP never state, but I agree it would be faster to compute using histogram binning).
But then the question is why use sparse at all? Just doing a basic for-loop on intervals and build L by "&" operator if the memory is the concern.

Accedi per commentare.


Matt J
Matt J il 10 Ott 2018
Or, do you mean the result should be a logical vector L the same length as EMG_times and L(i)=true if EMG_times(i) lies in any of the intervals? If so, and if the intervals are sequential and disjoint, you can do
edges= reshape(t_comb_5.',[],1);
L= mod(discretize(EMG_times, edges),2)==1;

Bruno Luong
Bruno Luong il 10 Ott 2018
Modificato: Bruno Luong il 10 Ott 2018
For general case, meaning without any assumption about the intervals; you can use a function in this FEX file to then reorganize the intervals, then use the HISTOGRAM binning algoritm to find out if it falls into the pairs (similar to Matt's dicretize method)
[left, right] = IntervalUnion(t_comb_5(:,1), t_comb_5(:,2)); % FEX
edges = [left,right]';
edges = edges(:);
[~,~,loc] = histcounts(EMG_times,edges);
L = mod(loc,2)==1;
This would be fast method without any assumption.
A small modification of Matt's method.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by