Re: st: doubt on Mata using multiple loops

Gioia de Melo wrote:
I have problems linking two matrices with for and if.
Matrix X is of n*5, in the first column it identifies firms, columns 2:5
identify firms that are connected to firm in column 1. I need to create a
symmetric matrix A nxn that has 1 in cells between two firms that are
connected.
I run this program but it does not alter A although it does not point any
error:
[mata code omitted]
Thank you for your help.
--------------------------------------------------------------------------------
If I understand your dataset correctly, then the mata function below should
work. You can see whether I understood your data structure (firm connections)
by examining the listing that the do-file does with the toy dataset it creates.
As a data-integrity check, the function will optionally give you values greater
than one if your dataset contains redundant connections (duplicate data). The
values shown in the returned matrix are the tallies of duplicate connections.
The option is on by default.
I haven't checked the code in order to see whether it works correctly
as-intended, but you can at least get an idea of how to do loops more
efficiently than what you showed. I used a single loop in order to go through
the firms one-by-one. This would be slower than a colon operator, but I suspect
that a colon operator requires creating a second n-by-n matrix inside the
function, and so using the one loop trades-off some speed for memory efficiency.
Joseph Coveney
version 11.0
clear *
set more off
set seed `=date("2010-03-15", "YMD")'
local firm_tally 20
set obs `firm_tally'
generate byte firm_nr = _n
// Each firm may be "connected to" up to four of the others
quietly forvalues connection = 1/4 {
// A value of zero means the firm is unconnected
generate byte connected_to`connection' = ///
floor((`firm_tally' + 1) * runiform())
replace connected_to`connection' = 0 ///
if connected_to`connection' == _n
}
list , noobs abbreviate(15) separator(0)
mata
mata set matastrict on
real matrix function getConnectedFirms(| real scalar show_duplicates) {
show_duplicates = (args() == 0) ? 1 : show_duplicates // Opt-out
real matrix Results
Results = J(st_nobs(), st_nobs(), 0)
transmorphic colvector Firms
Firms = (.)
st_view(Firms, ., 1)
real rowvector Connections // Can't transpose a view
Connections = (.)
real scalar connection_nr, firm_nr // Indexes
for (connection_nr=2; connection_nr<=st_nvar(); connection_nr++) {
Connections = st_data(., connection_nr)'
for (firm_nr=1; firm_nr<=st_nobs(); firm_nr++) {
Results[firm_nr, .] = Results[firm_nr, .] :+
(Firms[firm_nr, .] :== Connections)
}
}
if (show_duplicates) {
return(Results)
}
else {
return(Results :> 0)
}
}
getConnectedFirms()
getConnectedFirms(0)
getConnectedFirms(1)
end
*
* For searches and help try:
* http://www.stata.com/help.cgi?search
* http://www.stata.com/support/statalist/faq
* http://www.ats.ucla.edu/stat/stata/