MATLAB Answers

# elimination of conscutive regions (generalization: ones with zeros between)

1 view (last 30 days)
Michal Kvasnicka on 1 Oct 2018
Commented: Bruno Luong on 2 Oct 2018

I need effectively eliminate (by zeroing) the consecutive "1's" between "-1's" and start/end of column at each column of matrix A, which now can be separated by any number of zeroes. The number of consecutive "1's" between "-1's" and start/end of column is > N. This is a non-trivial generalization of my previous Question.

Again, typical size(A) = [100000,1000].

See example:

```A =
1    -1     0
0     1     1
0     1     1
1     1     0
0     0     1
1    -1     0
-1     1     1
-1     0    -1
1     1     1
0     1    -1
```

For N = 2 the expected result is

```Aclean =
0    -1     0
0     0     0
0     0     0
0     0     0
0     0     0
0    -1     0
-1     0     0
-1     0    -1
1     0     1
0     0    -1
```

For N = 3 the expected result is

```Aclean =
1    -1     0
0     1     0
0     1     0
1     1     0
0     0     0
1    -1     0
-1     1     0
-1     0    -1
1     1     1
0     1    -1
```
##### 4 CommentsShowHide 3 older comments
Michal Kvasnicka on 1 Oct 2018
Well OK, any sequence of "1's" and "0's" separated by start/end and "-1's".

Sign in to comment.

### Accepted Answer

Bruno Luong on 1 Oct 2018
A = [1 -1 0;
0 1 1;
0 1 1;
1 1 0;
0 0 1;
1 -1 0;
-1 1 1;
-1 0 -1;
1 1 1;
0 1 -1];
N = 3;
[m,n] = size(A);
Aclean = A;
for j=1:n
Aj = [-1; A(:,j); -1];
i = find(Aj == -1);
c = histc(find(Aj==1),i);
b = c <= N;
im = i(b);
ip = i([false; b(1:end-1)]);
a = accumarray(im,1,[m+2,1])-accumarray(ip,1,[m+2,1]);
mask = cumsum(a);
mask(i) = 1;
Aclean(:,j) = Aclean(:,j).*mask(2:end-1);
end
Aclean
##### 3 CommentsShowHide 2 older comments
Bruno Luong on 2 Oct 2018
No, I'm just used to HISTC.

Sign in to comment.

### More Answers (2)

Michal Kvasnicka on 1 Oct 2018
Edited: Michal Kvasnicka on 1 Oct 2018
I am still looking for better (faster) solution. Any idea how to improve so far best solution:
A = [1 -1 0;
0 1 1;
0 1 1;
1 1 0;
0 0 1;
1 -1 0;
-1 1 1;
-1 0 -1;
1 1 1;
0 1 -1];
N = 3;
sep = A==-1;
sep(1,:) = true;
idx = cumsum(sep(:));
sep(1,:) = A(1,:)==-1;
num = accumarray(idx, A(:)==1);
iff = num <= N;
Aclean = reshape(sep(:)|iff(idx), size(A)) .* A;
Aclean
Big test matrix:
A = double(rand(100000,1000)>.4) - double(rand(100000,1000)>.65);
Bruno's code (N = 5): Elapsed time is 4.848747 seconds.
My code (N = 5): Elapsed time is 3.257089 seconds.
##### 13 CommentsShowHide 12 older comments
Bruno Luong on 2 Oct 2018
And what about
mask = Aclean==A
?

Sign in to comment.

Bruno Luong on 2 Oct 2018
That's true, somehow it's a 1D scanning problem.
I think we are close to the limit of MATLAB can do, if faster speed is still needed, then one should go to MEX programming route instead of torturing MATLAB to squeeze out the last once of speed.
##### 1 CommentShowHide None
Bruno Luong on 2 Oct 2018
Sorry, it should be in the comment section

Sign in to comment.

R2018a

### Community Treasure Hunt

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

Start Hunting!