Iterated least squares

A second form of loop structure is designed primarily for carrying out iterated least squares. Greene (2000, ch. 11) shows how this method can be used to estimate nonlinear models.

To open this sort of loop you need to specify a condition rather than an unconditional number of times to iterate. This should take the form of the keyword while followed by an inequality: the left-hand term should be the name of a variable that is already defined; the right-hand side may be either a numerical constant or the name of another predefined variable. For example,

loop while essdiff > .00001

Execution of the commands within the loop (i.e. until endloop is encountered) will continue so long as the specified condition evaluates as true.

I assume that if you specify a "number of times" loop you are probably doing a Monte Carlo analysis, and hence you're not interested in the results from each individual iteration but rather the moments of certain variables over the ensemble of iterations. On the other hand, if you specify a "while" loop you're probably doing something like iterated least squares, and so you'd like to see the final result — as well, perhaps, as the value of some variable(s) (e.g. the error sum of squares from a regression) from each time round the loop. The behavior of the print and ols commands are tailored to this assumption. In a "while" loop print behaves as usual; thus you get a printout of the specified variable(s) from each iteration. The ols command prints out the results from the final estimation.

Example 9-2 uses a "while" loop to replicate the estimation of a nonlinear consumption function of the form as presented in Greene (2000, Example 11.3). This script is included in the gretl distribution under the name greene11_3.inp; you can find it in gretl under the menu item "File, Open command file, practice file, Greene...".

Example 9-2. Nonlinear consumption function


	open greene11_3.gdt 
	# run initial OLS
	ols C 0 Y 
	genr essbak = $ess 
	genr essdiff = 1
	genr b0 = coeff(Y) 
	genr gamma0 = 1 
	# form the linearized variables 
	genr C0 = C + gamma0 * b0 * Y^gamma0 * log(Y) 
	genr x1 = Y^gamma0 
	genr x2 = b0 * Y^gamma0 * log(Y) 
	# iterate OLS till the error sum of squares converges 
	loop while essdiff > .00001 
	   ols C0 0 x1 x2 -o 
	   genr b0 = coeff(x1) 
	   genr gamma0 = coeff(x2) 
	   genr C0 = C + gamma0 * b0 * Y^gamma0 * log(Y) 
	   genr x1 = Y^gamma0 genr x2 = b0 * Y^gamma0 * log(Y) 
	   genr ess = $ess genr
	   essdiff = abs(ess - essbak)/essbak 
	   genr essbak = ess 
	endloop 
	# print parameter estimates using their "proper names"
	noecho
	printf "alpha = %g\n", coeff(0)
	printf "beta  = %g\n", coeff(x1)
	printf "gamma = %g\n", coeff(x2)

Example 9-3 (kindly contributed by Riccardo "Jack" Lucchetti of Ancona University) shows how a loop can be used to estimate an ARMA model, exploiting the "outer product of the gradient" (OPG) regression discussed by Davidson and MacKinnon in their Estimation and Inference in Econometrics.

Example 9-3. ARMA 1, 1


	open arma.gdt

	genr c = 0
	genr a = 0.1
	genr m = 0.1

	genr e = const * 0.0
	genr de_c = e
	genr de_a = e
	genr de_m = e

	genr crit = 1
	loop while crit > 1.0e-9

	   # one-step forecast errors
	   genr e = y - c - a*y(-1) - m*e(-1)  

	   # log-likelihood 
	   genr loglik = -0.5 * sum(e^2)
	   print loglik

	   # partials of forecast errors wrt c, a, and m
	   genr de_c = -1 - m * de_c(-1) 
	   genr de_a = -y(-1) -m * de_a(-1)
	   genr de_m = -e(-1) -m * de_m(-1)
   
	   # partials of l wrt c, a and m
	   genr sc_c = -de_c * e
	   genr sc_a = -de_a * e
	   genr sc_m = -de_m * e
   
	   # OPG regression
	   ols const sc_c sc_a sc_m

	   # Update the parameters
	   genr dc = coeff(sc_c) 
	   genr c = c + dc
	   genr da = coeff(sc_a) 
	   genr a = a + da
	   genr dm = coeff(sc_m) 
	   genr m = m + dm

	   printf "  constant        = %.8g (gradient = %#.6g)\n", c, dc
	   printf "  ar1 coefficient = %.8g (gradient = %#.6g)\n", a, da
	   printf "  ma1 coefficient = %.8g (gradient = %#.6g)\n", m, dm

	   genr crit = $T - $ess
	   print crit
	endloop

	genr se_c = stderr(sc_c)
	genr se_a = stderr(sc_a)
	genr se_m = stderr(sc_m)

	noecho
	print "
	printf "constant = %.8g (se = %#.6g, t = %.4f)\n", c, se_c, c/se_c
	printf "ar1 term = %.8g (se = %#.6g, t = %.4f)\n", a, se_a, a/se_a
	printf "ma1 term = %.8g (se = %#.6g, t = %.4f)\n", m, se_m, m/se_m