def msm_res(params, moments_cov, func_kwargs): res = estimate_msm( simulate_moments=simulate_aggregated_moments, # only needed for shape since optimization is skipped empirical_moments=np.zeros(6), params=params, optimize_options=False, moments_cov=moments_cov, simulate_moments_kwargs=func_kwargs, weights="optimal", ) return res
def test_estimate_msm(simulate_moments, moments_cov, optimize_options): start_params = np.array([3, 2, 1]) expected_params = np.zeros(3) # abuse simulate_moments to get empirical moments in correct format empirical_moments = simulate_moments(expected_params) if isinstance(empirical_moments, dict): empirical_moments = empirical_moments["simulated_moments"] calculated = estimate_msm( simulate_moments=simulate_moments, empirical_moments=empirical_moments, moments_cov=moments_cov, params=start_params, optimize_options=optimize_options, ) # check that minimization works aaae(calculated.params, expected_params) # check that cov works calculated_cov = calculated.cov() if isinstance(calculated_cov, pd.DataFrame): calculated_cov = calculated_cov.to_numpy() # this works only in the very special case with diagonal moments cov and # jac = identity matrix expected_cov = np.diag([1, 2, 3]) aaae(calculated_cov, expected_cov) aaae(calculated.se(), np.sqrt([1, 2, 3])) # works only because parameter point estimates are exactly zero aaae(calculated.p_values(), np.ones(3)) # expected_ci_upper = np.array([1.95996398, 2.77180765, 3.3947572]) expected_ci_lower = -expected_ci_upper lower, upper = calculated.ci() aaae(lower, expected_ci_lower) aaae(upper, expected_ci_upper) aaae(calculated.ci(), calculated._ci) aaae(calculated.p_values(), calculated._p_values) aaae(calculated.se(), calculated._se) aaae(calculated.cov(), calculated._cov) summary = calculated.summary() aaae(summary["value"], np.zeros(3)) aaae(summary["p_value"], np.ones(3)) assert summary["stars"].tolist() == [""] * 3
def test_to_pickle(tmp_path): start_params = np.array([3, 2, 1]) # abuse simulate_moments to get empirical moments in correct format empirical_moments = _sim_np(np.zeros(3)) if isinstance(empirical_moments, dict): empirical_moments = empirical_moments["simulated_moments"] calculated = estimate_msm( simulate_moments=_sim_np, empirical_moments=empirical_moments, moments_cov=cov_np, params=start_params, optimize_options="scipy_lbfgsb", ) calculated.to_pickle(tmp_path / "bla.pkl")
def test_estimate_msm(simulate_moments, moments_cov): start_params = pd.DataFrame() start_params["value"] = [3, 2, 1] expected_params = pd.DataFrame() expected_params["value"] = np.zeros(3) # abuse simulate_moments to get empirical moments in correct format empirical_moments = simulate_moments(expected_params) if isinstance(empirical_moments, dict): empirical_moments = empirical_moments["simulated_moments"] optimize_options = {"algorithm": "scipy_lbfgsb"} # catching warnings is necessary because the very special case with diagonal # weighting and diagonal jacobian leads to singular matrices while calculating # sensitivity to removal of moments. with warnings.catch_warnings(): warnings.filterwarnings("ignore", message="Standard matrix inversion failed") calculated = estimate_msm( simulate_moments=simulate_moments, empirical_moments=empirical_moments, moments_cov=moments_cov, params=start_params, optimize_options=optimize_options, ) calculated_params = calculated["optimize_res"]["solution_params"][[ "value" ]] # check that minimization works aaae(calculated_params["value"].to_numpy(), expected_params["value"].to_numpy()) # check that cov works calculated_cov = calculated["cov"] if isinstance(calculated_cov, pd.DataFrame): calculated_cov = calculated_cov.to_numpy() # this works only in the very special case with diagonal moments cov and # jac = identity matrix expected_cov = np.diag([1, 2, 3]) aaae(calculated_cov, expected_cov)
def test_estimate_msm_ls(simulate_moments, moments_cov, optimize_options): start_params = np.array([3, 2, 1]) expected_params = np.zeros(3) # abuse simulate_moments to get empirical moments in correct format empirical_moments = simulate_moments(expected_params) if isinstance(empirical_moments, dict): empirical_moments = empirical_moments["simulated_moments"] calculated = estimate_msm( simulate_moments=simulate_moments, empirical_moments=empirical_moments, moments_cov=moments_cov, params=start_params, optimize_options=optimize_options, ) aaae(calculated.params, expected_params)
def test_caching(): start_params = np.array([3, 2, 1]) # abuse simulate_moments to get empirical moments in correct format empirical_moments = _sim_np(np.zeros(3)) if isinstance(empirical_moments, dict): empirical_moments = empirical_moments["simulated_moments"] got = estimate_msm( simulate_moments=_sim_np, empirical_moments=empirical_moments, moments_cov=cov_np, params=start_params, optimize_options="scipy_lbfgsb", ) assert got._cache == {} cov = got.cov(method="robust", return_type="array") assert got._cache == {} cov = got.cov(method="robust", return_type="array", seed=0) assert_array_equal(list(got._cache.values())[0], cov)
def test_estimate_msm_with_jacobian(): start_params = np.array([3, 2, 1]) expected_params = np.zeros(3) # abuse simulate_moments to get empirical moments in correct format empirical_moments = _sim_np(expected_params) if isinstance(empirical_moments, dict): empirical_moments = empirical_moments["simulated_moments"] calculated = estimate_msm( simulate_moments=_sim_np, empirical_moments=empirical_moments, moments_cov=cov_np, params=start_params, optimize_options="scipy_lbfgsb", jacobian=lambda x: np.eye(len(x)), ) aaae(calculated.params, expected_params) aaae(calculated.cov(), cov_np)
def test_estimate_msm_dict_params_and_moments(): def simulate_moments(params): return {k * 2: v for k, v in params.items()} start_params = {"a": 3, "b": 2, "c": 1} expected_params = {"a": 0, "b": 0, "c": 0} empirical_moments = {"aa": 0, "bb": 0, "cc": 0} moments_cov = { "aa": {"aa": 1, "bb": 0, "cc": 0}, "bb": {"aa": 0, "bb": 2, "cc": 0}, "cc": {"aa": 0, "bb": 0, "cc": 3}, } calculated = estimate_msm( simulate_moments=simulate_moments, empirical_moments=empirical_moments, moments_cov=moments_cov, params=start_params, optimize_options="scipy_lbfgsb", ) # check that minimization works assert_almost_equal(calculated.params, expected_params) # this works only in the very special case with diagonal moments cov and # jac = identity matrix assert_almost_equal(calculated.cov(), moments_cov) assert_almost_equal(calculated.se(), {"a": 1, "b": np.sqrt(2), "c": np.sqrt(3)}) # works only because parameter point estimates are exactly zero assert_almost_equal(calculated.p_values(), {"a": 1, "b": 1, "c": 1}) expected_ci_upper = {"a": 1.95996398, "b": 2.77180765, "c": 3.3947572} expected_ci_lower = {k: -v for k, v in expected_ci_upper.items()} lower, upper = calculated.ci() assert_almost_equal(lower, expected_ci_lower) assert_almost_equal(upper, expected_ci_upper) assert_almost_equal(calculated.ci(), calculated._ci) assert_almost_equal(calculated.p_values(), calculated._p_values) assert_almost_equal(calculated.se(), calculated._se) assert_almost_equal(calculated.cov(), calculated._cov) summary = calculated.summary() summary_df = pd.concat(list(summary.values())) aaae(summary_df["value"], np.zeros(3)) aaae(summary_df["p_value"], np.ones(3)) assert summary_df["stars"].tolist() == [""] * 3 expected_sensitivity_to_bias_dict = { "a": {"aa": -1.0, "bb": 0.0, "cc": 0.0}, "b": {"aa": 0.0, "bb": -1.0, "cc": 0.0}, "c": {"aa": 0.0, "bb": 0.0, "cc": -1.0}, } assert_almost_equal( calculated.sensitivity("bias"), expected_sensitivity_to_bias_dict ) expected_sensitivity_to_bias_arr = -np.eye(3) aaae( calculated.sensitivity("bias", return_type="array"), expected_sensitivity_to_bias_arr, ) aaae( calculated.sensitivity("bias", return_type="dataframe").to_numpy(), expected_sensitivity_to_bias_arr, ) expected_jacobian = { "a": {"aa": 1.0, "bb": 0.0, "cc": 0.0}, "b": {"aa": 0.0, "bb": 1.0, "cc": 0.0}, "c": {"aa": 0.0, "bb": 0.0, "cc": 1.0}, } assert_almost_equal(calculated.jacobian, expected_jacobian)