Bookmark and Share

Notice: On April 23, 2014, Statalist moved from an email list to a forum, based at statalist.org.


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: st: doubt on Mata using multiple loops


From   "Joseph Coveney" <[email protected]>
To   <[email protected]>
Subject   Re: st: doubt on Mata using multiple loops
Date   Sun, 14 Mar 2010 20:49:22 +0900

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/


© Copyright 1996–2018 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   Site index