Announcement

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

  • Interacting with stata temporary variables within mata functions

    I am attempting to pass a value within a mata function to a stata temporary variable in an ado file.

    The function test() below stores the name of a stata temporary variable in x (eg __00000R), assigns the value 1.2 to the temporary variable, and creates a tempvar named tmpname to reference the name of the temporary variable. I attempt to display the value of tmpname within the function and outside the function. The result is that tmpname evaluates to 1.2 only outside of the function:

    Code:
    mata
        void test(){
            string scalar x
            x = st_tempname()
            st_numscalar(x,1.2)          // x is string scalar that contains 1.2. Saved to stata scalar under a tempvar name 
            st_local("tmpname",x)        // tempvar `tmpname' in stata contains the tempvar name (eg __00000R)
            stata(`"di "Inside fnc, tmpname: " `tmpname'"')        
        }
        test()
        stata(`"di "Outside fnc, tmpname: " `tmpname'"')
    end
    Output:
    Inside fnc, tmpname:
    Outside fnc, tmpname: 1.2

    How can I access tmpname within the function? The end goal is to turn test() into a objective function for optimize() that takes in an initial scalar value, passes it to a stata command, retrieves the scalar result, and computes the difference between the initial and new values.

  • #2
    Perhaps the following will show where you went wrong and will point you in a useful direction.
    Code:
    scalar drop _all
     mata
        void test(){
            string scalar x
            " "
            x = st_tempname()
            "mata string x"
            x
            " "
            st_numscalar(x,1.2)
            "in Stata from fnc, scalar list __000000"    
            stata("scalar list __000000")
            " "
            st_local("tmpname1",x)
            "in Stata from fnc, macro list _tmpname1"      
            stata("macro list _tmpname1")
            " "
            stata(`"local tmpname2 ="'+x)
             "in Stata from fnc, macro list _tmpname2"      
            stata("macro list _tmpname2")
             " "
            st_local("tmpname3",strofreal(st_numscalar(x)))
            "in Stata from fnc, macro list _tmpname3"      
            stata("macro list _tmpname3")
            " "
        }
        test()
        // Outside fnc, macro list _tmpname1 _tmpname2 _tmpname3"
        stata("macro list _tmpname1 _tmpname2 _tmpname3")
    end
    Code:
    :     test()
      
      mata string x
      __000000
      
      in Stata from fnc, scalar list __000000
      __000000 =        1.2
      
      in Stata from fnc, macro list _tmpname1
    _tmpname1:      __000000
      
      in Stata from fnc, macro list _tmpname2
    _tmpname2:      1.2
      
      in Stata from fnc, macro list _tmpname3
    _tmpname3:      1.2
      
    
    :     // Outside fnc, macro list _tmpname1 _tmpname2 _tmpname3"
    :         stata("macro list _tmpname1 _tmpname2 _tmpname3")
    _tmpname1:      __000000
    _tmpname2:      1.2
    _tmpname3:      1.2
    I'm not quite sure what you're trying to accomplish, and it's the end of my day and I won't be back for several days, but I hope this can show you how better to understand what you are accomplishing in Stata from within Mata. In particular Stata's display command is not as help as macro list and scalar list to determine exactly what Stata has defined.
    Last edited by William Lisowski; 11 Jul 2021, 20:29.

    Comment


    • #3
      This is helpful, thank you. I see from your example that I don't even need to use st_local to pass a stata temporary scalar from mata to a stata command. My solution is below. The program add1 takes in a scalar, adds 1, and returns the result in r(result). In mata, the function test() takes in 2 as a scalar input, passes it to stata as a temporary scalar, and uses it in stata() to run add1. The result is 3 as expected.

      Code:
      cap program drop add1
      program define add1, rclass sortpreserve
          args x
          return scalar result = `x' + 1
      end
      Code:
      mata
      void test(input) {
              string scalar x
              x = st_tempname() 
              st_numscalar(x,input)
      
              stata(`"add1 "' + x)
              stata("di r(result)")
          }
          
          test(2)
      end
      Code:
      . mata
      ------------------------------------------------- mata (type end to exit) ----------------------------------
      : void test(input) {
      >                 string scalar x
      >                 x = st_tempname() 
      >                 st_numscalar(x,input)
      > 
      >                 stata(`"add1 "' + x)
      >                 stata("di r(result)")
      >                 stata("scalar list")
      >         }
      
      :         
      :         test(2)
      3
        __000000 =          2
      
      : end
      ------------------------------------------------------------------------------------------------------------

      Comment

      Working...
      X