@@ -874,6 +874,29 @@ def system_equations(nobs, endogenous=False):
874874 }
875875
876876
877+ def gmm_equations (nobs ):
878+ """
879+ Two equations, each with one endogenous regressor and one instrument
880+
881+ IVSystemGMM inverts the covariance of the moment conditions, in the robust and
882+ the kernel weights. The equations of system_equations(nobs, True) are exactly
883+ identified, so that their 4 moment conditions sum to zero at the estimates and have
884+ rank nobs - 1 or less: their covariance is singular with 4 or fewer observations,
885+ and inverting it only works up to rounding (it raised "Singular matrix" on FreeBSD,
886+ #853). These equations have no constant and 2 moment conditions, whose covariance
887+ has full rank from 3 observations.
888+ """
889+ first , second = iv_data (nobs , seed = 11 ), iv_data (nobs , seed = 111 )
890+ return {
891+ f"eq{ i } " : {
892+ "dependent" : data .y ,
893+ "endog" : data [["xn" ]],
894+ "instruments" : data [["z1" ]],
895+ }
896+ for i , data in enumerate ((first , second ))
897+ }
898+
899+
877900@pytest .mark .parametrize ("kernel" , CANONICAL )
878901@pytest .mark .parametrize (("model" , "endogenous" ), [(SUR , False ), (IV3SLS , True )])
879902def test_system_models_raise_when_fit_with_too_few_observations (
@@ -914,7 +937,7 @@ def test_system_models_explicit_bandwidth_works_with_the_observations_that_raise
914937def test_system_gmm_weights_raise_when_fit_with_too_few_observations (kernel ):
915938 nobs = fewest_observations (kernel ) - 1
916939 mod = IVSystemGMM (
917- system_equations (nobs , True ),
940+ gmm_equations (nobs ),
918941 weight_type = "kernel" ,
919942 kernel = kernel ,
920943 optimal_bw = True ,
@@ -923,20 +946,24 @@ def test_system_gmm_weights_raise_when_fit_with_too_few_observations(kernel):
923946 mod .fit ()
924947
925948
926- # The robust weights of the two equations need 4 observations before the covariance
927- # gets to the bandwidth: the Bartlett kernel is reached with 4
928- SYSTEM_GMM_COVARIANCE_FEW = [("parzen" , 4 ), ("qs" , 4 ), ("qs" , 5 )]
949+ # Every number of observations from 3, where the robust weights of gmm_equations can
950+ # be estimated, to one less than the kernel needs
951+ SYSTEM_GMM_COVARIANCE_FEW = [
952+ (kernel , nobs )
953+ for kernel in CANONICAL
954+ for nobs in range (3 , fewest_observations (kernel ))
955+ ]
929956
930957
931958@pytest .mark .parametrize (("kernel" , "nobs" ), SYSTEM_GMM_COVARIANCE_FEW )
932959def test_system_gmm_covariance_raises_when_fit_with_too_few_observations (kernel , nobs ):
933- mod = IVSystemGMM (system_equations (nobs , True ))
960+ mod = IVSystemGMM (gmm_equations (nobs ))
934961 with pytest .raises (ValueError , match = re .escape (too_few_message (kernel , nobs ))):
935962 mod .fit (cov_type = "kernel" , kernel = kernel )
936963
937964
938965def test_system_gmm_default_bandwidth_raises_when_fit_with_too_few_observations ():
939- mod = IVSystemGMM (system_equations ( 3 , True ), weight_type = "kernel" )
966+ mod = IVSystemGMM (gmm_equations ( 3 ), weight_type = "kernel" )
940967 with pytest .warns (DefaultBandwidthWarning ):
941968 with pytest .raises (ValueError , match = re .escape (too_few_message ("bartlett" , 3 ))):
942969 mod .fit ()
@@ -945,7 +972,7 @@ def test_system_gmm_default_bandwidth_raises_when_fit_with_too_few_observations(
945972@pytest .mark .parametrize ("kernel" , CANONICAL )
946973def test_system_gmm_explicit_bandwidth_works_with_the_observations_that_raise (kernel ):
947974 nobs = fewest_observations (kernel ) - 1
948- equations = system_equations (nobs , True )
975+ equations = gmm_equations (nobs )
949976 explicit = IVSystemGMM (
950977 equations , weight_type = "kernel" , kernel = kernel , bandwidth = 1
951978 ).fit ()
@@ -959,7 +986,7 @@ def test_system_gmm_explicit_bandwidth_works_with_the_observations_that_raise(ke
959986@pytest .mark .parametrize ("kernel" , CANONICAL )
960987def test_system_gmm_with_the_fewest_observations (kernel ):
961988 nobs = fewest_observations (kernel )
962- equations = system_equations (nobs , True )
989+ equations = gmm_equations (nobs )
963990 res = IVSystemGMM (
964991 equations , weight_type = "kernel" , kernel = kernel , optimal_bw = True
965992 ).fit (cov_type = "kernel" , kernel = kernel )
0 commit comments