Reputation: 1131
Firstly, the title is probably not clear enough, sorry for that (can't decide what's a better title without using explanation). Let me explain better in words.
Let's say I have a matrix
A=[
0 0 0 0 0 -1 -1 -1 1 1 1 1 0 0 0 0 0 1 1 1 -1 -1 -1 0 0 0 0 0
0 0 0 0 0 1 1 1 -1 -1 -1 -1 0 0 0 0 0 -1 -1 -1 1 1 1 0 0 0 0 ]
What I would like to this is detects the boundary between 0
and any values on per row and segment it by the enclosure. For row #1, I have (0 -1
, 1 0)
, (0 1
, -1 0)
, thus using this information I would like to correct all the values on enclosed inside that boundary to positive or negative values depending on what it begins with and ends with. For example, the first row would become somehting like:
[0 0 0 0 0 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0]
Any ideas that I can efficiently performs this because the matrix I'll be dealing with is of very large. Thanks you in advance!
EDIT
The enclosed values are not necessary 1. It can be any value ranges [-1 1]
.
Upvotes: 0
Views: 55
Reputation: 3071
Here is one possible solution:
% example matrix:
A=[
0 0 0 0 0 0.5 0.9 -1 0.1 0.3 1 1 0 0 0 0 0 0.9 -1 0.1 0.3 -1 -1 0 0 0 0 0;
0 0 0 0 0 0.1 0.3 1 -1 -1 -1 -1 0 0 0 0 0 -1 -1 -1 1 1 1 0 0 0 0 0 ];
[r,c]=find(A);
ind=sortrows([r c]);
steps=find(diff(ind(:,2))~=1);
steps=[[1; steps+1],[steps ;size(ind,1)]];
for k=1:size(steps,1)
A(ind(steps(k,1),1),ind(steps(k,1),2):ind(steps(k,2),2))=A(ind(steps(k,1),1),ind(steps(k,1),2))
end
% result matrix:
A=
0 0 0 0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0 0 0 0 0 0.9 0.9 0.9 0.9 0.9 0.9 0 0 0 0 0
0 0 0 0 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0 0 0 0 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0
EDIT
I came with a vectorized solution, thanks to the new repelem
. Now it works with continuous indexing in the matix A
, and not with row and column, so I transposed A
so that the interesting sequences through the matrix will have continuous indices:
A=A.';
B=find(A);
steps=diff([0;find(diff(B)>1) ;length(B)]);
vals=A(B([0 ;find(diff(B)>1)]+1));
A(A~=0)=repelem(vals,steps);
Upvotes: 1