2011-12-18

Indexing matrix elements of different indexes in different rows in Octave or MATLAB

Here is a tricky programming problem in Octave or MATLAB. Given a matrix A, and another array Y, how to build a new array Z such that Z(i)=A(i, Y(i)) without using loops?

In other words I need to pick one (and only one) element per row while the indexes of elements vary in rows. This is easy if using loops but I am a ``vectorization freak.''

Below is a solution I found out. A is the given matrix. Y is the array specifying the element of each row to be picked out.

Please note I call trace() function in the end, because I don't really need the array Z but only its sum. So I simply need to sum the diagonal of the last square matrix.

Comments are welcomed. Do you know any name for this operation? And does Octave or MATLAB already has a solution for this?

octave:2> A=magic(10)(:,1:4)
A =

    92    99     1     8
    98    80     7    14
     4    81    88    20
    85    87    19    21
    86    93    25     2
    17    24    76    83
    23     5    82    89
    79     6    13    95
    10    12    94    96
    11    18   100    77

octave:3> Y=ceil(rand(10,1)*4)
Y =

   2
   1
   1
   3
   2
   1
   3
   4
   2
   3

octave:4> A(:,Y)
ans =

    99    92    92     1    99    92     1     8    99     1
    80    98    98     7    80    98     7    14    80     7
    81     4     4    88    81     4    88    20    81    88
    87    85    85    19    87    85    19    21    87    19
    93    86    86    25    93    86    25     2    93    25
    24    17    17    76    24    17    76    83    24    76
     5    23    23    82     5    23    82    89     5    82
     6    79    79    13     6    79    13    95     6    13
    12    10    10    94    12    10    94    96    12    94
    18    11    11   100    18    11   100    77    18   100

octave:5> Z=diag(A(:,Y))
Z =

    99
    98
     4
    19
    93
    17
    82
    95
    12
   100

octave:6> trace(A(:,Y))
ans =  619
octave:7> sum(diag(A(:,Y)))
ans =  619

No comments: