systemgmmkit 0.5.4__tar.gz → 0.5.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. {systemgmmkit-0.5.4/src/systemgmmkit.egg-info → systemgmmkit-0.5.6}/PKG-INFO +19 -24
  2. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/README.md +18 -23
  3. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/pyproject.toml +1 -1
  4. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/estimators/first_difference.py +3 -6
  5. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/native_gmm.py +35 -4
  6. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6/src/systemgmmkit.egg-info}/PKG-INFO +19 -24
  7. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_xtabond2_system_gmm_parity.py +0 -8
  8. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/LICENSE +0 -0
  9. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/setup.cfg +0 -0
  10. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/__init__.py +0 -0
  11. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/cli.py +0 -0
  12. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/diagnostics/__init__.py +0 -0
  13. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/diagnostics/gmm.py +0 -0
  14. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/diagnostics/panel.py +0 -0
  15. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/diagnostics.py +0 -0
  16. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/dynamic_panel.py +0 -0
  17. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/fixed_effects.py +0 -0
  18. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/gmm_parity_policy.py +0 -0
  19. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/panel_iv.py +0 -0
  20. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/parity.py +0 -0
  21. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/presets.py +0 -0
  22. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/pydynpd_backend.py +0 -0
  23. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/pydynpd_output_parser.py +0 -0
  24. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/random_effects.py +0 -0
  25. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/reporting/__init__.py +0 -0
  26. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/reporting/parity.py +0 -0
  27. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/reporting.py +0 -0
  28. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/spec.py +0 -0
  29. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/suite.py +0 -0
  30. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/tables.py +0 -0
  31. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit/validation.py +0 -0
  32. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit.egg-info/SOURCES.txt +0 -0
  33. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit.egg-info/dependency_links.txt +0 -0
  34. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit.egg-info/entry_points.txt +0 -0
  35. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit.egg-info/requires.txt +0 -0
  36. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/src/systemgmmkit.egg-info/top_level.txt +0 -0
  37. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_apply_gmm_parity_policy_script.py +0 -0
  38. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_first_difference_reporting.py +0 -0
  39. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_fixed_effects.py +0 -0
  40. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_generic_presets.py +0 -0
  41. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_gmm_parity_policy.py +0 -0
  42. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_parity_native_gmm.py +0 -0
  43. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_pydynpd_backend.py +0 -0
  44. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_pydynpd_output_parser.py +0 -0
  45. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_random_effects_iv_tables.py +0 -0
  46. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_spec_command.py +0 -0
  47. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_validation_diagnostics.py +0 -0
  48. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_xtabond2_system_gmm_decomposition_controls_certification.py +0 -0
  49. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_xtabond2_system_gmm_decomposition_controls_scaffold.py +0 -0
  50. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_xtabond2_system_gmm_no_controls_certification.py +0 -0
  51. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_xtabond2_system_gmm_no_controls_scaffold.py +0 -0
  52. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_xtabond2_system_gmm_three_way_controls_certification.py +0 -0
  53. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_xtabond2_system_gmm_three_way_controls_scaffold.py +0 -0
  54. {systemgmmkit-0.5.4 → systemgmmkit-0.5.6}/tests/test_xtabond2_system_gmm_uncorrected_se_baseline.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: systemgmmkit
3
- Version: 0.5.4
3
+ Version: 0.5.6
4
4
  Summary: Generic panel-data econometrics workflow helpers for FE, RE, IV/2SLS, and Difference/System GMM in Python.
5
5
  Author: Oluwajuwon Mayomi Akanbi
6
6
  License-Expression: MIT
@@ -780,30 +780,25 @@ For dynamic-panel GMM, users should record at minimum:
780
780
 
781
781
  ## Validation roadmap
782
782
 
783
- Before claiming broader production certification across panel designs, the package should continue to be tested on:
783
+ ## Validation roadmap
784
784
 
785
- * balanced panels;
786
- * unbalanced panels;
787
- * short-`T` panels;
788
- * longer-`T` panels;
789
- * high-`N`, low-`T` panels;
790
- * panels with missing observations;
791
- * different lag windows;
792
- * models with no controls;
793
- * models with many controls;
794
- * interaction-heavy specifications;
795
- * decomposition specifications;
796
- * alternative instrument classifications;
797
- * Stata `xtabond2` replication benchmarks.
798
-
799
- High-priority remaining validation items:
800
-
801
- * broader System GMM parity across additional empirical specifications;
802
- * broader Windmeijer-corrected standard-error parity across additional empirical specifications;
803
- * broader robustness of Sargan, Hansen, and AR diagnostics across additional panel structures;
804
- * documentation of exact Stata-compatible options and known non-equivalence cases.
805
-
806
- This roadmap protects the package from overclaiming and supports academically defensible validation.
785
+ The current validation suite establishes benchmark-specific certification for the maintained native Difference GMM and native System GMM paths.
786
+
787
+ Native System GMM is certified against Stata `xtabond2` for the maintained collapsed two-step benchmark suite, including the baseline, no-controls, three-way interaction, and decomposition specifications. Certified quantities include sample size, group count, instrument count, coefficient estimates, Hansen diagnostics, Windmeijer-corrected two-step standard errors, and signed Arellano-Bond AR(1)/AR(2) diagnostics with p-values.
788
+
789
+ This should be interpreted as a strong benchmark-specific validation result, not as a universal claim of bit-for-bit equivalence across every possible Stata configuration, missing-data pattern, lag window, instrument classification, covariance assumption, or finite-sample correction.
790
+
791
+ Future validation-extension priorities include:
792
+
793
+ * testing additional unbalanced-panel and missing-data designs beyond the maintained benchmark suite;
794
+ * expanding documented examples for short-`T`, longer-`T`, and high-`N`, low-`T` panels;
795
+ * validating additional lag-window choices and alternative instrument classifications;
796
+ * documenting exact Stata-compatible option combinations and known non-equivalence cases;
797
+ * maintaining clear separation between certified `xtabond2` parity paths and experimental or implementation-dependent paths;
798
+ * further investigating FOD-specific validation, especially FOD Windmeijer covariance and FOD AR diagnostic parity against `xtdpdgmm`;
799
+ * extending reviewer-facing artifacts as new benchmark specifications are added.
800
+
801
+ This roadmap protects the package from overclaiming while making clear that the core native System GMM parity milestone has already been reached for the maintained benchmark suite.
807
802
 
808
803
  ---
809
804
 
@@ -738,30 +738,25 @@ For dynamic-panel GMM, users should record at minimum:
738
738
 
739
739
  ## Validation roadmap
740
740
 
741
- Before claiming broader production certification across panel designs, the package should continue to be tested on:
741
+ ## Validation roadmap
742
742
 
743
- * balanced panels;
744
- * unbalanced panels;
745
- * short-`T` panels;
746
- * longer-`T` panels;
747
- * high-`N`, low-`T` panels;
748
- * panels with missing observations;
749
- * different lag windows;
750
- * models with no controls;
751
- * models with many controls;
752
- * interaction-heavy specifications;
753
- * decomposition specifications;
754
- * alternative instrument classifications;
755
- * Stata `xtabond2` replication benchmarks.
756
-
757
- High-priority remaining validation items:
758
-
759
- * broader System GMM parity across additional empirical specifications;
760
- * broader Windmeijer-corrected standard-error parity across additional empirical specifications;
761
- * broader robustness of Sargan, Hansen, and AR diagnostics across additional panel structures;
762
- * documentation of exact Stata-compatible options and known non-equivalence cases.
763
-
764
- This roadmap protects the package from overclaiming and supports academically defensible validation.
743
+ The current validation suite establishes benchmark-specific certification for the maintained native Difference GMM and native System GMM paths.
744
+
745
+ Native System GMM is certified against Stata `xtabond2` for the maintained collapsed two-step benchmark suite, including the baseline, no-controls, three-way interaction, and decomposition specifications. Certified quantities include sample size, group count, instrument count, coefficient estimates, Hansen diagnostics, Windmeijer-corrected two-step standard errors, and signed Arellano-Bond AR(1)/AR(2) diagnostics with p-values.
746
+
747
+ This should be interpreted as a strong benchmark-specific validation result, not as a universal claim of bit-for-bit equivalence across every possible Stata configuration, missing-data pattern, lag window, instrument classification, covariance assumption, or finite-sample correction.
748
+
749
+ Future validation-extension priorities include:
750
+
751
+ * testing additional unbalanced-panel and missing-data designs beyond the maintained benchmark suite;
752
+ * expanding documented examples for short-`T`, longer-`T`, and high-`N`, low-`T` panels;
753
+ * validating additional lag-window choices and alternative instrument classifications;
754
+ * documenting exact Stata-compatible option combinations and known non-equivalence cases;
755
+ * maintaining clear separation between certified `xtabond2` parity paths and experimental or implementation-dependent paths;
756
+ * further investigating FOD-specific validation, especially FOD Windmeijer covariance and FOD AR diagnostic parity against `xtdpdgmm`;
757
+ * extending reviewer-facing artifacts as new benchmark specifications are added.
758
+
759
+ This roadmap protects the package from overclaiming while making clear that the core native System GMM parity milestone has already been reached for the maintained benchmark suite.
765
760
 
766
761
  ---
767
762
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "systemgmmkit"
7
- version = "0.5.4"
7
+ version = "0.5.6"
8
8
  description = "Generic panel-data econometrics workflow helpers for FE, RE, IV/2SLS, and Difference/System GMM in Python."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -11,9 +11,9 @@ systemgmmkit reporting helpers:
11
11
 
12
12
  from __future__ import annotations
13
13
 
14
+ from collections.abc import Iterable
14
15
  from dataclasses import dataclass, field
15
16
  from math import erf, sqrt
16
- from typing import Iterable
17
17
 
18
18
  import numpy as np
19
19
  import pandas as pd
@@ -164,7 +164,7 @@ def first_difference(
164
164
  rss = float(resid @ resid)
165
165
 
166
166
  if nobs > 0:
167
- tss = float(((y_vec - y_vec.mean()) @ (y_vec - y_vec.mean())))
167
+ tss = float((y_vec - y_vec.mean()) @ (y_vec - y_vec.mean()))
168
168
  r2 = float(1.0 - rss / tss) if tss > 0 else float("nan")
169
169
  else:
170
170
  r2 = float("nan")
@@ -189,10 +189,7 @@ def first_difference(
189
189
  coef = params[name]
190
190
  se = std_errors[name]
191
191
 
192
- if np.isfinite(se) and se > 0:
193
- stat = float(coef / se)
194
- else:
195
- stat = float("nan")
192
+ stat = float(coef / se) if np.isfinite(se) and se > 0 else float("nan")
196
193
 
197
194
  t_stats[name] = stat
198
195
  p_values[name] = _normal_two_sided_pvalue(stat)
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import contextlib
4
- import os
5
4
  from dataclasses import dataclass
6
5
 
7
6
  import numpy as np
@@ -45,6 +44,10 @@ class NativeGMMResult:
45
44
  j_stat: float | None = None
46
45
  ztu_norm: float | None = None
47
46
  w_norm: float | None = None
47
+ hansen_j_stat: float | None = None
48
+ sargan_j_stat: float | None = None
49
+ overid_df: int | None = None
50
+ hansen_j_error: str | None = None
48
51
 
49
52
  def summary_frame(self) -> pd.DataFrame:
50
53
  return pd.DataFrame(
@@ -1360,7 +1363,6 @@ def _native_fod_difference_windmeijer_covariance(
1360
1363
  idx = np.asarray(indices, dtype=int)
1361
1364
 
1362
1365
  Zi = Z[idx, :]
1363
- Xi = X[idx, :]
1364
1366
  ui1 = u1[idx, :]
1365
1367
  ui2 = u2[idx, :]
1366
1368
 
@@ -1461,10 +1463,10 @@ def run_native_dynamic_panel_gmm(
1461
1463
  # and second-step weighting matrices.
1462
1464
 
1463
1465
  # SYSTEMGMMKIT_FILE_INSTRUMENT_DEBUG
1464
- import os
1466
+ import os as _native_debug_os
1465
1467
  from pathlib import Path as _NativeDebugPath
1466
1468
 
1467
- debug_file = os.getenv("SYSTEMGMMKIT_DEBUG_INSTRUMENTS_FILE")
1469
+ debug_file = _native_debug_os.getenv("SYSTEMGMMKIT_DEBUG_INSTRUMENTS_FILE")
1468
1470
  if debug_file:
1469
1471
  debug_path = _NativeDebugPath(debug_file)
1470
1472
  debug_path.parent.mkdir(parents=True, exist_ok=True)
@@ -1711,6 +1713,28 @@ def run_native_dynamic_panel_gmm(
1711
1713
  )
1712
1714
  _sargan_stat = float(_j_stat_raw * _sargan_small_scale)
1713
1715
 
1716
+ _hansen_j_stat = None
1717
+ _hansen_p_candidate = None
1718
+ _hansen_j_error = None
1719
+
1720
+ try:
1721
+ _s_group_diag = _native_group_moment_sum(
1722
+ Z=Z,
1723
+ residuals=residual_vec,
1724
+ group_indices=group_indices_for_cov,
1725
+ )
1726
+ _hansen_weight = np.linalg.pinv(_s_group_diag)
1727
+ _hansen_j_candidate = float((_ztu.T @ _hansen_weight @ _ztu).squeeze())
1728
+
1729
+ if np.isfinite(_hansen_j_candidate) and _hansen_j_candidate >= 0:
1730
+ _hansen_j_stat = _hansen_j_candidate
1731
+ if _overid_df > 0:
1732
+ _hansen_p_candidate = float(stats.chi2.sf(_hansen_j_candidate, _overid_df))
1733
+ except Exception as exc:
1734
+ _hansen_j_stat = None
1735
+ _hansen_p_candidate = None
1736
+ _hansen_j_error = f"{type(exc).__name__}: {exc}"
1737
+
1714
1738
  # Store a one-step Sargan-style J statistic only for one-step estimation.
1715
1739
  # In two-step / Windmeijer mode, W is the two-step weighting matrix, so the
1716
1740
  # same quadratic form is not comparable to xtabond2's one-step Sargan.
@@ -1829,6 +1853,9 @@ def run_native_dynamic_panel_gmm(
1829
1853
  "W_rows": int(W.shape[0]),
1830
1854
  "W_cols": int(W.shape[1]),
1831
1855
  "native_j_stat": _j_stat,
1856
+ "native_hansen_j_stat": _hansen_j_stat,
1857
+ "native_sargan_j_stat": _sargan_stat,
1858
+ "native_overid_df": _overid_df,
1832
1859
  "native_ztu_norm": _ztu_norm,
1833
1860
  "native_w_norm": _w_norm,
1834
1861
  }
@@ -1883,6 +1910,10 @@ def run_native_dynamic_panel_gmm(
1883
1910
  j_stat=_j_stat,
1884
1911
  ztu_norm=_ztu_norm,
1885
1912
  w_norm=_w_norm,
1913
+ hansen_j_stat=_hansen_j_stat,
1914
+ sargan_j_stat=_sargan_stat,
1915
+ overid_df=_overid_df,
1916
+ hansen_j_error=_hansen_j_error,
1886
1917
  )
1887
1918
 
1888
1919
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: systemgmmkit
3
- Version: 0.5.4
3
+ Version: 0.5.6
4
4
  Summary: Generic panel-data econometrics workflow helpers for FE, RE, IV/2SLS, and Difference/System GMM in Python.
5
5
  Author: Oluwajuwon Mayomi Akanbi
6
6
  License-Expression: MIT
@@ -780,30 +780,25 @@ For dynamic-panel GMM, users should record at minimum:
780
780
 
781
781
  ## Validation roadmap
782
782
 
783
- Before claiming broader production certification across panel designs, the package should continue to be tested on:
783
+ ## Validation roadmap
784
784
 
785
- * balanced panels;
786
- * unbalanced panels;
787
- * short-`T` panels;
788
- * longer-`T` panels;
789
- * high-`N`, low-`T` panels;
790
- * panels with missing observations;
791
- * different lag windows;
792
- * models with no controls;
793
- * models with many controls;
794
- * interaction-heavy specifications;
795
- * decomposition specifications;
796
- * alternative instrument classifications;
797
- * Stata `xtabond2` replication benchmarks.
798
-
799
- High-priority remaining validation items:
800
-
801
- * broader System GMM parity across additional empirical specifications;
802
- * broader Windmeijer-corrected standard-error parity across additional empirical specifications;
803
- * broader robustness of Sargan, Hansen, and AR diagnostics across additional panel structures;
804
- * documentation of exact Stata-compatible options and known non-equivalence cases.
805
-
806
- This roadmap protects the package from overclaiming and supports academically defensible validation.
785
+ The current validation suite establishes benchmark-specific certification for the maintained native Difference GMM and native System GMM paths.
786
+
787
+ Native System GMM is certified against Stata `xtabond2` for the maintained collapsed two-step benchmark suite, including the baseline, no-controls, three-way interaction, and decomposition specifications. Certified quantities include sample size, group count, instrument count, coefficient estimates, Hansen diagnostics, Windmeijer-corrected two-step standard errors, and signed Arellano-Bond AR(1)/AR(2) diagnostics with p-values.
788
+
789
+ This should be interpreted as a strong benchmark-specific validation result, not as a universal claim of bit-for-bit equivalence across every possible Stata configuration, missing-data pattern, lag window, instrument classification, covariance assumption, or finite-sample correction.
790
+
791
+ Future validation-extension priorities include:
792
+
793
+ * testing additional unbalanced-panel and missing-data designs beyond the maintained benchmark suite;
794
+ * expanding documented examples for short-`T`, longer-`T`, and high-`N`, low-`T` panels;
795
+ * validating additional lag-window choices and alternative instrument classifications;
796
+ * documenting exact Stata-compatible option combinations and known non-equivalence cases;
797
+ * maintaining clear separation between certified `xtabond2` parity paths and experimental or implementation-dependent paths;
798
+ * further investigating FOD-specific validation, especially FOD Windmeijer covariance and FOD AR diagnostic parity against `xtdpdgmm`;
799
+ * extending reviewer-facing artifacts as new benchmark specifications are added.
800
+
801
+ This roadmap protects the package from overclaiming while making clear that the core native System GMM parity milestone has already been reached for the maintained benchmark suite.
807
802
 
808
803
  ---
809
804
 
@@ -112,11 +112,3 @@ def test_native_system_gmm_matches_xtabond2_moments_a2_and_hansen() -> None:
112
112
  assert native_a2.shape == stata_a2.shape
113
113
  assert np.isfinite(native_a2).all()
114
114
  assert np.isfinite(stata_a2).all()
115
-
116
- return
117
-
118
- j_from_native_scaled_a2 = float(
119
- (stata_ze.T @ native_a2_scaled @ stata_ze).squeeze()
120
- )
121
-
122
- assert abs(j_from_native_scaled_a2 - XTABOND2_HANSEN) < 1e-5
File without changes
File without changes