Announcement

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

  • Problem when calling mata function in stata

    Hi,

    I am trying to make the code below work. However, I haven't been able to call the function I created for Mata in Stata. When I run this code, I get the following error message (regarding the last block of code):
    centovintedias(): 3001 expected 1 arguments but received 0
    <istmt>: - function returned error

    In other words, I am trying to figure out how to call a mata function I wrote in stata. I don't know if the problem is the way I am calling f in the function or something else...

    I am using Stata 13/MP.

    Code:
    global VARALLL alll3_ret gasc3b_ret gasc4b_ret rlog3_ret vspt3_ret vspt4_ret
    global VARARCZ arcz3_ret fibr3_ret klbn3_ret klbn4_ret mlpa3_ret mspa3_ret mspa4_ret rpsa12_ret suzb11_ret suzb12_ret suzb3_ret suzb5_ret suzb6_ret
    global LISTAS "VARALL VARARCZ"
    
    mata
    function centovintedias(real scalar f)
    {
    A = J(131,1,.)
    h = 0
    for (i=1; i<=131; i++) {
        if (h==0) A[i,1] = aux[i + datas_base[f,1] - 125,1]
            if (aux[i,1]==.) h = 1    
        if (h==1) {
        st_numscalar("limite", h)
        st_local("limite", strofreal(h))
        return
        }
    }
    }
    end    
    
    *THE PROBLEM HAPPENS WHEN I RUN THIS PART
    putmata datas_base
    global f = 1
    foreach x of global LISTAS {
        local j = 1
        foreach var of global `x' {
            gen aux = `var'
            putmata aux
            mata centovintedias(`f')
            mata: mata drop aux
            if limite==1 {
                mata: mata drop A
            }
            if j==1 {
                getmata principal = A, force
            }
            Else {
                getmata final`j' = A, force
                if _rc==111{
                    local j = `j' + 1
                    continue
                }
            }
            local j = `j' + 1
        }
        global f = `f' + 1
    }
    I would be very pleased if you could help me! Thanks in advance!

  • #2
    You need a colon after the mata keyword (in this line: " mata centovintedias(`f')")

    Comment


    • #3
      Do you mean if I use the code shown below? In this case I still get the same error message...

      Code:
      putmata datas_base
      global f = 1
      foreach x of global LISTAS {
          global j = 1
          foreach var of global `x' {
              gen aux = `var'
              putmata aux
              mata: centovintedias(`f')
              mata: mata drop aux
              if limite==1 {
                  mata: mata drop A
              }
              if j==1 {
                  getmata principal = A, force
              }
              else {
                  getmata final`j' = A, force
                  if _rc==111{
                      global j = `j' + 1
                      continue
                  }
              }
              global j = `j' + 1
          }
          global f = `f' + 1
      }

      Comment


      • #4
        is it because you are calling a global macro f (and j) using local macro call syntax?

        have you tried replacing "global f" with "local f"?

        Comment


        • #5
          There is an L missing in VARALLL in the global LISTAS.
          Then as suggested by Salah use either local f instead of global f or write

          Code:
           mata: centovintedias($f)
          In general it is better to use locals rather than global unless you want to use these globals in other do-files.

          Comment


          • #6
            Thanks for your suggestions! Nevertheless, the problem persists... I was using locals before, but I substituted it for globals hoping to solve the problem. Anyway, I tested with locals again and, still, it didn't work. I have tried using
            Code:
            mata: centovintedias($f)
            and
            Code:
            mata: centovintedias(`f')
            defining f both as local and global and the iteration for f as
            Code:
            local f = `f' + 1
            local f = $f + 1
            global f = `f' + 1
            and
            global f = $f + 1
            Now my code has f and j defined as locals (thanks for this tip!), and I have corrected for the missing L in VARALLL, but it doesn't work. I would appreciate whether you have any further reccomendations.
            Thanks!

            Comment


            • #7
              The initial error code was

              Code:
              centovintedias(): 3001 expected 1 arguments but received 0
              It was because you had defined f as a global and refer to it as a local when passed to your mata function. The local f was not defined and as a consequence it was empty when evaluated by Stata and no argument was passed to centovindedias(). The definition of your function requires exactly one argument, hence the error.
              Your code should look something like the one below now and it should have solved this problem. What is the error message you get now?

              Aside: local ++j is a shorter way of writing local j = `j' + 1

              Code:
              putmata datas_base
              local f = 1
              foreach x of local LISTAS {
                  local j = 1
                  foreach var of local `x' {
                      gen aux = `var'
                      putmata aux
                      mata: centovintedias(`f')
                      mata: mata drop aux
                      if limite==1 {
                          mata: mata drop A
                      }
                      if j==1 {
                          getmata principal = A, force
                      }
                      else {
                          getmata final`j' = A, force
                          if _rc==111 {
                              local ++j
                              continue
                          }
                      }
                      local ++j
                  }
                  local ++f
              }

              Comment


              • #8
                Actually I found out that after making the modifications you suggested my code still didn't work, because the function needed more arguments! I was getting a new kind of error, 3301 if I am not mistaken exactly because my function hadn't enough arguments. Actually, I had to modify to something like this:
                Code:
                 
                 mata function centovintedias(scalar f, matrix aux, matrix datas_base, scalar h, matrix A) // otherwise it wouldn't work { A = J(131,1,.) h = 0 for (i=1; i<=131; i++) {     if (h==0) A[i,1] = aux[i + datas_base[f,1] - 125,1]         if (aux[i,1]==.) h = 1         if (h==1) {     st_numscalar("limite", h)     st_local("limite", strofreal(h))     return     } } } end
                Thanks a lot for your help!

                Comment

                Working...
                X