# Finding cluster of positive and negative numbers in an array, then the maximum and minimum value in each cluster

5 views (last 30 days)
Alekhya Hati on 31 Oct 2022
Edited: Bruno Luong on 31 Oct 2022
Say for example, I have
a = [ 2 -2 1 4 5 -3 -2 1 -1 2 5 -2 6 -7 1 3 -4]
What I want is to group the elements as
, [-2], [1 4 5], [-3 -2], , [-1], [2 5], [-2], , [-7], [1, 3], [-4]
Next, I want to do this
, [-2], , [-3], , [-1], , [-2], , [-7], , [-4]
Finally I want to extract index position of these values in the original array aa.
[1 2 5 6 8 9 11 12 13 14 16 18]
How do I vectorize this process?
Dyuman Joshi on 31 Oct 2022
If I am understanding correct, you want min values for negative group and max values for positive groups?

Bruno Luong on 31 Oct 2022
Edited: Bruno Luong on 31 Oct 2022
NOTE: max of [-3 -2] is -2 not -3. Your array has 17 elements, cannot have element index of 18.
a = [ 2 -2 1 4 5 -3 -2 1 -1 2 5 -2 6 -7 1 3 -4];
lgt = runlengthencoder(a > 0);
c = mat2cell(a, 1, lgt);
[maxa, subidx]=cellfun(@max, c)
maxa = 1×12
2 -2 5 -2 1 -1 5 -2 6 -7 3 -4
subidx = 1×12
1 1 3 2 1 1 2 1 1 1 2 1
idx=cumsum([0, lgt(1:end-1)])+subidx
idx = 1×12
1 2 5 7 8 9 11 12 13 14 16 17
% Do the same thinh with min
...
function [len, v, gr, subidx] = runlengthencoder(X)
% [len, v, gr, subidx] = runlengthencoder(X)
% Run-length encoder
%
% INPUT
% X is (1 x n) row vector, column is also allowed
% OUTPUTS:
% len: integer arrays (1 x m)
% v: (1 x m) ordering subset of X, such that two adjadcent elements are differents
% and X = replelem(v, len)
% gr: 1:m (group number)
% subidx: (1 x n) integer, interior indexes of X with in the group
%
if ~isrow(X)
X = reshape(X, 1, []);
end
n = size(X,2);
if n > 0
b = [true, diff(X)~=0];
ij = find([b, true]);
len = diff(ij);
v = X(b);
if nargout >= 3
gr = repelem(1:length(len),len);
if nargout >= 4
subidx = ones(1,n);
subidx(ij(2:end-1)) = 1-len(1:end-1);
subidx = cumsum(subidx, 2);
end
end
else
[len, v, gr, subidx] = deal([]);
end
end % runlengthencoder