How to use firs value from array column when threshold is reached without for loop?
2 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Mantas Vaitonis
am 28 Jun. 2018
Kommentiert: Mantas Vaitonis
am 6 Jul. 2018
Hello Everyone,
I have the following problem I am trying to solve. The situation is like this, if we look at the column there can’t be two numbers in a row that are above or below predefined threshold value. For example if we have array D:
D=-2 2 3 -1 -5
1 4 -2 3 4
5 3 -4 6 -5
-7 -2 1 4 -1
And we use threshold 0, then it should fulfill this logic
If D>0
B=D
And other values of B are zeros till D<0, then
B=D;
And other values of B are zeros till D>0, and so on.
As in our example final result should look like this:
B=0 2 3 0 0
1 0 -2 3 4
0 0 0 0 -5
-7 -2 1 0 0
The idea is to track when the threshold value is crossed and keep the values of D when threshold was crossed, the result matrix would be used for further calculations. Maybe someone would have an idea how to do this. In reality I would be using big arrays like 100000x20000, thus would be great to avoid for loops.
0 Kommentare
Akzeptierte Antwort
Stephen23
am 28 Jun. 2018
Bearbeitet: Stephen23
am 28 Jun. 2018
This actually returns the requested matrix, and follows the description in the question:
>> thr = 0;
>> D = [-2,2,3,-1,-5;1,4,-2,3,4;5,3,-4,6,-5;-7,-2,1,4,-1]
D =
-2 2 3 -1 -5
1 4 -2 3 4
5 3 -4 6 -5
-7 -2 1 4 -1
>> X = D>thr;
>> Y = D<thr & cumsum(X)>0;
>> Z = [X(1,:); diff(X)>0 | diff(Y)>0];
>> B = zeros(size(D));
>> B(Z) = D(Z)
B =
0 2 3 0 0
1 0 -2 3 4
0 0 0 0 -5
-7 -2 1 0 0
Compared to the requested output matrix:
>> [0 2 3 0 0; 1 0 -2 3 4; 0 0 0 0 -5; -7 -2 1 0 0]
ans =
0 2 3 0 0
1 0 -2 3 4
0 0 0 0 -5
-7 -2 1 0 0
6 Kommentare
Stephen23
am 6 Jul. 2018
Bearbeitet: Stephen23
am 6 Jul. 2018
@Mantas Vaitonis: you are right, it is required to keep track of the previous state of the elements whose values are equal to thr. Using a loop is one way to achieve that:
thr = 0
D = [2,2,2,-1,-5;0,4,-2,3,4;0,3,0,6,-5;2,-2,0,4,-1;2,-2,-1,4,-1]
Z = D(1,:)>thr;
B = zeros(size(D));
B(1,Z) = D(1,Z);
for k = 2:size(B,1)
X = D(k,:)<thr & Z;
Y = D(k,:)>thr & ~Z;
B(k,X|Y) = D(k,X|Y);
Z(X) = false;
Z(Y) = true;
end
giving:
B =
2 2 2 0 0
0 0 -2 3 4
0 0 0 0 -5
0 -2 0 0 0
0 0 0 0 0
Weitere Antworten (1)
Mandeep Singh
am 28 Jun. 2018
Refer to the following snippet of code for the desired result. The code avoids any for loops and gives out the result.
D=[2 2 3 -1 -5;
1 4 -2 3 4;
5 3 -4 6 -5;
-7 -2 1 4 -1];
d = D(:);
consec = logical(abs( (d(2:end)>0) - (d(1:end-1)>0) )); %Change threshold if required from here
B = zeros(size(d));
B([D(1)>0; consec]) = d([D(1)>0; consec]);
B = reshape(B, size(D,1), size(D,2))
2 Kommentare
Stephen23
am 28 Jun. 2018
Bearbeitet: Stephen23
am 28 Jun. 2018
This answer is buggy and does not return the requested output:
B =
0 2 3 -1 -5 % -1 and 5 should both be 0
1 0 -2 3 4
0 0 0 0 -5
-7 -2 1 0 0
The bug is due to the conversion of D into a column vector. By putting all of the data into one column vector d, it treats all elements D(1,2:end) as following elements D(end,1:end-1), thus leading to the incorrect values shown. It might be possible to fix but this would just make this code more complex.
See my answer for a simple solution that actually returns the requested output matrix:
0 2 3 0 0
1 0 -2 3 4
0 0 0 0 -5
-7 -2 1 0 0
Siehe auch
Kategorien
Mehr zu Performance and Memory finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!