0

I have 3 sequences in a cell-array:

Input_cell= {'ABCD','ACD', 'ABD'}

 S1= 'ABCD' % which means A<B<C<D
 S2= 'ACD'  % which means A<C<D  % missing B in the full string of 'ABCD'
 S3= 'ABD'  % which means A<B<D  % missing C in the full string of 'ABCD'

I want to convert each of the strings in the Input_cell into a matrix M (i-by-j) which has to satisfy these conditions:

  • M(i,j) and M(j,i) are random
  • M(i,i) = 0.5
  • M(i,j) + M(j,i) = 1
  • M(i,j) < M(j,i) For example if A<B then M(A,B) < M(B,A)

For example if we have S1 = 'ABCD' (which means A<B<C<D), the M1 matrix will be expected as follows:

     A      B     C     D
 A  0.5    0.3   0.2   0.1 
 B  0.7    0.5    0    0.4
 C  0.8     1    0.5   0.1
 D  0.9    0.6   0.9   0.5

If we have S2 = 'ACD' (which means A<C<D), missing B in the full string of 'ABCD', we will put the value 0.5 in every position of B in the matrix, the M2 matrix will be expected as follows:

     A      B     C     D
 A  0.5    0.5   0.2   0.1 
 B  0.5    0.5   0.5   0.5
 C  0.8    0.5   0.5   0.1
 D  0.9    0.5   0.9   0.5  

If we have S3 = 'ABD' (which means A<B<D), missing C in the full string of 'ABCD', we will put the value 0.5 in every position of C in the matrix, the M3 matrix will be expected as follows:

     A      B     C     D
 A  0.5    0.4   0.5   0.1 
 B  0.6    0.5   0.5   0.3
 C  0.5    0.5   0.5   0.5
 D  0.9    0.7   0.5   0.5  

How to create that kind of above matrices from a given cell-array of sequences?

1 Answer 1

1

Firstly you need to work out how to do this just for a single sequence:

  1. Create a matrix of random numbers between 0.5 and 1:

    M = 0.5*rand(4) + 0.5;
    
  2. Set the main diagonal to equal 0.5

    M(logical(eye(4))) = 0.5;
    
  3. Set the upper triangle of M equal to 1 - the lower triangle:

    M(triu(true(4))) = 1 - M(tril(true(4)));   %// Note the main diagonal doesn't matter...
    
  4. Work out which letter is missing and set the row and column equal to 0.5 accordingly:

    fullSeq = 'abcd';
    idx = find(fullSeq == setdiff(fullSeq, 'abd'));
    %// at this point you'll need to check if idx is empty first...
    M(:,idx) = 0.5;
    M(idx,:) = 0.5;
    

And now that you can do it for one matrix, just loop over your cell array or else encapsulate this into a function and use cellfun.

Sign up to request clarification or add additional context in comments.

6 Comments

Could you please tell me how to use cellfun for this case please ?
@kgk - you will take all the code as above, make it into a function which is trivial and well documented and then just call that function with cellfun so if you called it MyFunc then you go cellfun(@MyFunc, Input_cell) or if you get an error about uniform outputs then cellfun(@MyFunc, Input_cell, 'Uni', false)
Thanks ! But after calling cellfun , I got the error : "Matrix dimensions must agree" .
Maybe you should ask a new question (linking to this one) specifically about how to make your function work with cellfun. Give example data and code again. It's difficult to answer this in the comments. (I'm assuming you got this working using loops already btw)
@kgk can't you just create it as an "ABCD" matrix and then fliplr?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.