# Identifying sequences in a Matrix

4 views (last 30 days)
RG on 11 Oct 2017
Edited: Cedric Wannaz on 12 Oct 2017
Currently working on a sequential ligament cutting sequence where we are trying to compare outcomes between similar clusters of sequential ligament cuts. For example we have
• Experiment 1: Lig A Lig B Lig C Lig D Lig E
• Experiment 2: Lig A Lig B Lig E Lig B Lig C
• Experiment 3: Lig A Lig E Lig B Lig C Lig D
With a separate matrix that are the measured outcomes corresponding to the sequence described
In comparing like clusters, we would like to compare outcomes that are similar i.e.
• Compare outcome after ligament A sectioning for all three groups (timepoint 1)
• Compare outcome after ligament A and B sectioning for Experiments 1 and 2 (timepoint 2)
• Compare outcome after ligament A/B/E sectioning with A/E/B in Experiments 2 and 3 (timepoint 3, order does not matter)
So far I've seen the diff function being used to determine whether, for example, ligament A and B are clustered, or ligament B and C are clustered, but this runs into problems when comparisons are made between A and C vs. C and E (both diff will produce 2). So this is clearly not a solution.
Any thoughts on how to tackle this? Thanks!

Cedric Wannaz on 11 Oct 2017
You can find sequences using STRFIND, even when you are dealing with numbers:
>> seq_str = 'ACEBAECE' ;
>> strfind( seq_str, 'CE' )
ans =
2 7
>> strfind( seq_num, [3,5] )
ans =
2 7
##### 2 CommentsShowHide 1 older comment
Cedric Wannaz on 12 Oct 2017
Use PERMS, or better, pre-process the sequence and replace all characters to match with some place holder, and search for place holders:
seq_str = 'ACEBAECE' ; % Sequence.
subseq = 'CE' ; % What we want to match but order doesn't matter.
seq_copy = seq_str ; % Build copy that we can alter.
Then we replace all letters from the copy that are in subseq with an underscore. Here is one way to do it if you have a recent enough version of MATLAB (let me know if not):
seq_copy(any( seq_str == subseq.' )) = '_' ;
Evaluating the inner expressions helps to understand. There in an automatic expansion involved:
>> seq_str == subseq.'
ans =
2×8 logical array
0 1 0 0 0 0 1 0 <-- flag "has 'C'"
0 0 1 0 0 1 0 1 <-- flag "has 'E'"
>> any( seq_str == subseq.' )
ans =
1×8 logical array
0 1 1 0 0 1 1 1 <-- flag "has any"
The outcome of the replacement is therefore this:
seq_copy =
'A__BA___'
And then we look up for occurrences of as many place holder characters as there are characters in subseq. There are two ways to do it depending if the sequence has to be "eaten" (which means that matched characters cannot be reused for matching what follows) or not:
>> pos = regexp( seq_copy, repelem( '_', numel( subseq )))
pos =
2 6
>> pos = strfind( seq_copy, repelem( '_', numel( subseq )))
pos =
2 6 7
and you have to pick the one that is appropriate for your context.