Announcement

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

  • Variable scope problem

    I want to ask you about the scope of the variables in the Mata, because it seems that the Mata manual does not mention the content of the scope of the variables. Now I need to write a function that will change according to the value of the external variable. For example
    b=?;//b is a variable that will change with the previous calculation
    real scalar fun(x,y){
    z=x+b*y
    return(z)
    }

  • #2
    A couple of approaches come to mind: you can use a global variable
    Code:
    help m2_declarations##remarks10
    help mf_valofexternal
    help mf_findexternal
    or you can use class programming
    Code:
    help m2_class
    The former more closely resembles your example pseudo-code, and the latter might seem like more typing, but in more involved environments it strikes me as ultimately cleaner and less liable to unintended crosstalk (interference)—something like
    Code:
    class BScope {
        private:
            real scalar b
            void new()
        public:
            final void setB()
            final real scalar fun()
    }
    void function BScope::new() b = 0
    void function BScope::setB(real scalar b) this.b = b
    real scalar BScope::fun(real scalar x, real scalar y) return(x + b * y)
    Usage would be something like
    Code:
    version 17.0
    
    mata:
    mata set matastrict on
    
    bs = BScope()
    bs.setB(3)
    bs.fun(2, 3)
    
    end

    Comment


    • #3
      I mainly want to write a function that takes the values of some variables in Stata as parameters. The function solves a nonlinear equation internally and then returns the result of the solution. Some parameters of the solved nonlinear equation come from the parameters of the function. This function is expected to be called in a loop to calculate each sample, so the value of its parameter will change continuously with the loop. The test code I wrote is as follows. I'm a beginner, so the error is very serious. I don't know what the problem is.
      mata
      real scalar function yieldfun(real scalar tau,real scalar p,real scalar cpn,real scalar face,real scalar f,real scalar pay,real scalar term)
      {


      void nolinsolv(real scalar x,real scalar val,real scalar tau,real scalar p,real scalar cpn,real scalar face,real scalar term)
      {
      val=(p-(face+term*cpn)/((1+x)^tau))^2
      }
      real scalar capgain
      real scalar income
      real scalar xinit
      capgain = (100-p)/tau
      income = (100-p)/tau+cpn
      xinit = (income/p + income/(100-capgain))/2
      S = optimize_init()
      optimize_init_argument(S, 1,tau)
      optimize_init_argument(S, 2,p)
      optimize_init_argument(S, 3,cpn)
      optimize_init_argument(S, 4,face)
      optimize_init_argument(S, 5,term)
      optimize_init_evaluator(S, &nolinsolv())
      optimize_init_conv_nrtol(S, 1e-7)
      optimize_init_params(S, xinit)
      optimize_init_evaluatortype(S, "df0")
      bh = optimize(S)

      return(bh)
      }
      yield = real scalar yieldfun(5,98,0.06,100,2,1,10)
      end

      Comment


      • #4
        This is a code of Stata blog I found.It is used to calculate nonlinear least squares problem.https://blog.stata.com/2016/05/12/pr...es-estimators/. I don't know how the optimization command can identify which is a function parameter and which is a function variable.
        mata:
        void MYNLExp(real scalar todo, real vector b, ///
        real vector y, real matrix X, ///
        val, grad, hess)
        {
        real vector r, f, xb
        real matrix df

        xb = X*b'
        f = exp(X*b')
        r = y - f
        val = -(r:^2)
        df = f:*X

        if (todo>=1) {
        grad = r:*df
        }
        if (todo==2) {
        hess = -1*quadcross(df, df)
        }
        }
        y = st_data(., "accidents")
        X = st_data(., "cvalue tickets")
        n = rows(y)
        X = X, J(n, 1, 1)
        p = cols(X)
        S = optimize_init()
        optimize_init_argument(S, 1, y)
        optimize_init_argument(S, 2, X)
        optimize_init_evaluator(S, &MYNLExp())
        optimize_init_conv_nrtol(S, 1e-11)
        optimize_init_params(S, J(1, 3, .01))
        optimize_init_evaluatortype(S, "gf2")
        bh = optimize(S)
        M = invsym(-1*optimize_result_Hessian(S))
        sb = (-1/(n-p))*optimize_result_value(S)
        V = sb*M
        "Point estimates"
        bh
        "VCE"
        V
        end

        Comment


        • #5
          Originally posted by John Ling View Post
          The test code I wrote is as follows. I'm a beginner, so the error is very serious. I don't know what the problem is.
          A few problems are apparent by inspection.

          First, you're trying to define a function (nolinsolv()) within another (yieldfun()). Mata doesn't allow that. Define them separately.

          Second, "df0" is not a valid evaluator type for optimize(). I'm guessing that you want "d0", which is the default, anyway, and so you can omit that line of code.

          Third, optimize() is going to expect to be able to feed any evaluator function that it calls three more housekeeping arguments (a todo real scalar, a gradient vector and a Hessian matrix) than you've allowed for in your evaluator function's argument list.

          Fourth, you feed your outer function two arguments (f, and pay) that are never used anywhere. Even with fixing up the errors above, your test case gives an initial values not feasible error. So, you'll want to make sure that your computations are correct by manually executing your evaluator function directly with your test-case arguments and computed initial value. (You can use missing-value dummy arguments for the to-do, gradient and Hessian housekeeping arguments.)

          You'll probably also want to first become more familiar with the workings of optimize() by working through simpler examples, such as those in the help file (user's manual or Stata Press books referenced there).

          Comment


          • #6
            Thank you very much. I have solved the problem and tested a sample. I also want to ask a question, can mata execute the code part by part by clicking the do button like the do file of Stata, because I want to test the mata program I wrote step by step, or does mata have any debug mode?

            Comment

            Working...
            X