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/