Stata’s nl fits an arbitrary function by least squares. That is, given
y_{j} = f(x_{j}, b) + u_{j}
nl finds b to minimize Σ_{j} (u_{j}^{2}). (nl can also obtain weighted least squares estimates.) You need only supply the function f(); you do not need to supply the derivatives.
nl provides three ways to define the function. Most commonly, you simply type the function directly on the command line or in the dialog box. nl also offers a way to package a function that you use frequently so that you do not have to reenter it each time. A third way allows you to define arbitrarily complex functions that can take any number of lines in a program file.
To fit the negative exponential-growth model
y_{j} = b_{0} * (1 − exp(−b_{1}*x_{j})) + u_{j}
you type
. nl (y = {b0=1}*(1 - exp(-1*{b1=0.1}*x))) (obs = 20) Iteration 0: residual SS = .0026064 Iteration 1: residual SS = .0005769 Iteration 2: residual SS = .0005768 Iteration 3: residual SS = .0005768
Source | SS df MS | ||
Number of obs = 20 | |||
Model | 17.6717234 2 8.83586172 | R-squared = 1.0000 | |
Residual | .00057681 18 .000032045 | Adj R-squared = 1.0000 | |
Root MSE = .0056608 | |||
Total | 17.6723003 20 .883615013 | Res. dev. = -152.317 |
y | Coef. Std. Err. t P>|t| [95% Conf. Interval] | |
/b0 | .9961886 .0016138 617.29 0.000 .9927981 .9995791 | |
/b1 | .0419539 .0003982 105.35 0.000 .0411172 .0427905 | |
(The dataset for this example was obtained from SAS [1985, 588].) Notice that we put the parameter names in braces, and to initialize them we simply included an equal sign and our initial values.
Many models are frequently used, so typing in the formula each time can become tedious. nl has several models built-in, and you can write your own programs for other models. For example, say you want to fit the exponential model
y_{j} = b_{0} + b_{1}*b_{2}^{xj} + u_{j}
You would simply type
. nl exp3 : y x
because this three-parameter exponential function is built into nl. If that function were not included with nl, you could create the following program:
program nlexp3ex, rclass version 16 syntax varlist(min=2 max=2) if local y : word 1 of `varlist' local x : word 2 of `varlist' return local eq "`y' = {b0} + {b1}*{b2}^`x'" return local title "My exponential function" end
We named our program nlexp3ex because nl defines the program nlexp3 for its version of the three-parameter exponential model. After saving the program, you could fit it to your data by typing
. nl exp3ex : y x
To specify initial values as well, you would type
. nl exp3ex : y x, initial(b0 1 b1 0.9 b2 0.9)
Some functions are more complex, and writing them in one line of code is either impossible or at least error-prone. In those cases, a third method of defining your function is best. The constant elasticity of substitution production function is
ln Q_{j} = b_{0} − (1/ρ)*ln{δ*K_{j}^{−ρ} + (1−δ)*L_{j}^{−ρ}}
where Q_{j} is the jth firm's output and K_{j} and L_{j} are the amounts of capital and labor the firm uses. b_{0}, ρ, and δ are the parameters to estimate.
First, you write a program that calculates the function:
program nlces version 16 syntax varlist(min=3 max=3) [aw fw iw] if, at(name) local logout: word 1 of `varlist' local capital: word 2 of `varlist' local labor: word 3 of `varlist' // Retrieve parameters out of at tempname b0 rho delta scalar `b0' = `at'[1,1] scalar `rho' = `at'[1,2] scalar `delta' = `at'[1,3] // Some temporary variables tempvar kterm lterm generate double `kterm' = `delta'*`capital'^(-1*`rho') `if' generate double `lterm' = (1-`delta')*`labor'^(-1*`rho') `if' // Now fill in dependent variable replace `logout' = `b0' - 1/`rho'*ln(`kterm'+`lterm') `if' end
Then you call nl like this, specifying initial values for some or all of the parameters:
. nl ces @ logout capital labor, parameters(b0 rho delta) /// initial(rho 1 delta 0.5)
nl is notable because it was written in Stata’s programming language. Stata is fully programmable; even if we had not written the nl command for you, with (admittedly considerable) work, you could have written it yourself. In fact, the first versions of nl were written by users; see Danuso (1991) and Royston (1992, 1993). It was officially adopted by StataCorp (meaning it became supported) in September 1992.