0
votes

I want to find double sequences (of 10-bit data, not necessary here) which length is more than 2. The double sequence of certain elements can be numbered by two indices, here. Example data is

data = [ 4.123456 4.123456 4.123456 4.123456 7.123456 1.123456 1.123456 1.123456 ] 

which expected output is

{[4.123456 4.123456 4.123456 4.123456], [1.123456 1.123456 1.123456]}

Hankel approach

I am interested in transformations like hankel as used well in the answer here about Finding a sequence of 4 values in an array without loop and described here by J. Layman well. Hankel provides a transformation of a sequence and the determinant of its matrix is Catalecticant, where the latter property is the one that can be useful here. It may characterise the two indices of the double sequence.

The problem here is that whether we can characterise Hankel determinants of the given sequences or not. I think it may not be possible.

Incomplete Pseudocode

  1. Transform data into square matrix and use two indices to express doubles.
  2. Loop the first index.
  3. Loop the second index.
    1. Set counter if two vectors (1st and 2nd indexes) are the same.
    2. Reset counter if the third vector is not expected as the previous two.
    3. Go back to (1).
    4. End at end of data.

How can you find double Sequence in the data?

2

2 Answers

2
votes

My solution of the problem, assuming I understood it correctly:

x = [9 1 5 6 6 6 5 1 1 0 7 7 7 7 7 8];

d = diff(diff([0 x 0]) == 0);
y = arrayfun(@(i,j) x(i:j), find(d>0), find(d<0), 'Uniform',false);
celldisp(y)

The result for this example:

x =
     9     1     5     6     6     6     5     1     1     0     7     7     7     7     7     8

y = 
    [1x3 double]    [1x2 double]    [1x5 double]
y{1} =
     6     6     6
y{2} =
     1     1
y{3} =
     7     7     7     7     7
1
votes

I would probably just try to identify consecutive duplicates and assign each of them an index. Then you can determine how many items you have in each group and only keep the ones that you care about.

%// Desired minimum length
minlen = 2;

%// Assign a unique index to each consecutive repeated value
index = cumsum([0 diff(data)] ~= 0);

%// Then group them
inds = 0:max(index);
nPerGroup = histc(index, inds);

%// Figure out which to keep
inds2keep = inds(nPerGroup > minlen);

%// Then create a cell array
values = arrayfun(@(x)data(index == x), inds2keep, 'uni', 0);

%// And just to check
celldisp(values)

    values{1} =

        4.1235    4.1235    4.1235    4.1235

    values{2} =

        1.1235    1.1235    1.1235

An alternate approach can avoid the usage of histc:

index = cumsum([0 diff(data)] ~= 0);
values = arrayfun(@(x)data(index == x), 0:max(index), 'uni', 0);
tokeep = cellfun(@(x)numel(x) >= minlen, values);
values = values(tokeep);