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

1 回表示 (過去 30 日間)
Michal
Michal 2018 年 10 月 1 日
コメント済み: Bruno Luong 2018 年 10 月 2 日

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 件のコメント
Matt J
Matt J 2018 年 10 月 1 日
編集済み: Matt J 2018 年 10 月 1 日
which now can be separated by any number of zeroes
This is the definition of non-consecutive. Why, then, are you saying the eliminated 1's are to be consecutive?
Michal
Michal 2018 年 10 月 1 日
Well OK, any sequence of "1's" and "0's" separated by start/end and "-1's".

サインインしてコメントする。

採用された回答

Bruno Luong
Bruno Luong 2018 年 10 月 1 日
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 件のコメント
Michal
Michal 2018 年 10 月 2 日
Is there any serious reason to still use old "histc" instead "histcounts"? Both functions has same performance and "histc" will be removed in future releases.
Bruno Luong
Bruno Luong 2018 年 10 月 2 日
No, I'm just used to HISTC.

サインインしてコメントする。

その他の回答 (2 件)

Michal
Michal 2018 年 10 月 1 日
編集済み: Michal 2018 年 10 月 1 日
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 件のコメント
Michal
Michal 2018 年 10 月 2 日
Yes … nice simplification!
Bruno Luong
Bruno Luong 2018 年 10 月 2 日
And what about
mask = Aclean==A
?

サインインしてコメントする。


Bruno Luong
Bruno Luong 2018 年 10 月 2 日
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.

カテゴリ

Help Center および File ExchangeWaveform Generation についてさらに検索

製品


リリース

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by