Announcement

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

  • Creating new variables with for loop

    Dear all,

    A simple code:

    for (x = 1; x <= 5; x++) {
    m_x = x
    }

    doesn't create five variables (m_1...m_5), as I expected, but rather creates one variable m_x.
    Anyone has any idea about how to make Mata generate these 5 variables in a loop? Would be much appreciated.

    Dmitry

  • #2
    You are expecting Mata scalars to behave like Stata local macros. Short answer is that won't work. Another answer is that if this were true, then there would be a horrible class of bugs. If I really want m_x or a variable excellent inside a loop with index x, I am scuppered. Mata would instead create e1cellent, etc. But it doesn't work like that.

    A longer answer starts by saying that there are different and usually better ways to do what you want. One is that a set of related scalars is usually best created as a vector. Another is that you need to know about pointers.

    A fuzzier truth is that features you like and are familiar with aren't always available in other languages.

    Some references:

    SJ-11-2 pr0052 . . . . Stata tip 100: Mata and the case of the missing macros
    . . . . . . . . . . . . . . . . . . . . . . . . W. Gould and N. J. Cox
    Q2/11 SJ 11(2):323--324 (no commands)
    tip showing how to do the equivalent of Stata's macro
    substitution in Mata

    SJ-8-3 pr0040 . . . . . . . . . . . . . . . . . . . . . Mata Matters: Macros
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . W. Gould
    Q3/08 SJ 8(3):401--412 (no commands)
    describes why macros are seldom needed in Mata and
    outlines what you might do with macros in Mata
    Last edited by Nick Cox; 09 Jun 2014, 16:14.

    Comment


    • #3
      Thank you, Nick!

      ​The only thing which I should have mentioned in the first place is that m_x in my application are, actually, matrices, not scalars. Hence, I doubt that the solution with a vector of matrices would work. But thank you for the references and pointers - I will read it carefully.

      Dmitry

      Comment


      • #4
        To be more precise, what I need is the following:

        for (x = 1; x <= 1000; x++) {
        P_x = J(10,20,.)
        }

        In words, I need to generate 1000 for now missing matrices, each of them should be labeled P_1, P_2 ... P_1000.
        Now, the above code doesnt work and it is clear why. So far my understanding of pointers also cannot help to solve this problem.
        I am a bit frustrated as it is a very easy task for Stata, but in Mata it becomes for some reason a puzzle for me...

        Comment


        • #5
          You need a thousand of these simultaneously? Could you work with J(10000,20,.)? If so and if not, then it sounds like pointers.

          Comment


          • #6
            As Nick mentioned, a set of related scalars--or in this instance, an array of related matrices--is best handled as a Mata vector, and you'll benefit from a knowledge of Mata pointers. In this case, you can put the two together with a pointer vector that can point to your 1000 missing-valued matrices.
            Code:
            version 13.1
            
            mata:
            mata set matastrict on
            
            void function assignMatrix(real scalar x, pointer(real matrix) vector P) {
            
                real matrix M
                M = J(10, 20, .)
            
                P[x] = &M
            }
            
            void function demo() {
            
                pointer(real matrix) vector P
                P = J(1, 1000, NULL)
            
                real scalar x
                for (x=1; x<=1000; x++) {
                    assignMatrix(x, P)
                }
            
                // Dereference P[index] and do stuff with the missing-valued matrix
            }
            
            end
            
            exit

            Comment


            • #7
              In interactive mode you can write

              Code:
              forval x = 1/1000 {
                        mata: p_`x' = J(10, 20,.)
              
              }
              
              mata:p_1
              An alternative to Joseph solution could be
              Code:
              mata:
              
              M = J(1,1000,NULL)
              
              for (i=1;i<=1000;i++)
              {
                        M[1,i] = &J(10,20,.)
              }
              
              end
              You access the first matrix by typing

              Code:
              *M[1,1]
              In non-interactive mode you have to use a vector of pointers to collect the different matrices in one place. See the help on pointers from the Mata manual.

              Comment


              • #8
                Great, thanks a lot!!

                Comment


                • #9
                  For those interested in the question: the quoted nice piece of code

                  Originally posted by Christophe Kolodziejczyk View Post
                  In interactive mode you can write

                  Code:
                  forval x = 1/1000 {
                  mata: p_`x' = J(10, 20,.)
                  
                  }
                  
                  mata:p_1
                  unfortunately doesn't work with if statements. For example, the following code won't be executed:

                  Code:
                  forvalues x = 1/5 {
                      mata: if (`x' >= 2) `x'
                  }

                  Comment


                  • #10
                    One-line blocks (if, for, etc.) need to be followed by two semicolons in interactive mode. Your code works when they're added:

                    Code:
                    forvalues x = 1/5 {
                        mata: if (`x' >= 2) `x';;
                    }
                    Apparently the `x' statement needs one semicolon, and the if another. Why Mata has trouble parsing this line without them, I'm not sure.

                    Comment


                    • #11
                      See this post about the issue raised by Matthew. http://www.stata.com/statalist/archi.../msg00434.html

                      Comment

                      Working...
                      X