From 88a791af0a2856db789481275228ae9fd60ac69e Mon Sep 17 00:00:00 2001 From: Hayden Freedman Date: Fri, 28 Jun 2024 16:56:12 -0600 Subject: [PATCH 01/15] feols.vcov() returns covariance matrix --- pyfixest/estimation/feols_.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfixest/estimation/feols_.py b/pyfixest/estimation/feols_.py index a3b18347..8782de55 100644 --- a/pyfixest/estimation/feols_.py +++ b/pyfixest/estimation/feols_.py @@ -478,7 +478,7 @@ def vcov( # update p-value, t-stat, standard error, confint self.get_inference() - return self + return self._vcov def _vcov_iid(self): _N = self._N From 7372f2b5ac7696fbe7de85c457f79281d178d61e Mon Sep 17 00:00:00 2001 From: Hayden Freedman Date: Mon, 1 Jul 2024 11:54:47 -0600 Subject: [PATCH 02/15] changed self._vcov to self.vcov in feols.py --- pyfixest/estimation/feols_.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pyfixest/estimation/feols_.py b/pyfixest/estimation/feols_.py index 8782de55..2c617043 100644 --- a/pyfixest/estimation/feols_.py +++ b/pyfixest/estimation/feols_.py @@ -256,7 +256,7 @@ def __init__( self._clustervar: list[str] = [] self._G: list[int] = [] self._ssc = np.array([], dtype=np.float64) - self._vcov = np.array([]) + self.vcov= np.array([]) self.na_index = np.array([]) # initiated outside of the class self.n_separation_na = 0 @@ -390,7 +390,7 @@ def vcov( vcov_type="iid", ) - self._vcov = self._ssc * self._vcov_iid() + self.vcov= self._ssc * self._vcov_iid() elif self._vcov_type == "hetero": self._ssc = get_ssc( @@ -402,7 +402,7 @@ def vcov( vcov_type="hetero", ) - self._vcov = self._ssc * self._vcov_hetero() + self.vcov= self._ssc * self._vcov_hetero() elif self._vcov_type == "CRV": if data is not None: @@ -429,7 +429,7 @@ def vcov( # loop over columns of cluster_df vcov_sign_list = [1, 1, -1] - self._vcov = np.zeros((self._k, self._k)) + self.vcov= np.zeros((self._k, self._k)) for x, col in enumerate(self._cluster_df.columns): cluster_col_pd = self._cluster_df[col] @@ -448,7 +448,7 @@ def vcov( self._ssc = np.array([ssc]) if x == 0 else np.append(self._ssc, ssc) if self._vcov_type_detail == "CRV1": - self._vcov += self._ssc[x] * self._vcov_crv1( + self.vcov+= self._ssc[x] * self._vcov_crv1( clustid=clustid, cluster_col=cluster_col ) @@ -467,18 +467,18 @@ def vcov( and (_method == "feols") and (_is_iv is False) ): - self._vcov += self._ssc[x] * self._vcov_crv3_fast( + self.vcov+= self._ssc[x] * self._vcov_crv3_fast( clustid=clustid, cluster_col=cluster_col ) else: - self._vcov += self._ssc[x] * self._vcov_crv3_slow( + self.vcov+= self._ssc[x] * self._vcov_crv3_slow( clustid=clustid, cluster_col=cluster_col ) # update p-value, t-stat, standard error, confint self.get_inference() - return self._vcov + return self def _vcov_iid(self): _N = self._N @@ -674,7 +674,7 @@ def get_inference(self, alpha: float = 0.95) -> None: ------- None """ - _vcov = self._vcov + _vcov = self.vcov _beta_hat = self._beta_hat _vcov_type = self._vcov_type _N = self._N @@ -783,7 +783,7 @@ def wald_test(self, R=None, q=None, distribution="F") -> None: """ raise ValueError("wald_tests will be released as a feature with pyfixest 0.14.") - _vcov = self._vcov + _vcov = self.vcov _N = self._N _k = self._k _beta_hat = self._beta_hat @@ -1198,7 +1198,7 @@ def ccv( vcov_splits /= N crv1_idx = self._coefnames.index(treatment) - vcov_crv1 = self._vcov[crv1_idx, crv1_idx] + vcov_crv1 = self.vcov[crv1_idx, crv1_idx] vcov_ccv = qk * vcov_splits + (1 - qk) * vcov_crv1 se = np.sqrt(vcov_ccv) @@ -1668,7 +1668,7 @@ def confint( crit_val = np.abs(norm.ppf(alpha / 2)) else: D_inv = 1 / self._se[joint_indices] - V = self._vcov[np.ix_(joint_indices, joint_indices)] + V = self.vcov[np.ix_(joint_indices, joint_indices)] C_coefs = (D_inv * V).T * D_inv crit_val = simultaneous_crit_val(C_coefs, reps, alpha=alpha, seed=seed) From f4e281a9e3af167588ddac68fd4a47d8cb30749d Mon Sep 17 00:00:00 2001 From: Hayden Freedman Date: Mon, 1 Jul 2024 12:04:14 -0600 Subject: [PATCH 03/15] Update quickstart.ipynb with vcov attribute --- docs/quickstart.ipynb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/quickstart.ipynb b/docs/quickstart.ipynb index fbfa0d66..4c3c071a 100644 --- a/docs/quickstart.ipynb +++ b/docs/quickstart.ipynb @@ -719,6 +719,13 @@ "fit.vcov({\"CRV3\": \"group_id\"}).summary()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After calling `.vcov()` on a feols object, the covariance matrix will be available as an attribute of the feols object called `.vcov`." + ] + }, { "cell_type": "markdown", "metadata": {}, From c05e12c4b5f8f8bdd1bbece52253aeae5f17bf8a Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Mon, 1 Jul 2024 21:12:21 +0200 Subject: [PATCH 04/15] Update lpdid.py rename `self._vcov` to `self.vcov` in the `lpdid` class --- pyfixest/did/lpdid.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyfixest/did/lpdid.py b/pyfixest/did/lpdid.py index f6d633d1..109a7deb 100644 --- a/pyfixest/did/lpdid.py +++ b/pyfixest/did/lpdid.py @@ -107,7 +107,7 @@ def __init__( if vcov is None: vcov = {"CRV1": idname} - self._vcov = vcov + self.vcov = vcov self._pre_window = pre_window_int self._post_window = post_window_int self._never_treated = never_treated @@ -121,7 +121,7 @@ def estimate(self): yname=self._yname, idname=self._idname, tname=self._tname, - vcov=self._vcov, + vcov=self.vcov, pre_window=self._pre_window, post_window=self._post_window, att=self._att, From ab24f36ff0e37e13a35ee443899dabc4a704fdc3 Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Mon, 1 Jul 2024 21:14:06 +0200 Subject: [PATCH 05/15] Update quickstart.ipynb the vcov attribute is always available =) --- docs/quickstart.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quickstart.ipynb b/docs/quickstart.ipynb index 4c3c071a..e2085fa4 100644 --- a/docs/quickstart.ipynb +++ b/docs/quickstart.ipynb @@ -723,7 +723,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "After calling `.vcov()` on a feols object, the covariance matrix will be available as an attribute of the feols object called `.vcov`." + "The estimated covariance matrix is available as an attribute of the `Feols` object called `.vcov`." ] }, { From 81be6615b9e6d0aff64ed994563f9806b8e03411 Mon Sep 17 00:00:00 2001 From: Hayden Freedman Date: Fri, 5 Jul 2024 17:58:41 -0600 Subject: [PATCH 06/15] Update feols_.py replacing .vcov with ._vcov --- pyfixest/estimation/feols_.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pyfixest/estimation/feols_.py b/pyfixest/estimation/feols_.py index f5f71f1b..1f06460c 100644 --- a/pyfixest/estimation/feols_.py +++ b/pyfixest/estimation/feols_.py @@ -263,7 +263,7 @@ def __init__( self._clustervar: list[str] = [] self._G: list[int] = [] self._ssc = np.array([], dtype=np.float64) - self.vcov= np.array([]) + self._vcov = np.array([]) self.na_index = np.array([]) # initiated outside of the class self.n_separation_na = 0 @@ -421,7 +421,7 @@ def vcov( vcov_type="iid", ) - self.vcov= self._ssc * self._vcov_iid() + self._vcov = self._ssc * self._vcov_iid() elif self._vcov_type == "hetero": self._ssc = get_ssc( @@ -433,7 +433,7 @@ def vcov( vcov_type="hetero", ) - self.vcov= self._ssc * self._vcov_hetero() + self._vcov = self._ssc * self._vcov_hetero() elif self._vcov_type == "CRV": if data is not None: @@ -460,7 +460,7 @@ def vcov( # loop over columns of cluster_df vcov_sign_list = [1, 1, -1] - self.vcov= np.zeros((self._k, self._k)) + self._vcov = np.zeros((self._k, self._k)) for x, col in enumerate(self._cluster_df.columns): cluster_col_pd = self._cluster_df[col] @@ -479,7 +479,7 @@ def vcov( self._ssc = np.array([ssc]) if x == 0 else np.append(self._ssc, ssc) if self._vcov_type_detail == "CRV1": - self.vcov+= self._ssc[x] * self._vcov_crv1( + self._vcov += self._ssc[x] * self._vcov_crv1( clustid=clustid, cluster_col=cluster_col ) @@ -498,11 +498,11 @@ def vcov( and (_method == "feols") and (_is_iv is False) ): - self.vcov+= self._ssc[x] * self._vcov_crv3_fast( + self._vcov += self._ssc[x] * self._vcov_crv3_fast( clustid=clustid, cluster_col=cluster_col ) else: - self.vcov+= self._ssc[x] * self._vcov_crv3_slow( + self._vcov += self._ssc[x] * self._vcov_crv3_slow( clustid=clustid, cluster_col=cluster_col ) @@ -706,7 +706,7 @@ def get_inference(self, alpha: float = 0.05) -> None: ------- None """ - _vcov = self.vcov + _vcov = self._vcov _beta_hat = self._beta_hat _vcov_type = self._vcov_type _N = self._N @@ -815,7 +815,7 @@ def wald_test(self, R=None, q=None, distribution="F") -> None: """ raise ValueError("wald_tests will be released as a feature with pyfixest 0.14.") - _vcov = self.vcov + _vcov = self._vcov _N = self._N _k = self._k _beta_hat = self._beta_hat @@ -1230,7 +1230,7 @@ def ccv( vcov_splits /= N crv1_idx = self._coefnames.index(treatment) - vcov_crv1 = self.vcov[crv1_idx, crv1_idx] + vcov_crv1 = self._vcov[crv1_idx, crv1_idx] vcov_ccv = qk * vcov_splits + (1 - qk) * vcov_crv1 se = np.sqrt(vcov_ccv) @@ -1712,7 +1712,7 @@ def confint( crit_val = np.abs(norm.ppf(alpha / 2)) else: D_inv = 1 / self._se[joint_indices] - V = self.vcov[np.ix_(joint_indices, joint_indices)] + V = self._vcov[np.ix_(joint_indices, joint_indices)] C_coefs = (D_inv * V).T * D_inv crit_val = simultaneous_crit_val(C_coefs, reps, alpha=alpha, seed=seed) From 2228131b9802665bd6aa12e30ee513cbadf2ae9e Mon Sep 17 00:00:00 2001 From: Hayden Freedman Date: Fri, 5 Jul 2024 18:01:59 -0600 Subject: [PATCH 07/15] Update quickstart.ipynb .vcov to ._vcov --- docs/quickstart.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/quickstart.ipynb b/docs/quickstart.ipynb index e2085fa4..dd486674 100644 --- a/docs/quickstart.ipynb +++ b/docs/quickstart.ipynb @@ -6,7 +6,7 @@ "source": [ "# Getting Started with PyFixest\n", "\n", - "## What is a fix effect model?\n", + "## What is a fixed effect model?\n", "\n", "A fixed effect model is a statistical model that includes fixed effects, which are parameters that are estimated to be constant across different groups. \n", "\n", @@ -723,7 +723,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The estimated covariance matrix is available as an attribute of the `Feols` object called `.vcov`." + "The estimated covariance matrix is available as an attribute of the `Feols` object called `._vcov`." ] }, { From 6f1fb7534e27ad7ada7e7fc0504d6e198a2e03e1 Mon Sep 17 00:00:00 2001 From: Hayden Freedman Date: Fri, 5 Jul 2024 18:06:23 -0600 Subject: [PATCH 08/15] .vcov to ._vcov --- pyfixest/did/lpdid.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyfixest/did/lpdid.py b/pyfixest/did/lpdid.py index 109a7deb..f6d633d1 100644 --- a/pyfixest/did/lpdid.py +++ b/pyfixest/did/lpdid.py @@ -107,7 +107,7 @@ def __init__( if vcov is None: vcov = {"CRV1": idname} - self.vcov = vcov + self._vcov = vcov self._pre_window = pre_window_int self._post_window = post_window_int self._never_treated = never_treated @@ -121,7 +121,7 @@ def estimate(self): yname=self._yname, idname=self._idname, tname=self._tname, - vcov=self.vcov, + vcov=self._vcov, pre_window=self._pre_window, post_window=self._post_window, att=self._att, From a407c92fd4c50c81f0513c1370a6203675137829 Mon Sep 17 00:00:00 2001 From: Hayden Freedman Date: Thu, 11 Jul 2024 16:51:34 -0600 Subject: [PATCH 09/15] lsqr method for fixed effect solver --- pyfixest/estimation/feols_.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyfixest/estimation/feols_.py b/pyfixest/estimation/feols_.py index 0bea777a..f69e0f13 100644 --- a/pyfixest/estimation/feols_.py +++ b/pyfixest/estimation/feols_.py @@ -1384,8 +1384,8 @@ def fixef(self) -> dict[str, dict[str, float]]: D2 = Formula("-1+" + fixef_fml).get_model_matrix(_data, output="sparse") cols = D2.model_spec.column_names - alpha = spsolve(D2.transpose() @ D2, D2.transpose() @ uhat) - + alpha = lsqr(D2, uhat) + res: dict[str, dict[str, float]] = {} for i, col in enumerate(cols): matches = re.match(r"(.+?)\[T\.(.+?)\]", col) From c3b088dacbfc2d650b7d6229384ffbdb8f4dc9c4 Mon Sep 17 00:00:00 2001 From: Hayden Freedman Date: Fri, 12 Jul 2024 07:11:29 -0600 Subject: [PATCH 10/15] Take first element from last() --- pyfixest/estimation/feols_.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfixest/estimation/feols_.py b/pyfixest/estimation/feols_.py index f69e0f13..7787f153 100644 --- a/pyfixest/estimation/feols_.py +++ b/pyfixest/estimation/feols_.py @@ -1384,7 +1384,7 @@ def fixef(self) -> dict[str, dict[str, float]]: D2 = Formula("-1+" + fixef_fml).get_model_matrix(_data, output="sparse") cols = D2.model_spec.column_names - alpha = lsqr(D2, uhat) + alpha = lsqr(D2, uhat)[0] res: dict[str, dict[str, float]] = {} for i, col in enumerate(cols): From ba598085a8d58827cbb32d47227584204051b694 Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Fri, 12 Jul 2024 23:03:39 +0200 Subject: [PATCH 11/15] Update feols_.py `uhat` as dense 1D array --- pyfixest/estimation/feols_.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfixest/estimation/feols_.py b/pyfixest/estimation/feols_.py index 7787f153..fbd64c80 100644 --- a/pyfixest/estimation/feols_.py +++ b/pyfixest/estimation/feols_.py @@ -1379,7 +1379,7 @@ def fixef(self) -> dict[str, dict[str, float]]: X = X[self._coefnames] # drop intercept, potentially multicollinear vars Y = Y.to_numpy().flatten().astype(np.float64) X = X.to_numpy() - uhat = csr_matrix(Y - X @ self._beta_hat).transpose() + uhat = (Y - X @ self._beta_hat).flatten() D2 = Formula("-1+" + fixef_fml).get_model_matrix(_data, output="sparse") cols = D2.model_spec.column_names From 4e73f58760a5bb480e079209698d2bcbec528c33 Mon Sep 17 00:00:00 2001 From: greenguy33 Date: Thu, 18 Jul 2024 20:27:57 -0600 Subject: [PATCH 12/15] atol and btol argument to lsqr --- pyfixest/estimation/feols_.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/pyfixest/estimation/feols_.py b/pyfixest/estimation/feols_.py index fd0c6bf9..68d6b630 100644 --- a/pyfixest/estimation/feols_.py +++ b/pyfixest/estimation/feols_.py @@ -1358,7 +1358,7 @@ def ccv( n_splits=n_splits, ) - def fixef(self) -> dict[str, dict[str, float]]: + def fixef(self, atol, btol) -> dict[str, dict[str, float]]: """ Compute the coefficients of (swept out) fixed effects for a regression model. @@ -1404,12 +1404,12 @@ def fixef(self) -> dict[str, dict[str, float]]: X = X[self._coefnames] # drop intercept, potentially multicollinear vars Y = Y.to_numpy().flatten().astype(np.float64) X = X.to_numpy() - uhat = csr_matrix(Y - X @ self._beta_hat).transpose() + uhat = (Y - X @ self._beta_hat).flatten() D2 = Formula("-1+" + fixef_fml).get_model_matrix(_data, output="sparse") cols = D2.model_spec.column_names - alpha = lsqr(D2, uhat) + alpha = lsqr(D2, uhat, atol=atol, btol=btol)[0] res: dict[str, dict[str, float]] = {} for i, col in enumerate(cols): @@ -1429,7 +1429,7 @@ def fixef(self) -> dict[str, dict[str, float]]: return self._fixef_dict - def predict(self, newdata: Optional[DataFrameType] = None) -> np.ndarray: + def predict(self, newdata: Optional[DataFrameType] = None, atol: Float = 1e-6, btol: Float = 1e-6) -> np.ndarray: """ Predict values of the model on new data. @@ -1442,6 +1442,12 @@ def predict(self, newdata: Optional[DataFrameType] = None) -> np.ndarray: newdata : Optional[DataFrameType], optional A pd.DataFrame or pl.DataFrame with the data to be used for prediction. If None (default), the data used for fitting the model is used. + atol : Float, default 1e-6 + Stopping tolerance for scipy.sparse.linalg.lsqr(). + See https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.linalg.lsqr.html + btol : Float, default 1e-6 + Another stopping tolerance for scipy.sparse.linalg.lsqr(). + See https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.linalg.lsqr.html Returns ------- @@ -1472,7 +1478,7 @@ def predict(self, newdata: Optional[DataFrameType] = None) -> np.ndarray: if self._has_fixef: if self._sumFE is None: - self.fixef() + self.fixef(atol, btol) fvals = self._fixef.split("+") df_fe = newdata[fvals].astype(str) # populate fixed effect dicts with omitted categories handling From a5428fe64627d7ff1e2278e44c2115470ae50643 Mon Sep 17 00:00:00 2001 From: greenguy33 Date: Thu, 18 Jul 2024 21:05:13 -0600 Subject: [PATCH 13/15] float data type fixed --- .gitignore | 1 + pyfixest/estimation/feols_.py | 2 +- tests/.coverage | Bin 53248 -> 53248 bytes 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1cef81b4..4ad0559a 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,5 @@ readme.ipynb #objects.json #docs/site_libs #site_libs +tests/.coverage diff --git a/pyfixest/estimation/feols_.py b/pyfixest/estimation/feols_.py index 68d6b630..e529f140 100644 --- a/pyfixest/estimation/feols_.py +++ b/pyfixest/estimation/feols_.py @@ -1429,7 +1429,7 @@ def fixef(self, atol, btol) -> dict[str, dict[str, float]]: return self._fixef_dict - def predict(self, newdata: Optional[DataFrameType] = None, atol: Float = 1e-6, btol: Float = 1e-6) -> np.ndarray: + def predict(self, newdata: Optional[DataFrameType] = None, atol: float = 1e-6, btol: float = 1e-6) -> np.ndarray: """ Predict values of the model on new data. diff --git a/tests/.coverage b/tests/.coverage index 0ff6f399a0ab4e56123f7906e81f4e23e116982d..b8efbe173150b2e797f3a6ccba40668f8c58c137 100644 GIT binary patch literal 53248 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 literal 53248 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 d!YD#0f+%DZ0Tg}|J``RQ5(*K82L- Date: Thu, 18 Jul 2024 23:05:13 -0600 Subject: [PATCH 14/15] changed assert_allclose tolerance level in test --- pyfixest/estimation/feols_.py | 2 +- tests/.coverage | Bin 53248 -> 53248 bytes tests/test_predict_resid_fixef.py | 8 ++++---- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyfixest/estimation/feols_.py b/pyfixest/estimation/feols_.py index e529f140..7f8b30e1 100644 --- a/pyfixest/estimation/feols_.py +++ b/pyfixest/estimation/feols_.py @@ -1358,7 +1358,7 @@ def ccv( n_splits=n_splits, ) - def fixef(self, atol, btol) -> dict[str, dict[str, float]]: + def fixef(self, atol : float = 1e-06, btol : float = 1e-06) -> dict[str, dict[str, float]]: """ Compute the coefficients of (swept out) fixed effects for a regression model. diff --git a/tests/.coverage b/tests/.coverage index b8efbe173150b2e797f3a6ccba40668f8c58c137..350f993bb1edb860ba933f60f828f072e7e6d650 100644 GIT binary patch delta 1131 zcmYjPe@qis9RJ>3uXoqG>rr6LR-rY+AstjQks?E=XttK2OedM3h8n;y<0gm$&DPzK z&6rGn=1o~#W=WR)wQR6paQ`5kE(USgfH-H2gKh@1IR~8q!?g7FUb`*65MrOiq0L>-Dat<0Y%mU_}n9@+PyzD;ZGZ#3i3hyKSfks|&0Qv=C4_+IFA;3yN0| zR&&LAzOJqnpFK~bzqaL|)85pfE#+6)BL1B4s_+#5BfnPY;P)%rq)hRwA_(7_ub7XS zpBL}Q5$TXvE*j-8OzCPmUb;8fPx}EYwQWjm0)M(?TGH@c%V!P0*akzum+oe6K)}eYpwS zHQ%hsOB1U=Sy1jPx0OldE9Em~hdEQeCr`=a@)`N4TqI3NUrRoT74M4EVux6T&8`;F z;ZuWZSu#rr?S|yJy9&g|NLRt*+bz={mKD>WE!*{XFe(^;2M3Iq9UKk-uh2Lo;Yo#4 zAjH05AvtO+t`LFu?!LoBe`hc)+8V$s@O~=^3qLQW;Gi9DU;%O)3It5XC2rd8;ud| zQt75YaPjEOi<4Opt3CL^{UDrAfpE}!Tnj{18$9a%KHCZ0TJ&sZMnip&f&OX%k_ycR zN;qO3E+odmqtB=d7gFbFfUq8WNU75GsY9PPrBt@(1KNdw|G@Z7VnJVY<-0?Dp}EM7k$sqT z=~4ImV^bjwp?6<9@%CjJnwFMdqD&s3CrY1?;p~g{-py$!++|ot!!9T888qR!Cw#Jf z7QcAJb!$2q3WxJNxM*9Ha#0V&ogDdinaJOr^|A(fu=LYe-Tp*U4Ib)$4@G>jQQCQW zOrR;sWW-%gGj5jvj2SH6m#{_TEdVvc8Qy|xSG9)895mit#H1;Wi0jG4zj(ef)EN9I F?;j4XQ!xMl delta 1335 zcmZWoU2GIp6h1SvKl6Wgw=MhMT?2-)>6Th-mlWJi6NqIg5K&`GFw)RsmsDG`ZT(4b zheV$U#m!9&@<8!H6McX-O?=^{BnAok0P#(YDH@?^j6keL66|`;%#IIwl6%g%-}$-U zIg_z3N%kdaq1y`km9LaJFIWxx1qhRQVf&JEY^sXP2zfH~wB_NI9q6klU1u zd{6$I9niOE7nq_3%cbd)%VpsMou2ruju!2nxBIF%F#TH zB4qf3m-94<(8@=KcKgx=slq=V%4-ecsh!dc-4%~_l3yI^@g-ciQzXj6oh|>P9D7Ep z^5+ia__2ek%lgQdPZrbaBCvJ#EBk@nW{d0-Hf-jN-;M8$Z;g55w6S0RMgLlVMbGG< z{iS`XO=@G>F0Dla^|pFdT}0-SYE@4A1SOKbQ15F_p_fao=>V|W2O#*YDh%Y4h#pOT zw*%2zbqO^}76$6B^RVhzPnk^#Om9nkC;%LDQ_g=B-x5c#6#uhG@?f5xl+|`Ry*N^|w@o6sF5QkkMEG zLAO{$l0;O1(8;i0P)@%P?pSs(im$qZoFX3}MrvK~g~$T|tt*skY>I+^_mLJy8POPEKW+>+mS%5IJCs$aR?Aki#FwT35swf8F$+G+ z+qpx;rnd6aCcbgf{9>o`h*fv@MMeJ+cNb1eTSysL)oaWuIKaxk^g@d48JxP?LnWC=uF`u zS#dPDk6Vokgi1mB9L>SCd-Y7M)+Vi>>2KP)(WeG*5t{-B@jnQ(`q3}?d%Zy^^1z=I#;O*X=gu;N;xK(bW9@Qn0VYVv6y3`(WUYE H^PT?yMojf= diff --git a/tests/test_predict_resid_fixef.py b/tests/test_predict_resid_fixef.py index ce011ea1..f95aa65d 100644 --- a/tests/test_predict_resid_fixef.py +++ b/tests/test_predict_resid_fixef.py @@ -174,7 +174,7 @@ def test_predict_nas(): res = fit.predict(newdata=data) fit_r = fixest.feols(ro.Formula(fml), data=data) res_r = stats.predict(fit_r, newdata=data) - np.testing.assert_allclose(res, res_r) + np.testing.assert_allclose(res, res_r, atol=1e-05, rtol=1e-05) assert data.shape[0] == len(res) assert len(res) == len(res_r) @@ -187,14 +187,14 @@ def test_predict_nas(): res = fit.predict(newdata=newdata) fit_r = fixest.feols(ro.Formula(fml), data=data) res_r = stats.predict(fit_r, newdata=newdata) - np.testing.assert_allclose(res, res_r) + np.testing.assert_allclose(res, res_r, atol=1e-05, rtol=1e-05) assert newdata.shape[0] == len(res) assert len(res) == len(res_r) newdata.loc[198, "Y"] = np.nan res = fit.predict(newdata=newdata) res_r = stats.predict(fit_r, newdata=newdata) - np.testing.assert_allclose(res, res_r) + np.testing.assert_allclose(res, res_r, atol=1e-05, rtol=1e-05) assert newdata.shape[0] == len(res) assert len(res) == len(res_r) @@ -204,7 +204,7 @@ def test_predict_nas(): res = fit.predict(newdata=data) fit_r = fixest.feols(ro.Formula(fml), data=data) res_r = stats.predict(fit_r, newdata=data) - np.testing.assert_allclose(res, res_r) + np.testing.assert_allclose(res, res_r, atol=1e-05, rtol=1e-05) assert data.shape[0] == len(res) assert len(res) == len(res_r) From 932730818d1bfcc72cc87ddb3bb8ce091e3987f4 Mon Sep 17 00:00:00 2001 From: greenguy33 Date: Thu, 18 Jul 2024 23:33:14 -0600 Subject: [PATCH 15/15] adding tolerance level to test_did assert_allclose() --- tests/.coverage | Bin 53248 -> 53248 bytes tests/test_did.py | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/.coverage b/tests/.coverage index 350f993bb1edb860ba933f60f828f072e7e6d650..ef76747fe563ff9163714c6069e00e499afd5d92 100644 GIT binary patch delta 1284 zcmZ8gTWB0*6h5;vyK|p^lTF>(OS3CYX}V- zX2!cDdY8ndZl@`#-cmnQ$JI9Fp7NP8scc(rirB@aXO zzTSIAn=>MFsWji%mPO z`547l1Nvvk2e3)43sRgcfJABq$pKKBMNTLxIdLG4gh#ab=z=7}#&0TDbx93pv;oN&`V5s%s`T^8PP%KCD*e~D8M zwnRn$lVBHqOHas}SXDCTRUBaDUwUx|@|ckCG`3^-gfaiP!3n%VuHNuNsL`HZKc9|0 zjbv@$chB#Yw<|c=JBNA4f}L!P781eM9{SnZKw?V-`~~MJMjbtJ=#`-gZt{3-VP7u+ zB;l=!zYju!5e3D8$ZdbA1d@2Lp5xaSl0E2C5}g@5BrCp#;Bu$&0P(U+ucJj?`?a2{ z)!M}sGy{ok8~s`g7x7f=5Pto!)+qXY(NegGup0Q+@0Y|38|3l_MU73cBkTn>%m(rQ dk=Yh%AY?MWNvD02O8LgNeUnTspIp4S^B-@8>fZnW delta 1164 zcmY*XeN0nV6hH5yeed^bAIP{ z&hNaZ_A+WO)4$#wLkX9JQ^F1*j=#=-!u$B-ff&=T9PPBB*S${N3sweNQH3`Zm3k!I z`a}jA(6~24mtKD?Z#C*KN=5H^V%b#;_z6g3~=$>g6xx8pCD7al;nbVW6cxX%@Hs8^^eqBWQbZ3VPQov9?^M zb?H&!F|pQcrhz=fs@kdyym9SB)VC)MYcR8`H!^+_TtR~W)3NF?;R8&V;A9#JOd+s; z1zDC;9mu!Mz%6T9iNbr+mL-*avnDfM+zHB@a#y*jj4NL$pDEjoN%9?eLLQaR$W3yN zG$DO0c_p2ATbvZz#hqBl(;})n)$cDb>nNd(HP75uU}+6?WwIQf1-E)D9UO?wl2 z1r~U)!-&z&VFU0Ajg1L!DijMr-N6{bQ5KUPBx0uKu42DITTk#3J&qB=HFY~e3 zsCCskfK&+KdiJy|2FA*bBn;h)LFx=^r|^|sazKrR^WfVEDz$A0p2p6jMoIvm8(nQr z*tAa}MT?Zl=q^8I?W>3mM@jBN{>DFX@yOJR4jTtuq;YU-Q~tU0aWgbPNQ>U5{L=M_1D`h}7S0~x z0DLWY9Kj7e-4yt|DRvoW7Rb#Om4(n!HeoOYjdmUu)(g*C;TN z%AR%44WZGF1pPEsm3bo#-Raokcko!zJ0<*u;WpL&9}yuVYfNjsn6B+V;avRQfA+g% zO$7JbYWc^Bc#2a;qW6lmb0S|kTa4T5y+F+mGb;1DALVT(BT-2{xFP)0;oTZ`sOS40 zJC`EM2l}Ej%Ngtm&V+v)+KW*aA9l??GPr06zV+JiH!jgozp(fcWpD#Mmj6T=W}mm6 z-V~2QooogTB@R3@sKsc^Q0MEgPCqzv?W5NQ}@Ij9Qk-j$k&zpvI<%t z|I=yB_5`U4_q7KDVQ+Mpc6=}*&=h6R<0;4Mw@Cncs}A4ubU8!|K-r+xlYRAyT0NeM YM!RyDc%=q$-D&t2&r$|z0v~4n143|JBme*a diff --git a/tests/test_did.py b/tests/test_did.py index 2fdb7f1d..46c002fe 100644 --- a/tests/test_did.py +++ b/tests/test_did.py @@ -47,8 +47,8 @@ def test_event_study(data): did2s_df = pd.DataFrame(did2s_df).T if True: - np.testing.assert_allclose(fit_did2s.coef(), stats.coef(fit_did2s_r)) - np.testing.assert_allclose(fit_did2s.se(), float(did2s_df[2])) + np.testing.assert_allclose(fit_did2s.coef(), stats.coef(fit_did2s_r), atol = 1e-05, rtol = 1e-05) + np.testing.assert_allclose(fit_did2s.se(), float(did2s_df[2]), atol = 1e-05, rtol = 1e-05) def test_did2s(data): @@ -78,8 +78,8 @@ def test_did2s(data): did2s_df = broom.tidy_fixest(fit_did2s_r, conf_int=ro.BoolVector([True])) did2s_df = pd.DataFrame(did2s_df).T - np.testing.assert_allclose(fit_did2s.coef(), stats.coef(fit_did2s_r)) - np.testing.assert_allclose(fit_did2s.se(), float(did2s_df[2])) + np.testing.assert_allclose(fit_did2s.coef(), stats.coef(fit_did2s_r), atol = 1e-05, rtol = 1e-05) + np.testing.assert_allclose(fit_did2s.se(), float(did2s_df[2]), atol = 1e-05, rtol = 1e-05) if True: # ATT, event study @@ -105,8 +105,8 @@ def test_did2s(data): did2s_df = broom.tidy_fixest(fit_r, conf_int=ro.BoolVector([True])) did2s_df = pd.DataFrame(did2s_df).T - np.testing.assert_allclose(fit.coef(), stats.coef(fit_r)) - np.testing.assert_allclose(fit.se(), did2s_df[2].values.astype(float)) + np.testing.assert_allclose(fit.coef(), stats.coef(fit_r), atol = 1e-05, rtol = 1e-05) + np.testing.assert_allclose(fit.se(), did2s_df[2].values.astype(float), atol = 1e-05, rtol = 1e-05) if True: # test event study with covariate in first stage @@ -131,8 +131,8 @@ def test_did2s(data): did2s_df = broom.tidy_fixest(fit_r, conf_int=ro.BoolVector([True])) did2s_df = pd.DataFrame(did2s_df).T - np.testing.assert_allclose(fit.coef(), stats.coef(fit_r)) - np.testing.assert_allclose(fit.se(), did2s_df[2].values.astype(float)) + np.testing.assert_allclose(fit.coef(), stats.coef(fit_r), atol = 1e-05, rtol = 1e-05) + np.testing.assert_allclose(fit.se(), did2s_df[2].values.astype(float), atol = 1e-05, rtol = 1e-05) if True: # test event study with covariate in first stage and second stage @@ -157,8 +157,8 @@ def test_did2s(data): did2s_df = broom.tidy_fixest(fit_r, conf_int=ro.BoolVector([True])) did2s_df = pd.DataFrame(did2s_df).T - np.testing.assert_allclose(fit.coef(), stats.coef(fit_r)) - np.testing.assert_allclose(fit.se(), did2s_df[2].values.astype(float)) + np.testing.assert_allclose(fit.coef(), stats.coef(fit_r), atol = 1e-05, rtol = 1e-05) + np.testing.assert_allclose(fit.se(), did2s_df[2].values.astype(float), atol = 1e-05, rtol = 1e-05) if True: # binary non boolean treatment variable, just check that it runs