Announcement

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

  • Mata loops

    I have a matrix A that I want to jumble the rows and take the logs of. Then taking the elements on the diagonal and creating a variable in Stata.

    Click image for larger version

Name:	Capture.PNG
Views:	1
Size:	19.0 KB
ID:	1405097



    Tried this bit of code.
    mata:
    for (i=1; i<=3; i++) {
    jumble(A)
    logA`i' = log(A)
    Ad`i' = diagonal(logA`i')
    st_matrix("Ad`i'", Ad`i')
    }
    end

    But it merged all of it into i. I know the code is clunky, but I'm not familiar with loops in Mata.


    Click image for larger version

Name:	Capture2.PNG
Views:	1
Size:	55.2 KB
ID:	1405098


    Thanks, Gene

  • #2
    Gene Sim
    Mata does not know about locals (and globals). By thw way there is a nice Mata matters article in the Stata Journal about locals and globals you could read.
    So in a loop you cannot refer to i with `i'. In this case it is just an empty local.
    Create instead the stata name Ad1, Ad2, Ad3 with strofreal(). Note also the difference between _jumble and jumble.
    There is another issue in your code. In your code example writing jumble(A) will just show the result but will not change the content of A. Since jumble() returns a matrix you have to code for example

    Code:
    B = jumble(A)

    If you want to change the content of A use the same function with an underscore. Contrary to jumble it returns nothing but changes the argument.

    Code:
    mata:  
    for (i=1; i<=3; i++) {
    _jumble(A) Ad = diagonal(log(A)) // or replace the previous two lines with Ad = diagonal(log(jumble(A))) st_matrix("Ad"+strofreal(i), Ad) // <= creates Stata matrices Ad1, Ad2 and Ad3
    } end
    or shorter

    Code:
    mata:
    for (i=1; i<=3; i++) {
    st_matrix("Ad"+strofreal(i), diagonal(log(jumble(A)))) // <= creates Stata matrices Ad1, Ad2 and Ad3
    }
    end
    Last edited by Christophe Kolodziejczyk; 04 Aug 2017, 12:55.

    Comment


    • #3
      Christophe Kolodziejczyk
      Thanks for this! Exactly what I needed. Absolutely spot on,touché

      Comment


      • #4
        Hi Christophe Kolodziejczyk, thank you for the reply.

        the code work perfectly to create multiple matrices and export to Stata but what about creating matrices only in MATA without posting them into Stata?

        for example let "Ad" matrix is identity matrix. I run the following code but get error:

        mata:
        Ad=I(3)
        for (i=1; i<=3; i++) {
        "Ad"+strofreal(i)= Ad
        }
        end

        thanks.

        Comment


        • #5
          Code:
          "Ad"+strofreal(i)= Ad
          A couple of things are wrong with this:
          1) The left side of statement that assigns a value must be the name of a variable, not an expression. That is true in every computer language I have ever seen.
          2) Perhaps you think you are using a string expression on the left side to create a variable name to which the matrix Ad will be assigned. That won't work. A variable name can't be a string expression. Again, I don't know any computer language that will allow that kind of construction.

          To understand this, try in Mata:
          Code:
          Z = 1
          "Z=" 1
          The first statement says "Assign to the variable named Z the value 1." The second statement says "Assign to the string expression "Z" the value 1."

          My understanding is that you want to create matrices named Ad1, Ad2, Ad3 each of which would contain the original matrix Ad. If that is what you want, I don't know how you would do that in a loop. But, more importantly, I would guess that is not a good way to do what you want. I'd suggest you explain what you are trying to do here, perhaps with a *small* example. If you can do that, someone will likely have a better idea of how to do this. One guess I might have is that you want to simulate a three-dimensional matrix, about which there is a short thread here. However, I would not be sure that is the best approach for your problem.

          Comment


          • #6
            Regarding creating a Mata variable within a Mata loop, here is how you could do, using the crexternal() mata function. Here the loop does nothing very interesting. After it's executed, the somevar1, somevar2 and somevar3 external variables are defined and contain real matrices. Notice that crexternal() returns a pointer to an empty real matrix, but you can put whatever you need. For instance, *p = J(i,i, 1i) would create a complex matrix. See -help mf_findexternal- for more information on this and related functions. See also -help mf_valofexternal- and -help mf_direxternal- for other useful ones.

            mata
            for (i = 1; i <= 3; i++) {
            p = crexternal(sprintf("somevar%f", i))
            *p = J(i, i, 1)
            }
            end
            Hope this helps

            Jean-Claude Arbaut
            Last edited by Jean-Claude Arbaut; 17 Apr 2018, 06:01.

            Comment


            • #7
              One way to accomplish what I believe is the objective stated in #4
              Code:
              mata:
              Ad=I(3)
              for (i=1; i&lt;=3; i++) {
              "Ad"+strofreal(i)= Ad
              }
              end
              is this:
              Code:
              mata
              Ad=I(3)
              for (i=1;i<=3;i++) {
                stata("mata: Ad"+strofreal(i)+"=Ad")
              }
              end
              This is clunky and probably not efficient. But it is a workaround for the kinds of issues that Mike (appropriately) raises in #5.

              Comment

              Working...
              X