Announcement

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

  • Could one Stata program calls two different Mata functions?

    I am kind of curious whether this can work. I use a program to test it, but it does not work well. I think there is something wrong with my code but I cannot tell. Matrix C turns out to be a 1*1 matrix and with missing values. I am not sure where went wrong. Thank you so much!

    capture program drop tt11
    program tt11
    version 13

    mat AA = (1,2,4,5)
    mata: test10_1("AA")
    mat A2 = r(A2)
    mata: test10_2("AA")
    mat B2 = r(B2)
    mat C = B2 - A2

    end

    capture mata mata drop test10_1()
    capture mata mata drop test10_2()
    mata:
    void test10_1(string scalar A)
    {
    real matrix A1, A2
    A1 = st_matrix("A")
    A2 = A1 * 2
    st_matrix("r(A2)",A2)

    }

    void test10_2(string scalar B)
    {
    real matrix B1, B2
    B1 = st_matrix("A")
    B2 = B1 * 3
    st_matrix("r(B2)",B2)

    }
    end

  • #2
    Short answer: use
    Code:
    mata set matastrict on
    , and run the program as a do-file in order to do a first-pass debug of the code.

    Long answer: (1) When you define a token as a string (A and B in your Mata functions' argument lists, you shouldn't then surround them in double-quotation marks when you reference them later. (2) Your second Mata function defines s string scalar B in its argument list, but never refers to it. Instead, its code refers to a nonexistent string scalar A.

    Code:
    *! tt11.ado
    program define tt11
        version 13.1
        syntax
    
        matrix define AA = (1, 2, 4, 5)
    
        mata: test10_1("AA")
    
        mata: test10_2("AA")
    
        matrix define C = r(B2) - r(A2)
        matrix list C
    end
    
    version 13.1
    
    mata:
    mata set matastrict on
    
    void test10_1(string scalar A) st_matrix("r(A2)", st_matrix(A) :* 2)
    
    void test10_2(string scalar B) st_matrix("r(B2)", st_matrix(B) :* 3)
    
    end
    Attached Files

    Comment


    • #3
      Thank you for your answer. I still have some questions.

      1. I am kind of confused about the quotes. When we use st_matrix(), we should pass a string to it. Could you explain a little bit why we should or should not use quotes?

      2. Another problem with my code is that I use return mat C. When I change it into mat list C, my program works. What if I want to write a rclass Stata program? When should I use return mat?

      Thank you !!!

      Comment


      • #4
        One additional question, should we use quotes for st_local(), st_numscalar() in Mata function? I keep using them and they work for me. Would there be any differences by using quotes and not using quotes?

        Comment


        • #5
          "1. I am kind of confused about the quotes. When we use st_matrix(), we should pass a string to it. Could you explain a little bit why we should or should not use quotes?"

          I garbled my text above. I should have written, "When you define a token as a string scalar (A and B in your Mata functions' argument lists), . . ."

          You don't use quotation marks when the argument to st_matrix() is a string scalar (a variable containing the text). You do when it is a string literal (the text, itself).

          When you passed the name of the Stata matrix AA to your Mata function as an argument (mata: test10_1("AA") in your code above), you passed it as a string literal. So you needed the double-quotation marks.

          Your Mata functions assigned the value to a string scalar (A or B in your code above). You don't put double-quotation marks around the name of your string scalar when referring to it in st_matrix().

          On the other hand, when you pass the name of the Stata matrix directly to st_matrix() as a string literal, e.g., B1 = st_matrix("AA"), you must surround the string literal by double-quotation marks.

          This is all better explained in this Stata Journal article.

          "2. Another problem with my code is that I use return mat C. When I change it into mat list C, my program works. What if I want to write a rclass Stata program? When should I use return mat?"

          You haven't shown your (apparently new) code and so it's impossible to say what you've done wrong. If you're defining C as you've done above, then you don't need to use rclass programming and return matrix. The matrix C will be available to Stata after your program ends.

          Comment


          • #6
            Very good answers. Thanks a lot! But I would say that for a string scalar, st_matrix() would also work if you quotes it. But I think this is definitely not a good programming style. Thank you for clarifying the above two points!

            Comment


            • #7
              I'd would be curious to see your example where it does. Here's one where it doesn't.

              .ÿdoÿ"F:\tt11.ado"

              .ÿ*!ÿtt11.ado
              .ÿprogramÿdefineÿtt11
              ÿÿ1.ÿÿÿÿÿÿÿÿÿversionÿ13.1
              ÿÿ2.ÿÿÿÿÿÿÿÿÿsyntax
              ÿÿ3.ÿ
              .ÿÿÿÿÿÿÿÿÿmatrixÿdefineÿAAÿ=ÿ(1,ÿ2,ÿ4,ÿ5)
              ÿÿ4.ÿÿÿÿÿÿÿÿÿmata:ÿtest10_1("AA")
              ÿÿ5.ÿ
              .ÿÿÿÿÿÿÿÿÿmatrixÿlistÿr(A2)
              ÿÿ6.ÿend

              .ÿ
              .ÿmata:
              -------------------------------------------------ÿmataÿ(typeÿendÿtoÿexit
              >ÿ)ÿ--------------------------------------------------------------------
              :ÿvoidÿfunctionÿtest10_1(stringÿscalarÿA)ÿ{
              >ÿÿÿÿÿÿÿÿÿrealÿmatrixÿA1,ÿA2
              >ÿÿÿÿÿÿÿÿÿA1ÿ=ÿst_matrix("A")
              >ÿ"BeginÿListingÿA1:"
              >ÿA1
              >ÿ"EndÿListingÿA1"
              >ÿÿÿÿÿÿÿÿÿA2ÿ=ÿA1ÿ*ÿ2
              >ÿÿÿÿÿÿÿÿÿst_matrix("r(A2)",ÿA2)
              >ÿ
              >ÿ}
              note:ÿargumentÿAÿunused

              :ÿendÿ
              ------------------------------------------------------------------------

              .ÿ
              .ÿexit

              endÿofÿdo-file


              .ÿtt11
              ÿÿBeginÿListingÿA1:
              ÿÿEndÿListingÿA1
              matrixÿr(A2)ÿnotÿfound
              r(111);

              .

              Comment


              • #8
                Joseph,
                There is a small mistake in your program, which prevents to make it work. If you write

                Code:
                A1ÿ=ÿst_matrix(A)
                then the program works, otherwise A2 is empty/void and so is r(A2) .
                Besides I am not sure it is such a good idea to send matrices from Mata in Stata called r(`something'). If you write your program as an rclass, then r(A2) will disappear after the program is called and will not be part of the return list. If you write an eclass program, then you can use it with ereturn matrix. I know that Kit Baum has some examples in his book "Introduction to Stata programming" (nice book BTW) where he uses this technique, but I don't see the point after. I have tried the technique myself and as there were a few drawbacks I dropped it. I think if the matrices are temporary then it is better to define tempnames in the Stata programs and then use st_local() in your Mata-program

                Code:
                program foo , rclass
                tempname A mata:fooMata() ret matrix A = `A'
                end mata: void fooMata() {
                st_matrix(st_local("A"),J(2,2,0)
                } end foo ret li

                Comment


                • #9
                  Originally posted by Christophe Kolodziejczyk View Post
                  There is a small mistake in your program, which prevents to make it work. If you write

                  Code:
                  A1ÿ=ÿst_matrix(A)
                  then the program works, otherwise A2 is empty/void and so is r(A2) .
                  Christophe, it's not my program, but your point is exactly the point I was trying to make.



                  Comment


                  • #10
                    Ok. I missed the point , sorry.
                    And I meant

                    If you write an eclass program, then you canNOT use it with ereturn matrix

                    Comment


                    • #11
                      Originally posted by Christophe Kolodziejczyk View Post
                      Joseph,
                      There is a small mistake in your program, which prevents to make it work. If you write

                      Code:
                      A1ÿ=ÿst_matrix(A)
                      then the program works, otherwise A2 is empty/void and so is r(A2) .
                      That is what confuses me, because in another Stata program, I use quotes but it just works well. But in this case, it doesn't work at all. But still thanks.

                      Comment


                      • #12
                        You should show us the code where it works. My guess is that you refer directly to the Stata matrix and therefore passing the name of the matrix as an argument is irrelevant.
                        In the first example below the string scalar A is never used, but the program works because the Stata matrix "AA" exists already in memory. In his example Joseph refers to matrix "A" in st_matrix() (following your logic that you have to refer to the argument with quotes) but this matrix does in exist in Stata's memory, hence the error. We could just make write the function without arguments and the function would have little purpose.

                        Example 1:
                        Code:
                        mata:
                        void test10_1(string scalar A)
                        {
                        A
                        real matrix B B = st_matrix("AA")
                        } end
                        In this second example, I pass the Mata object A, which is a string scalar, to st_matrix(), and not "A". It makes the function more useful since you use its argument.

                        Example 2;
                        Code:
                        mata:
                        void test10_1(string scalar A)
                        {
                        A
                        real matrix B B = st_matrix(A)
                        } end
                        Note that you can directly use expressions in a function if the results of the expressions agrees with the eltype and the orgtype of the arguments of the function. It is maybe this which confuses you.

                        This lines of codes are equivalent
                        Code:
                        st_matrix("A"+"A")
                        
                        A = "A" + "A"
                        st_matrix(A)

                        Comment


                        • #13
                          Originally posted by Christophe Kolodziejczyk View Post
                          You should show us the code where it works. My guess is that you refer directly to the Stata matrix and therefore passing the name of the matrix as an argument is irrelevant.
                          The code is too long and st_matrix() is just a small part of it. I double checked the code and you are right about that. Thank you for your patience and helpfulness!!!

                          Comment


                          • #14
                            I meant the part which works and uses st_matrix() and not the whole code, or as suggested by Joseph in #7 an exemple which supports your claim, so we can reproduce the problem.

                            Comment


                            • #15
                              I will try to find out that program tomorrow. But since it fails sometimes, I think I just change the code in your suggested way. But I will try to find them and extract them from the original code.

                              Comment

                              Working...
                              X