# How to use firs value from array column when threshold is reached without for loop?

1 view (last 30 days)
Mantas Vaitonis on 28 Jun 2018
Commented: Mantas Vaitonis on 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.

Stephen23 on 28 Jun 2018
Edited: Stephen23 on 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
Mantas Vaitonis on 6 Jul 2018

Mandeep Singh on 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 CommentsShowHide 1 older comment
Stephen23 on 28 Jun 2018
Edited: Stephen23 on 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