16.0 SIMEQ Command The SIMEQ command supports OLS, 2SLS, LIML, 3SLS, I3SLT and FIML estimation of systems of equations. The constrained reduced form can optionally be calculated. The SIMEQ command uses very fast code developed by Jennings. If it is desired to estimate only a single OLS model, the B34S REGRESSION command provides more diagnostic tests. For a basic reference on the procedure see: - Jennings, Les. "Simultaneous Equations Estimation", Journal of Econometrics, Vol 12, # 1 Jan 1980, pp. 23-39. Form of SIMEQ command. B34SEXEC SIMEQ options parameters$ HEADING=(' Any heading desired') $ EXOGENOUS Xvar1 Xvar2 $ ENDOGENOUS Yvar1 Yvar2 $ MODEL LVAR=Yvar RVAR=(Xvar1 Xvar2 Yvar3) NAME=(' any name ') $ IDENTITY LVAR=YVAR RVAR=(Xvark Xvarj Yvarh) RVARCOEF=(real1 real2 ) NAME=('Any name for identity here') $ B34SEEND$ The EXOGENOUS, ENDOGENOUS and MODEL sentences are required. There can be more than one MODEL and IDENTITY sentences. The number of MODEL sentences plus IDENTITY sentences equals the number of variables listed in the ENDOGENOUS sentence. Note: While every effort has been made to test the output of SIMEQ, there remains some doubt whether the FIML SE's are too small by a scalar. In addition the FIML code is not a robust as desired. Hence the FIML option on the SIMEQ paragraph should be regarded as experimental. SIMEQ sentence options. PRINTSYS - Will print system of equations estimated. PRINTDATA - Will print the data and the system estimated. REDUCED - Will calculate reduced form equations for system. OLS - Will give OLS estimates. LIML - Will give LIML estimates. No SE is given since 2SLS SE is same asymptotically as LIML. Jennings view is that these SE's are more appropriate to use that attemting to get SE's from a nonlinear solution. LS2 - Will give 2SLS estimates. LS3 - Will give 3SLS estimates. ILS3 - Will give I3SLS estimates. ICOV - Will give covariance matrix for I3SLS estimates. Unless this is set, I3SLS will not have SE. On 1 April 2006 icov was made the default. NOICOV - Turns off printing of covariance matrix for 3SLS. If this is set, no SE for 3SLS will be given. NOKCOV - Turns off covariance matrix for I3SLS. FIML - Will give FIML estimates. FIMLC - Will give FIML covariance matrix. GTIME - Will time each estimation calculation. SIMEQ sentence parameters. KCOV = key If key = DIAG diagonal blocks of 3SLS covariance matrix printed. This is the default. If key = FULL the whole 3SLS covariance matrix will be printed. ITMAX = n1 Sets the maximum iterations for I3SLS and FIML. Default = 50. MAXIT can be used in place of ITMAX. IPR = n2 Set number of significant digits in data. Default=10. Set to a smaller number if fewer digits are supplied. Unless this is done, I3SLS may not converge. Note: The following space parameters are usually left to default values unless program will not run and user must reset values. The default values equally allocate available space among all work arrays. ZSING, ZDOUB and AARRAY are usually the largest internal work arrays. ZSING = n3 Sets space for internal array ZSING. ZDOUB = n4 Sets space for internal array ZDOUB. AARRAY = n5 Sets space for internal array A. YARRAY = n6 Sets space for internal array Y. CARRAY = n7 Sets space for internal array COV. SIGMA = n8 Sets space for internal array SIGMA. RES = n9 Sets space for internal array RES. INDEX = n10 Sets space for internal array INDEX. HEADING sentence. HEADING=('Any message here ' ) $ The HEADING sentence is optional. Up to 72 characters can be specified. Since the B34S Parser does not read beyond col 72 on any one card, continue HEADING sentence on nextline. EXOGENOUS sentence. EXOGENOUS Xvar1 Xvar2 Xvar3 $ The EXOGENOUS sentence is required. ENDOGENOUS sentence. ENDOGENOUS Yvar1 Yvar2 Yvar3 $ The ENDOGENOUS sentence is required. All variables mentioned on either the MODEL or IDENTITY sentences must be listed in either the ENDOGENOUS or EXOGENOUS sentences. MODEL sentence. MODEL LVAR=Yvar RVAR=(Xvar1 Xvar2 Yvar3) NAME=('Any name ') $ The MODEL sentence is required. The parameters LVAR and RVAR must be supplied. The NAME parameter is highly recommended. There can be more than one MODEL sentence. MODEL sentence parameters. LVAR = Yvar Sets the left hand variable. Yvar must have been listed in the ENDOGENOUS sentence. RVAR=(Xvar1 Yvar2 ) Sets the endogenous and exogenous variables on the right hand side of the equation. These variables must have been listed in either the EXOGENOUS or ENDOGENOUS sentences. NAME=('any text') Sets a name for the equation. Up to 40 characters can be supplied. IDENTITY sentence IDENTITY LVAR = Yvar RVAR=(Xvar1 Yvark) RVARCOEF=(real1 real2) NAME=('Up to 40 characters here') $ The IDENTITY sentence is not required. There can be more than one IDENTITY sentence. The number of MODEL plus IDENTITY sentences must equal the number of variables listed in the ENDOGENOUS sentence. IDENTITY sentence parameters. LVAR = Yvar Sets the left hand variable. Yvar must have been listed in the ENDOGENOUS sentence. RVAR=(Xvar1 xvar2 ) Sets the endogenous and exogenous variables on the right hand side of the equation. These variables must have been listed in either the EXOGENOUS or ENDOGENOUS sentences. NAME=('any text') Sets a name for the equation. Up to 40 characters can be supplied. RVARCOEF =(r1 r2 r3) Sets coefficients for identity. Uses G16.8. Default =1.0. Note: If the identity desired was Y = 100 + 40X1 - 50X2, then specify: IDENTITY LVAR=Y RVAR=(CONSTANT X1 X2) RVARCOEF=(100.0 40.0 -50.0) NAME=('Test identity') $ Note: it is important to specify -50. not - 50. . Sample problem from Kmenta (1971 page 565 - 582). b34sexec simeq printsys reduced ols liml ls2 ls3 $ heading=('test case from kmenta 1971 page 565 - 582 ') $ exogenous constant d f a $ endogenous p q $ model lvar=q rvar=(constant p d) name=('Demand Eq.') $ model lvar=q rvar=(constant p f a) name=('Supply Eq.') $ b34seend$ More extensive test case showing SAS, RATS and a MATRIX command implementation. This test case is in example.max /; A number of tests are run with SAS and RATS /; /; For 3slq B34S Agrees with Kmenta(1971) for demand and supply /; For Kementa (1986) the Supply equation differs slightly. /; SAS gets the Kmenta (1986) Demand and Supply. /; Rats gets the Kmenta Demand but its Supply is quite /; different RATS is getting what B34S calls I3SLS! /; B34S uses matrix command to validate its SIMEQ command /; %b34slet dosas=0; %b34slet dorats=0; %b34slet ratsliml=0; %b34slet domatrix=0; %b34slet verbose=0; /; set =1 to "test" matrix setup. Usually set=0 /$ PROBLEM FROM KMENTA (1971) PAGE 565 - 582 B34SEXEC DATA NOOB=20 HEADING=('KMENTA TEST DATA')$ COMMENT=(' TEST DATA FROM PAGE 565 ') $ INPUT Q P D F A $ DATACARDS $ 98.485 100.323 87.4 98.0 1 99.187 104.264 97.6 99.1 2 102.163 103.435 96.7 99.1 3 101.504 104.506 98.2 98.1 4 104.240 98.001 99.8 110.8 5 103.243 99.456 100.5 108.2 6 103.993 101.066 103.2 105.6 7 99.900 104.763 107.8 109.8 8 100.350 96.446 96.6 108.7 9 102.820 91.228 88.9 100.6 10 95.435 93.085 75.1 81.0 11 92.424 98.801 76.9 68.6 12 94.535 102.908 84.6 70.9 13 98.757 98.756 90.6 81.4 14 105.797 95.119 103.1 102.3 15 100.225 98.451 105.1 105.0 16 103.522 86.498 96.4 110.5 17 99.929 104.016 104.4 92.5 18 105.223 105.769 110.7 89.3 19 106.232 113.490 127.1 93.0 20 B34SRETURN $ B34SEEND$ B34SEXEC LIST $ VAR Q P D F A $ B34SEEND $ /$ /; Note: ipr set = 6 for # of significant digits. If 10 is set /; will get a convergence error with ils3 b34sexec simeq printsys reduced ols liml ls2 ls3 ils3 icov ipr=6 itmax=2000 kcov=diag $ heading=('test case from kmenta 1971 page 565 - 582 ' ) $ exogenous constant d f a $ endogenous p q $ model lvar=q rvar=(constant p d) name=('demand eq.') $ model lvar=q rvar=(constant p f a) name=('supply eq.') $ b34seend $ /; /; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /; /$ /$ Estimates Kmenta Problem with Matrix command. /$ Purpose is to illustrate OLS/2SLS/3SLS/FIML both with /$ SIMEQ and with Matrix Commands. /$ /$ FIML SE same as 3SLS asymptotically (See Greene 5e page 408) /$ /$ Problem Discussed in "Specifying and Diagnostically Testing /$ Econometric Models" Chapter 4 Third Edition /$ %b34sif(&domatrix.ne.0)%then; b34sexec matrix; call loaddata; verbose=0; %b34sif(&verbose.ne.0)%then; verbose=1; %b34sendif; x_1=mfam(catcol(constant p d)); x_2=mfam(catcol(constant p f a)); x_1px_1=transpose(x_1)*x_1; x_2px_2=transpose(x_2)*x_2; x_1py_1=transpose(x_1)*vfam(q); x_2py_2=transpose(x_2)*vfam(q); d1=inv(x_1px_1)*x_1py_1; d2=inv(x_2px_2)*x_2py_2; call print('OLS eq 1 ',d1 ); call print('OLS eq 2 ',d2 ); * 2SLS ; * z_i is right hand side of equation i ; x = mfam(catcol(constant d f a)); xpx = transpose(x)*x; z_1 = mfam(catcol(constant p d) ); z_2 = mfam(catcol(constant p f a)); xpz_1 = transpose(x)*z_1; xpz_2 = transpose(x)*z_2; xpy_1 = transpose(x)*vfam(q); xpy_2 = transpose(x)*vfam(q); y_1py_1 = vfam(q)*vfam(q); y_2py_2 = vfam(q)*vfam(q); y_1py_2 = vfam(q)*vfam(q); ls2eq1=inv(transpose(xpz_1)*inv(xpx)*xpz_1)* (transpose(xpz_1)*inv(xpx)*xpy_1); call print('Two stage estimates Equation 1',ls2eq1); fit1=vfam(q)-z_1*ls2eq1; sigma11=(y_1py_1 - (2.*vfam(q)*z_1*ls2eq1) + ls2eq1*transpose(z_1)*z_1*ls2eq1)/17.; if(verbose.ne.0)then; call print('sigma11 ',sigma11:); call print('Residual Variance 1',sigma11*sigma11:); call print('Test 1 ',(fit1*fit1)/ 17.:); call print('Large sample ',(fit1*fit1)/ 20.:); endif; varcoef1= sigma11*inv(transpose(z_1)*x*inv(xpx)*transpose(x)*z_1); call print('Asymptotoc Covariance Matrix eq 1 ',varcoef1); ls2eq2=inv(transpose(xpz_2)*inv(xpx)*xpz_2)* (transpose(xpz_2)*inv(xpx)*xpy_2); call print('Two stage estimates Equation 2',ls2eq2); fit2=vfam(q)-z_2*ls2eq2; sigma22=(y_2py_2 - (2.*vfam(q)*z_2*ls2eq2) + ls2eq2*transpose(z_2)*z_2*ls2eq2)/16.; if(verbose.ne.0)then; call print('sigma22 ',sigma22:); call print('Residual Variance 2',sigma22*sigma22:); call print('Test 2 ',(fit2*fit2)/ 16.:); call print('Large Sample ',(fit2*fit2)/ 20.:); endif; sigma12=(y_1py_2 - (vfam(q)*z_1*ls2eq1) - (vfam(q)*z_2*ls2eq2)+ ls2eq1*transpose(z_1)*z_2*ls2eq2)/20.; if(verbose.ne.0)call print('test sigma12 ',sigma12); varcoef2= sigma22*inv(transpose(z_2)*x*inv(xpx)*transpose(x)*z_2); call print('Asymptotic Covariance Matrix eq 2 ',varcoef2); * Get sigma(i,j) from fits ; s=mfam(catcol(fit1,fit2)); sigma=(transpose(s)*s)/20.; call print('Large Sample sigma (Jennings) ',sigma); covar1=sigma(1,1)*inv(transpose(xpz_1)*inv(xpx)*xpz_1); covar2=sigma(2,2)*inv(transpose(xpz_2)*inv(xpx)*xpz_2); call print('Estimated Covaiance Matrix - Large Sample':); call print(covar1,covar2); ls2se=dsqrt(array(:covar1(1,1),covar1(2,2),covar1(3,3) covar2(1,1),covar2(2,2),covar2(3,3) covar2(4,4))); call print('SE of LS2 Model Equations - Large Sample',ls2se); sssigma(1,1)=sigma(1,1)*(20./17.); sssigma(1,2)=sigma(1,2)*(20./dsqrt(17.*16.)); sssigma(2,1)=sigma(2,1)*(20./dsqrt(17.*16.)); sssigma(2,2)=sigma(2,2)*(20./16.); call print('Kmenta (Small Sample Sigma ',sssigma); covar1=sssigma(1,1)*inv(transpose(xpz_1)*inv(xpx)*xpz_1); covar2=sssigma(2,2)*inv(transpose(xpz_2)*inv(xpx)*xpz_2); call print('Estimated Covariance Matrix - Small Sample':); call print(covar1,covar2); ls2se=dsqrt(array(:covar1(1,1),covar1(2,2),covar1(3,3) covar2(1,1),covar2(2,2),covar2(3,3) covar2(4,4))); call print('SE of LS2 Model Equations - Small Sample',ls2se); * LS3 calculation ; xpxinv=inv(xpx); /$ sigma=inv(sssigma); sigma=inv(sigma); term11= sigma(1,1)*(transpose(xpz_1)*xpxinv*xpz_1); term12= sigma(1,2)*(transpose(xpz_1)*xpxinv*xpz_2); term21= sigma(2,1)*(transpose(xpz_2)*xpxinv*xpz_1); term22= sigma(2,2)*(transpose(xpz_2)*xpxinv*xpz_2); left1 =catcol(term11 term12); left2 =catcol(term21 term22); left =catrow(left1 left2); if(verbose.ne.0) call print(term11 term12 term21 term22 left1 left2 left); right1=(sigma(1,1)*(transpose(xpz_1)*xpxinv*xpy_1)) + (sigma(1,2)*(transpose(xpz_1)*xpxinv*xpy_2)); right2=(sigma(2,1)*(transpose(xpz_2)*xpxinv*xpy_1)) + (sigma(2,2)*(transpose(xpz_2)*xpxinv*xpy_2)); right=catrow(right1 right2); call print(right1 right2 right,inv(left)); ls3=inv(left)*right; call print('Three Stage Least Squares ',ls3); ls3se = dsqrt(diag(inv(left))); t3sls=array(norows(ls3):ls3(,1))/afam(ls3se); call print('Three Stage Least Squares SE',ls3se); call print('Three Stage Least Squares t ',t3sls); * FIML following Kmenta (1971) pages 578 - 581 ; * q = f(constant P D ) ; * q = g(constant p F A) ; * q = a1 + a2*p + a3*d + u1 ; * q = b1 + b2*p + b3*f + b4*a + u2; y = transpose(mfam(catcol(q p))); x = transpose(mfam(catcol(constant d f a))); gt= 2.* dfloat(norows(y)); t =dfloat(norows(y)); call print('Using 3sls starting values ',ls3); /$ a1=sfam(ls3(1)); /$ a2=sfam(ls3(2)); /$ a3=sfam(ls3(3)); /$ b1=sfam(ls3(4)); /$ b2=sfam(ls3(5)); /$ b3=sfam(ls3(6)); /$ b4=sfam(ls3(7)); program model; bigb = matrix(2,2: 1.0, -1.0*a2, 1.0, -1.0*b2); biggamma = matrix(2,4:-1.0*a1, -1.0*a3, 0.0, 0.0, -1.0*b1, 0.0, -1.0*b3, -1.0*b4); u1u2=bigb*y+biggamma*x; phi = u1u2*transpose(u1u2); /$ General purpose FIML setup if there are no identities /$ For a discussion of Formulas see Kmenta (1971) page 578-581 func=(-1.0*(gt*pi())/2.0) - ((t/2.0)*dlog(dmax1(dabs(det(phi)) ,.1d-30))) + ( t *dlog(dmax1(dabs(det(bigb)),.1d-30))) - (.5*sum(transpose(u1u2)*inv(phi)*u1u2)); call outstring(3, 3,'Function'); call outdouble(36,3,func); call outdouble(4, 4, a1); call outdouble(36,4, a2); call outdouble(55,4, a3); call outdouble(4 ,5, b1); call outdouble(36,5, b2); call outdouble(55,5, b3); call outdouble(4, 6, b4); return; end; call print(model); rvec =vector(7:ls3); ll =vector(7:) -1.d+2; uu =vector(7:) +1.d+3; call echooff; call cmaxf2(func :name model :parms a1 a2 a3 b1 b2 b3 b4 :ivalue rvec :lower ll :upper UU :maxit 10000 :maxfun 10000 :maxg 10000 :print); b34srun; %b34sendif; %b34sif(&dosas.eq.1)%then; B34SEXEC OPTIONS OPEN('testsas.sas') UNIT(29) DISP=UNKNOWN$ B34SRUN$ B34SEXEC OPTIONS CLEAN(29) $ B34SEEND$ B34SEXEC PGMCALL IDATA=29 ICNTRL=29$ SAS $ PGMCARDS$ proc means; run; proc syslin 3sls reduced; instruments d f a constant; endogenous p q; demand: model q = p d; supply: model q = p f a; run; proc syslin it3sls reduced; instruments d f a constant; endogenous p q; demand: model q = p d; supply: model q = p f a; run; B34SRETURN$ B34SRUN $ B34SEXEC OPTIONS CLOSE(29)$ B34SRUN$ /$ The next card has to be modified to point to SAS location /$ Be sure and wait until SAS gets done before B34S resumes B34SEXEC OPTIONS dodos('start /w /r sas testsas') dounix('sas testsas')$ B34SRUN$ B34SEXEC OPTIONS NPAGEOUT NOHEADER WRITEOUT(' ','Output from SAS',' ',' ') WRITELOG(' ','Output from SAS',' ',' ') COPYFOUT('testsas.lst') COPYFLOG('testsas.log') dodos('erase testsas.sas','erase testsas.lst', 'erase testsas.log') dounix('rm testsas.sas','rm testsas.lst', 'rm testsas.log')$ B34SRUN$ B34SEXEC OPTIONS HEADER$ B34SRUN$ %b34sendif; %b34sif(&dorats.ne.0)%then; b34sexec options open('rats.dat') unit(28) disp=unknown$ b34srun$ b34sexec options open('rats.in') unit(29) disp=unknown$ b34srun$ b34sexec options clean(28)$ b34srun$ b34sexec options clean(29)$ b34srun$ b34sexec pgmcall$ rats passasts pcomments('* ', '* Data passed from B34S(r) system to RATS', '* ', "display @1 %dateandtime() @33 ' Rats Ver: ' %ratsversion()" '* ') $ PGMCARDS$ * * heading=('test case from kmenta 1971 page 565 - 582 ' ) $ * exogenous constant d f a $ * endogenous p q $ * model lvar=q rvar=(constant p d) name=('demand eq.') $ * model lvar=q rvar=(constant p f a) name=('supply eq.') $ linreg q # constant p d linreg q # constant p f a instruments constant d f a linreg(inst) q # constant p d linreg(inst) q # constant p f a %b34sif(&ratsliml.ne.0)%then; source d:\r\liml.src @liml q # constant p d @liml q # constant p f a %b34sendif; equation demand q # constant p d equation supply q # constant p f a * Supply does not match known answers!! sur(inst,iterations=200) 2 # demand resid1 # supply resid2 nonlin(parmset=structural) c0 c1 c2 d0 d1 d2 d3 compute c0 = .1 compute c1 = .1 compute c2 = .1 compute d0 = .1 compute d1 = .1 compute d2 = .1 compute d3 = .1 frml d_eq q = c0 + c1*p + c2*d frml s_eq q = d0 + d1*p + d2*f + d3*a nlsystem(inst,parmset=structural,outsigma=v) * * d_eq s_eq b34sreturn$ b34srun $ b34sexec options close(28)$ b34srun$ b34sexec options close(29)$ b34srun$ b34sexec options /$ dodos(' rats386 rats.in rats.out ') dodos('start /w /r rats32s rats.in /run') dounix('rats rats.in rats.out')$ B34SRUN$ b34sexec options npageout WRITEOUT('Output from RATS',' ',' ') COPYFOUT('rats.out') dodos('ERASE rats.in','ERASE rats.out','ERASE rats.dat') dounix('rm rats.in','rm rats.out','rm rats.dat') $ B34SRUN$ %b34sendif;