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

2 visualizaciones (últimos 30 días)
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.

Respuesta aceptada

Stephen23
Stephen23 el 28 de Jun. de 2018
Editada: Stephen23 el 28 de Jun. de 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 comentarios
Stephen23
Stephen23 el 6 de Jul. de 2018
Editada: Stephen23 el 6 de Jul. de 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
Mantas Vaitonis
Mantas Vaitonis el 6 de Jul. de 2018
@Stephen Cobeldick thank you for the answer and your time.

Iniciar sesión para comentar.

Más respuestas (1)

Mandeep  Singh
Mandeep Singh el 28 de Jun. de 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 comentarios
Mantas Vaitonis
Mantas Vaitonis el 28 de Jun. de 2018
Oh, Thank You. Sometimes it looks like magic, how fast you respond with the answer. It took me 5 days with no result, and only couple hours for you :) It took me some time to go through your code and it seems it does what I need.
Stephen23
Stephen23 el 28 de Jun. de 2018
Editada: Stephen23 el 28 de Jun. de 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

Iniciar sesión para comentar.

Categorías

Más información sobre Performance and Memory en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by