Search code examples
matlabmatrixcell-array

Generate reciprocal matrices from sequences in the cell array ( Matlab )


I have 3 sequences in a cell-array :

   S= {'ABC','ACB','AB'}
   S{1}='ABC' means A<B<C and have the weights : A:3, B:2, C:1
   S{2}='ACB' means A<C<B and have the weights : A:3, C:2, B:1
   S{3}='AB' means A<B and have the weights : A:3, B:2

I want to convert each of the strings in the Input_cell into a matrix M[i,j] which has to satisfy those conditions :

   M[i,i] =1
   M[i,j] = 1/M[j,i]
   If S{1}(i)<S{1}(j) then M[i,j]=weight(S{1}(i))/weight(S{1}(j))

For example: In S{1}= 'ABC' , and weights will be A:3, B:2, C:1

 If A<B then M[A,B]=3/2 and M[B,A]=2/3
 If B<C then M[B,C]=2/1 and M[C,B]=1/2 ....etc

So the expected matrix for S{1} would be:

       A     B    C
  A   [1    3/2  3
  B    2/3  1    2
  C    1/3  1/2  1]

In S{2}='ACB', the weights of ACB will be A:3, C:2, B:1. So the expected matrix of S{2} would be:

       A   B   C  
  A   [1   3  3/2
  B   1/3 1  1/2
  C   2/3 2  1] 

In S{3}='AB', the weights of AB will be A:3, B:2, C:unknown. If there is an unknown value, we will put 1 in the matrix. Such as M[A,C]=M[C,A]=M[B,C]=M[C,B]=1. So the expected matrix of S{3} would be: A B C A [1 3/2 1 B 2/3 1 1 C 1 1 1] How can I input the cell array of strings and convert them into matrices as above ?


Solution

  • This task has 2 parts (for each element of cell array): 1) Get numbers from strings. For example, ACB sequence is transformed to [3, 1, 2], because strength of the first column will be 3, the second 1, the third 2. 2) Create matrix from that array.

    1) Check which letter is first and put 3 on the correct place. Then check which is second, put 2. Third, put 1. If there is no number, put nan (= initialize array by nan). If you can have arbitrarily many letters thing works the same, just first figure out how big array you need. But then your 3rd case will cease to work, as it will assume you only have 2 elements and will make 2x2 matrix.

    The second part goes like this:

    seq=[3,1,2];
    M = seq' * (1./seq);
    M(isnan(M)) = 1; % all the numbers with nan become 1.
    

    Note that this will have doubles - M=1.5 and 0.3333, not fractions (1/3, 3/2). To represent it as fractions, you will require a bit more work to do it in general. For each element of the matrix, find gcd of the nominator and denominator and divide by it. In this simple case of 3 elements, you simply put nominator and denominator in the matrix with 1 on the diagonal - there are no common divisors.

    denominator = repmat(seq, 3, 1);