Announcement

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

  • How to create a program to perform NLS estimation to a complex function

    Dear Stata users, I am a beginner in Stata software


    I need to use NLS to estimate the following equation describing the so-called Bass diffusion model:

    yt = m * [ ((1 - exp (-(p+q) * t)) / (1 + q/p * exp (-(p+q) * t))) - ((1 - exp (-(p+q) * (t-1))) / (1 + q/p * exp (-(p+q) * (t-1)))) ] + ut

    where m,p, and q are parameters and t indicates time. As initial values for these parameters, I am to use those obtained with OLS applied to:

    yt = β0 + β1 x1, t-1 + β2 x2, t-1 + ϵt

    where β0 = m * p
    β1 = q - p
    β2= - q/m

    Note that m = 41302528
    p = 0.024
    q = 0.194


    To perform this NLS estimation, I tried to follow the example that was given in the Stata forum (https://www.stata.com/features/overv...ar-regression/) in order to create a program that defines my function.Then, I used the nl command and specified the initial values.

    When I run the command, I get the following message:

    verify that nlces is a function evaluator program
    r(198);

    Would you please help me figure out what the problem is?
    Thanks in advance.
    Last edited by Melissa Moular; 29 Nov 2020, 14:48.

  • #2
    Your question really isn't clear without more detail, or at a minimum it is too difficult to guess at a good answer from what you have shared. Please help us help you. Show your code. Subtle errors in your understanding of the example code you followed could be the source of your problem. How are we to comment on the code you have not shown us?

    To assure maximum readability of code that you post, please copy it from the Do-file Editor window and paste it into a code block in the Forum editor using code delimiters [CODE] and [/CODE], as explained in section 12 of the Statalist FAQ linked to at the top of the page.

    Comment


    • #3
      Thank you William Lisowski

      This is the code used for the nl program:

      Code:
      program nlbass
       
              version 14
              y t (min=2 max=2)
       
              local y: word 1 of `y t'
              local t: word 2 of `y t'
       
              tempname m p q
       
              scalar `m' = `at'[1,1]
              scalar `p' = `at'[1,2]
              scalar `q' = `at'[1,3]
       
              tempvar expterm explterm
       
              generate double `expterm' = exp(-1*(`p'+`q')*`t')
              generate double `explterm' = exp(-1*(`p'+`q')*(`t'-1))
       
              replace `y' = `m'*(((1-`expterm')/(1+`q'/`p'*`expterm'))-((1-`explterm')/(1+`q'/`p'*`explterm')))
      end


      I typed nl command and specified the initial values as follow:

      Code:
      nl bass @ y t, parameters(m p q) initial(m 41302528 p 0.024 q 0.194)
      When I run the command, I get the following message:

      Code:
      nlbass returned 199
      verify that nlbass is a function evaluator program
      r(199);
      Last edited by Melissa Moular; 03 Dec 2020, 04:16.

      Comment


      • #4
        The example code you followed assumed that the reader has the basic knowledge of writing Stata "programs" that would be obtained by reading Chapter 18 "Programming Stata" of the Stata User's Guide PDF, which is included in your Stata installation and accessible from Stata's Help menu.

        The code below corrects your code to better conform to the example, with the changes to your code highlighted in red.
        Code:
        program nlbass
         
                version 14
                syntax varlist(min=2 max=2) [aw fw iw] if, at(name)
                local y: word 1 of `varlist'
                local t: word 2 of `varlist'
        
                tempname m p q
         
                scalar `m' = `at'[1,1]
                scalar `p' = `at'[1,2]
                scalar `q' = `at'[1,3]
         
                tempvar expterm explterm
         
                generate double `expterm' = exp(-1*(`p'+`q')*`t')
                generate double `explterm' = exp(-1*(`p'+`q')*(`t'-1))
        
                replace `y' = `m'*(((1-`expterm')/(1+`q'/`p'*`expterm'))-((1-`explterm')/(1+`q'/`p'*`explterm')))
        end
        I test it on invented data and it no longer gets an error message.
        Code:
        . nl bass @ y t, parameters(m p q) initial(m 41302528 p 0.024 q 0.194)
        (obs = 100)
        [remaining output omitted]

        Comment


        • #5
          William Lisowski Thank you for this answer. The code works.

          Comment


          • #6
            On further reflection, my response in post #4 was focused on providing a correct syntax command in the function evaluator program nlbass, but this was only part of the problem with the code in post #3.

            Anyone writing a function evaluator program should start with the full documentation for the nl command in the Stata Base Reference Manual PDF included in your Stata installation and accessible through Stata's Help menu. In there you will find a section on writing function evaluator programs that you should read and understand, having first read and understood the documentation on writing Stata programs more generally that I referred to in post #4.

            I now see two problems with the nlbass code I gave in post #4.

            The syntax command includes weights [aw fw iw] and an if clause. If either of these is passed to the nlbass program, the program will quietly ignore them, which is not good programming.

            For the nlbass program the weights are not a problem, because the generate and replace commands do not accept weights.

            Ignoring the if clause is probably not a good idea. Instead, the nlbass program in post #4 should incorporate it following the examples in the nl documentation and in the Stata overview linked to from post #1. The differences in the code below from the code in post #3 are again highlighted in red - in post #4 I mistakenly highlighted the three scalar commands, which in fact were unchanged.
            Code:
            program nlbass
             
                    version 14
                    syntax varlist(min=2 max=2) [aw fw iw] if, at(name)
                   
                    local y: word 1 of `varlist'
                    local t: word 2 of `varlist'
            
                    tempname m p q
             
                    scalar `m' = `at'[1,1]
                    scalar `p' = `at'[1,2]
                    scalar `q' = `at'[1,3]
             
                    tempvar expterm explterm
             
                    generate double `expterm' = exp(-1*(`p'+`q')*`t') `if'
                    generate double `explterm' = exp(-1*(`p'+`q')*(`t'-1)) `if'
            
                    replace `y' = `m'*(((1-`expterm')/(1+`q'/`p'*`expterm'))-((1-`explterm')/(1+`q'/`p'*`explterm'))) `if'
            end

            Comment

            Working...
            X