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

 From wgould@stata.com (William Gould, StataCorp LP) To statalist@hsphsun2.harvard.edu Subject Re: st: Q about programming in mata re. syntax Date Thu, 25 Oct 2007 11:09:59 -0500

```Xiaoheng Zhang <zhangx@tcd.ie> 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

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.

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
wgould@stata.com
*
*   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/
```