Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Loop for multiple matrix operations on mata

    Hello everyone,

    I would like to warn you that I am new to mata and that I have some problems with the way loops work, more precisely with the way to refer to matrices.

    All my matrices are currently on mata and look like this:
    I have 52*21 int_i_j matrices where i=1...51 and j=1994...2014 and 51 WI_i matrices where i=1...51. i represents countries and j represents years.
    What I would like to do is to multiply each int_i_j matrix by the corresponding WI matrix, i.e. the i in the int_i_j matrix and the i in the WI_i matrix must be equal. The code I did initially looks like this:

    mata

    for(i=1;i<=51;i++) {
    for(j=1994;j<=2014;k++) {
    "wgt_int_`i'_`j'=WI_`i' * int_`i'_`j'
    }
    }
    end

    wgt_int_`i'_`j' is the name I want to give to my new matrices created by multiplying the others.

    I understand that mata doesn't work like Stata and that I can't refer to the running variable in the same way (using `...'), but I can't find anywhere how to do this loop on mata.
    I would like to know if it is possible to do it and how if anyone knows.

    Thanks.

    Best regards,
    DS

  • #2
    Perhaps you can do your looping outside of Mata. In the following example, Stata resolves the values of the local macros before passing the command to Mata.
    Code:
    forvalues i=1/3 {
    forvalues j=1994/1997 {
    mata: w_`i'_`j' = J(1,1,.)
    }
    }
    mata: mata describe
    Code:
    . mata: mata describe
    
          # bytes   type                        name and extent
    -------------------------------------------------------------------------------
                8   real scalar                 w_1_1994
                8   real scalar                 w_1_1995
                8   real scalar                 w_1_1996
                8   real scalar                 w_1_1997
                8   real scalar                 w_2_1994
                8   real scalar                 w_2_1995
                8   real scalar                 w_2_1996
                8   real scalar                 w_2_1997
                8   real scalar                 w_3_1994
                8   real scalar                 w_3_1995
                8   real scalar                 w_3_1996
                8   real scalar                 w_3_1997
    -------------------------------------------------------------------------------
    
    .

    Comment


    • #3
      William's suggestion in #2 is likely to be the smartest way to do this in most contexts. But I have occasionally found myself in contexts where it's helpful to stay inside the Mata environment and have used this admittedly clunky solution that uses Mata's –Stata(...)– function
      Code:
      mata
      
      for (i=1;i<=3;i++) {
       for (j=1994;j<=1997;j++) {
        si=strofreal(i)
        sj=strofreal(j)
        ul="_"
       stata("mata: w"+ul+si+ul+sj+"=J(1,1,.)")
      }
      }
      
      mata describe w_*
      
      end
      That is, the 1x1 string that gets passed to the –Stata(...)– function is composed in part of string versions of the loop indexes.

      Comment


      • #4
        You do not tell us how how you created your 1000+ named matrices in the first place. Perhaps rather than create thousands of distinct matrices with names not easy to construct using Mata tools, you could instead choose to store your matrices as elements of a Mata associative array.
        Code:
        help mf_asarray
        Code:
        . mata
        ------------------------------------------------- mata (type end to exit) ----------------------
        : W = asarray_create("real",2)
        
        : for(i=1;i<=3;i++) {
        > for(j=1994;j<=1997;j++) {
        > asarray(W,(i,j),J(2,2,i*10000+j))
        > }
        > }
        
        : a = asarray(W,(2,1994))
        
        : a
        [symmetric]
                   1       2
            +-----------------+
          1 |  21994          |
          2 |  21994   21994  |
            +-----------------+
        
        : end
        ------------------------------------------------------------------------------------------------
        
        .
        So in this scheme, asarray(W,(i,j)) would return the matrix corresponding to your matrix w_`i'_`j'.

        Comment

        Working...
        X