Announcement

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

  • Problem with passing macros from stata to mata and vica versa

    Hi everyone!

    I have Problems with writing an ado file that gets as Input the following 6 local macros defined in stata (`q',`gg',`a2',`a3',`zeta',`delta'), does some very simple matrix calculations and passes back the result to Stata in the local macro called: `size_avg_estab_mata'.


    The error message I get:

    1 invalid name
    r(198);

    What is the correct way of passing on macros to the program and then the result back to stata?

    In my stata file I do this:


    local q = 1
    local gg = 2
    local a2 = 3
    local a3 = 4
    local zeta = 5
    local delta= 6

    matsum(`q',`gg',`a2',`a3',`zeta',`delta')


    And my matsum.ado file Looks like this:

    program matsum
    set trace on
    version 12
    syntax varname [if] [in]
    marksample touse
    mata: calcsum("`varlist'", "`touse'")
    display as txt " factor = " as res r(sum)
    end

    version 12
    mata:
    mata set matastrict on
    void calcsum(string scalar varname, string scalar touse)
    {
    real colvector x
    real matrix z
    real scalar size_avg_estab


    q_m = st_local(q)
    gg_m = st_local(gg)
    a2_m = st_local(a2)
    a3_m = st_local(a3)
    zeta_m = st_local(zeta)
    delta_m = st_local(delta)

    for (s=1; s<=`q_m'; s++) {

    z[`s'+1,2] = ((`gg_m'^`s')/(1+`a2_m'*(`a3_m'^`s')))^`zeta_m'

    z[`s'+1,1] = `delta_m'*(1-`delta_m')^`s'
    }

    x = z[.,1] :* z[.,2]

    size_avg_estab_mata = colsum(x)/colsum(z[.,1])

    st_numscalar("r(sum)",size_avg_estab_mata)
    }
    end


    Thanks for any help,
    Eniko




  • #2
    Hi Eniko
    There is a lot of errors in your code.

    I can't figure out what you are trying to do, but I've attached some code based on guessing.
    This is not how I would do it, it is just how I could make it work.

    Code:
    cls
    capture program drop matsum
    program matsum
        args q gg a2 a3 zeta delta
        mata: st_numscalar("out", calcsum(`q',`gg',`a2',`a3',`zeta',`delta'))
        display as txt " factor = " as res out
    end
    
    capture mata mata drop calcsum()
    mata:
        mata set matastrict on
        real scalar calcsum(real scalar q_m, gg_m, a2_m, a3_m, zeta_m, delta_m)
        {
            real colvector x
            real matrix z
            real scalar size_avg_estab_mata, s
            
            z = J(q_m, 2, .)
            for(s=1; s<=q_m; s++){
                z[s, 2] = ((gg_m^s)/(1+a2_m*(a3_m^s)))^zeta_m
                z[s, 1] = delta_m*(1-delta_m)^s
            }
            x = z[.,1] :* z[.,2]
            size_avg_estab_mata = colsum(x) / colsum(z[.,1])
    
            return(size_avg_estab_mata)
        }
    end
    
    
    matsum 6 2 3 4 5 6
    Maybe by comparing the code blocks you'll get an idea of what should be done.

    Btw: The 2 capture lines should be deleted in the ado file
    Last edited by Niels Henrik Bruun; 19 Oct 2015, 05:18.
    Kind regards

    nhb

    Comment


    • #3
      Hi Niels,

      this is very helpful and very close to what I would like the program to do, thank you very much.

      I am new to writing such programs, therefore, could you please tell me, how should I modify your code to use the result stored in size_avg_estab_mata from within another program?

      To be more precise, the above code only writes out the value stored in size_avg_estab_mata, but I would like to use this value for further calculations in another program, nlmyreg, which will estimate a non-linear Regression (I also attached a sample file that is used by nlmyreg).

      Like this:



      program nlmyreg
      version 12
      syntax varlist (min=2) if, at(name)
      local rel_estab_size_c_interp: word 1 of `varlist'
      local ageq: word 2 of `varlist'
      // Retrieve parameters
      tempname gg a2 a3 q delta zeta
      tempvar size_avg_estab
      scalar `gg' = `at'[1,1]
      scalar `a2' = `at'[1,2]
      scalar `a3' = `at'[1,3]
      scalar `q' = `at'[1,4]
      scalar `delta' = `at'[1,5]
      scalar `zeta' = `at'[1,6]
      // Now fill in dependent variable
      replace `rel_estab_size_c_interp' = (((`gg'^`ageq')/(1+`a2'*`a3'^`ageq'))^`zeta')/`size_avg_estab_mata' `if'

      end


      nl myreg @ rel_estab_size_c_interp ageq, parameters(gg a2 a3 q delta zeta) initial(gg 1.0008873 a2 0.5 a3 0.3 q 20 delta 0.018 zeta 2.8)







      Kind regards,
      Eniko

      Attached Files

      Comment


      • #4
        You can use code blocks to make your code more readable on this forum (with indentation and monospacing). Start a block with a line containing just [code] and end the block with another line containing just [//code] (with one slash instead of two). You can also click the "Quote" button at the bottom write of anyone's post to see how they use this markup.

        Anyway, after having a look at help return, this seems to work:

        Code:
        capture program drop matsum
        program matsum, rclass
            args q gg a2 a3 zeta delta
            mata: st_numscalar("out", calcsum(`q',`gg',`a2',`a3',`zeta',`delta'))
            display as txt " factor = " as res out
            return scalar out = out
        end
        
        matsum 6 2 3 4 5 6
        
        return list
        ** see your result is in `r(out)'
        You can save the result somewhere else with local mysum = r(out) to use later.
        Last edited by Frank Erickson; 19 Oct 2015, 11:20.

        Comment


        • #5
          Hi Frank,

          Yes, I should have written my post that way. Thank you for making that Point and also for your suggestions, the code runs now. that is great, Thank you.

          Eniko

          Comment

          Working...
          X