FInding value that satisfies 2 conditions
조회 수: 82 (최근 30일)
이전 댓글 표시
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
답변 (3개)
dpb
2014년 10월 19일
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
dpb
2014년 10월 20일
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
2014년 10월 20일
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
dpb
2014년 10월 20일
편집: dpb
2014년 10월 20일
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
dpb
2014년 10월 22일
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
...
참고 항목
카테고리
Help Center 및 File Exchange에서 Workspace Variables and MAT-Files에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!