Statalist


[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

Re: st: Q about programming in mata re. syntax


From   [email protected] (William Gould, StataCorp LP)
To   [email protected]
Subject   Re: st: Q about programming in mata re. syntax
Date   Thu, 25 Oct 2007 11:09:59 -0500

Xiaoheng Zhang <[email protected]> is having trouble understanding and using 
Mata syntax, and offers the following:

        . mata
        -------------------------- mata (type end to exit)
        : for (k=1; k<=2; k++) {
        >     r`k' = rowmin(D)
        >     C`k' = J(3 , 3 , 2)
        >     for (i=1; i<=3; i++) {
        >         for (j=1; j<=3; j++) {
        >             if (D[ i , j ] == r`k'[ i , 1 ])
        >                 C`k'[ i , j ] = 1
        >                 D[ i , j ] = D[ i , j ] + 10000
        >             else C`k'[ i , j ] = 0
        'else' found where almost anything else expected
        r(3000);

        : }
        expression invalid
        r(3000);

        : }
        expression invalid
        r(3000);

        : }
        expression invalid
        r(3000);

        : end
        -----------------------------------------------------------

Xiaoheng has one typogrpahical error and one conceptual error in the above.
The typographical error is in 

                      if (D[ i , j ] == r`k'[ i , 1 ]) 
                          C`k'[ i , j ] = 1
                          D[ i , j ] = D[ i , j ] + 10000
                      else C`k'[ i , j ] = 0

I suspect he means to code 

                      if (D[ i , j ] == r`k'[ i , 1 ]) {
                          C`k'[ i , j ] = 1
                          D[ i , j ] = D[ i , j ] + 10000
                      }
                      else C`k'[ i , j ] = 0

Note that I added braces. 

The conceptual error, however, is more serious.  Throughout his code, Xiaohang
refers to r`k' and C`k'.  The Stata macro-substitution syntax makes no sense
to Mata and the entire approach is simply not going to work.

Xiaoheng wants to start with a Distance matrix D

                    Distance between firms
                  | 1          2         3
                --+---------------------------
                1 | 0          5         7
                2 | 5          0         2
                3 | 7          2         0
                ------------------------------
           
                (Three firms shown for illustration)

and create two indicator matrices, C1 showing the nearest firm:

                  | 1          2         3        meaning 
                --+---------------------------
                1 | 0          1         0        nearest to 1 is 2
                2 | 0          0         1        nearest to 2 is 3
                3 | 0          1         0        nearest to 3 is 2
                ------------------------------

and C2, showing the second nearest firm:

                  | 1          2         3        meaning 
                --+---------------------------
                1 | 0          0         1        2nd nearest to 1 is 3
                2 | 1          0         0        2nd nearest to 2 is 1
                3 | 1          0         0        2nd nearest to 3 is 1
                ------------------------------

So that's the problem:  Given D, produce C1 and C2.  

The first thing I'm goping to do is change the problem a little.  I'm going 
to produce vectors c1 and c2, c1 containing 

                  |                               meaning 
                --+---                          
                1 | 2                             nearest to 1 is 2
                2 | 3                             nearest to 2 is 3
                3 | 2                             nearest to 3 is 2
                ------                          

and c2, a vector defined similarly.  It will be easy enough to produce C1 
from c1 and produce C2 from c2, as I will show.

First, here's a function that, given D, produces c1:

        real colvector closest(D)
        {
                c = J(rows(D), 1, 0)
                for (i=1; i<=rows(D); i++) { 
                        j_min = d_min = . 
                        for (j=1; j<=cols(D); j++) {
                                if (i!=j) {
                                        if (D[i,j]<d_min) { 
                                                j_min = j
                                                d_min = D[i,j]
                                        }
                                }
                         }
                         c[i] = j_min
                  }
                  return(c)
        }

and here's a function that will produce c2 given D and c1:


        real colvector closest2(D, c1)
        {
                D2 = D
                for (i=1; i<=rows(D); i++) D2[i,c1[i]] = .
                return(closest(D2))
        }

and finally, here's a function that will produce a C matrix from a c vector:


        real matrix C_of_c(c)
        {
                C = J(rows(c), rows(c), 0)
                for (i=1; i<=rows(C); i++) C[i,c[i]] = 1
                return(C)
        }

Below I try them out:

        : D = (0,5,7 \ 5,0,2 \ 7,2,0)

        : D
        [symmetric]
               1   2   3
            +-------------+
          1 |  0          |
          2 |  5   0      |
          3 |  7   2   0  |
            +-------------+

        : c1 = closest(D)

        : c1
               1
            +-----+
          1 |  2  |
          2 |  3  |
          3 |  2  |
            +-----+

        : c2 = closest2(D, c1)

        : c2
               1
            +-----+
          1 |  3  |
          2 |  1  |
          3 |  1  |
            +-----+

        : C_of_c(c1)
               1   2   3
            +-------------+
          1 |  0   1   0  |
          2 |  0   0   1  |
          3 |  0   1   0  |
            +-------------+

        : C_of_c(c2)
               1   2   3
            +-------------+
          1 |  0   0   1  |
          2 |  1   0   0  |
          3 |  1   0   0  |
            +-------------+

-- Bill
[email protected]
*
*   For searches and help try:
*   http://www.stata.com/support/faqs/res/findit.html
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/



© Copyright 1996–2024 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index