FInding value that satisfies 2 conditions
78 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
i need to verify the accuracy of the different measuring systems (data stored in diff .mat files) i'd used in my project by verifying it with the benchmark values. the different periods of measurement is stored in a step graph of 7 different steps. i opened the .mat file and realised that the values within are
"1 1 1 ..., 2 2 2..., 3 3 3 ..., 4 4 4 .., 5 5 5 ...., 6.....,7...., 1....., 2...."
There are a total of 5040 cycles of 1..,2......till 7.
I've managed to come up with a code to determine the first value of every set of values i.e.the index where the first '3' is detected, first '2'...
idx= (find(diff(RuleState)==1));
idx(end+1) = 0;
idx = idx([end, 1:end-1]);
idx = idx + 1;
However, I realised that by doing so, I'll be leaving out the start of the '1's as the difference between the first '1' and the previous value '7' is 6. so I tried to include an OR condition to the first line. But the code doesnt work.
idx= (find(diff(RuleState)==1)) | (find(diff(RuleSTate)==6));
idx(end+1) = 0;
idx = idx([end, 1:end-1]);
idx = idx + 1;
Can I have some help regarding this as I cant find anything online. Thanks!!
0 commentaires
Réponses (3)
dpb
le 19 Oct 2014
idx= (find(diff(RuleState)==1)) | (find(diff(RuleSTate)==6));
You're or'ing the result of find which is the numeric location(s) where the condition is true. or(32,12) say isn't a useful logical operation. or the condition, and then find the locations (or just use the resulting logical addressing array).
idx= find((diff(RuleState)==1) | (diff(RuleSTate)==6));
3 commentaires
dpb
le 20 Oct 2014
There's no retrieving a clear ed variable unless you had saved workspace or it. You can look at the history and retrieve the set of operations done if at the command line that previously generated it, however.
But, instead of that, explain again more fully what you're actually looking for--is it the first location of each group of the set of integers 1:7 sequentially or are there multiple sets wanted at a time?
Star Strider
le 20 Oct 2014
The easiest way to test for the transitions would likely to be with the filter function (although conv could also work):
vt = 1:7; % Create Data
mt = repmat(vt,4,5); % Create Data
v = mt(:)'; % Vector Of Serial Repeats
vr = filter([7 1]/14,1,v); % Use Pattern To Find Transitions
vi = [1 find((vr > 1-1E-5) & (vr < 1+1E-5))]; % Find ‘vr’ = 1
vm = [[1:length(v)]' v' vr']; % Check Data To Verify Result (Discard)
This simply filters the vector ‘v’ with the serial repeats for the occurrence of the [7 1] pattern (creating vector ‘vr’). It then checks ‘vr’ for values approximating 1 (allowing for the errors inherent in digital computations). It then uses the find function to locate all the first indices of 1 values, reporting them in ‘vi’. The ‘vm’ matrix simply shows the result, with the index numbers in the first column, the data vector in the second, and the output of the filter in the third.
Note that this code creates everything as row vectors, so do the appropriate transposes if your data are column vectors.
4 commentaires
dpb
le 20 Oct 2014
Modifié(e) : dpb
le 20 Oct 2014
Assuming I do understand what you're looking for, look at the following--
I took your above vector and augmented it just a little for working case
>> v=[1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 7 1 2 2 3 3 3 4 4 4 5 5 5 6 7];
>> ixgrp=diff([0 v])~=0; % each breakpoint location
>> [v;ixgrp;ixgrp & v==1] % find each starting point of "1" in v
ans =
Columns 1 through 21
1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 7 1 2 2 3
1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 1 1 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
Columns 22 through 31
3 3 4 4 4 5 5 5 6 7
0 0 1 0 0 1 0 0 1 1
0 0 0 0 0 0 0 0 0 0
For each set simply change the value looked for in the original vector in sequence.
NB that often as here the "trick" in the end effects with diff is to augment the initial vector appropriately so the result is still the same length as the undifferentiated vector. Adding the preceding '0' since it's known the initial value is nonzero makes the first location easy regardless of it's actual value.
3 commentaires
dpb
le 22 Oct 2014
diff ([0 v]) is simply augmenting (by prepending) the results of diff(v) with a zero so the length of the resulting vector of differences is the same as the vector. For the "trick" to work, to locate the first element as a transition the prepended value must be one other than the first value in the set of values. I chose zero because it's not a member of your vector.
What actually finds the various levels is the last line in the displayed array of and ing the logic vector of transitions with the logic vector of v==N (where N==1 in the example; to find the beginning of the sequence of fives, write
idx5=(ixgrp & v==5);
As noted, to find each in sequence you can write a loop--
ixgrp=diff([0 v])~=0;
u=unique(v); % the unique values in v
for i=1:length(u)
idN=(ixgrp & v==u(i));
% do whatever w/ that group here
...
Voir également
Catégories
En savoir plus sur Workspace Variables and MAT-Files dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!