From feba6b4c95c07e78767263a77a8b9b287dde60b8 Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Fri, 30 Aug 2024 18:45:23 +0200 Subject: [PATCH 01/11] flatten residual --- .coverage | Bin 53248 -> 53248 bytes pyfixest/estimation/FixestMulti_.py | 2 +- pyfixest/estimation/feols_.py | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.coverage b/.coverage index 7deaa6558f09b3ec0358ae27f458692d8fe9009f..43d031a8678d1f310a6baba09cfc10f9e61d7cca 100644 GIT binary patch delta 1224 zcmY+C%WqRh6vpq|nfsXg8apO&f*nZBq6<)PTj4@NAx`SrNgSI1ja{XZOR`Z1+?8*s;aUmQrqmRN`O=(SU|!876q29y5J$Pr0Tgh_lmHX#re*h@0>aF zTW!(R7X6L&s6@Pw#EbQC=(&gqLSxaz+Sz7(ZuZmORPRTIBuPZPk;I$zaN}Q5GH8tZ zc^gv+EhLG%;-WYqqRu1diZkKF?0@VZ?2_GXZCDqq1LiC9SM!V+Gd7Ixj05~7|Al|U zeC$<#nZh zHM8O7W#@;2EQLR@$c9(IGLUH(@ za!B^ALX}E=wmx5R2TKtuHC?Nd)!MfUQ>eJ`B($(3E{S{gkK&~0bRIk4l$^Nz#4ek0 zW0Rk#Y&m4%^T*Fv23LHD}G&{;NAK&{d+B}ozNrNW9=Feaz}+te4UR6NkE~L zp`Xze?@xU^SkGa)90A`U0&p~LAv4h$s`gHQQ}A08VUH|!S~1fyykME z?EHe^=erEy{LVo><%5TjdF t`?haTPSGZJ@zDc({%EnDpIFN~G$AHHyEP<>iS_YYreFyw*)X~B^Z%||Z@&Nl delta 2586 zcmY*ZYiv~45uW?l`@Z+=!``*y*L7NogdJmr)PN0m?S*)4V+ zre?1Lfi!Iz?9-&GS{0-!YSkYpNgAuFlG-XQp%96sZCa#I9x5XAktQIh4A|bzxx3!h zN80_)eCL}vb7n@@IVCu!gwvv}@Z<)NPsxq9eclgAg~1CYWOrgDo;c7uQcXCaC^Xi8 zU}SJ;|JtfARz0Nw08efMxlQh)!xi$3A(U`SdR`NX)U4b@Wx3o2%gb5EVZ>=$Ud&jDV57n0;As|sf^_Y(L8W%T_*mA1Hnp2#p#aY^9bxVn=b8cmMi{5{^*?j) zD;TaZL`$1%Xew%QL3%Y>&*h`tC^h8eZZVr>`f^m4wgiwO=v-s&JGghWcWB=*`fu~o z!!6r6AHCGlLhrP0=9>vEX>H*wdTDE|cc6cGXmBLX(l&DeBT>I+gCRiDeZ>1smK4^P zUJ*JtI=FYFJ02h0KR6m^j!hb#1=zJ@taoTE?h25Ps94cjTG^uV5e2sqsY%W$`$t9x z_a#QL@2G5-sI#?$^I%4sr7a?g+*i;aHtSM@fF`SECH-cbpX0FvtLcR{!msDB4eMLj z#FWc1AZOJV$uTvi`jwROva(GH${&)5eqZmm=4EP4Tm4qC{-*gCBdq(i3+9yBti7mh z)zM(t!y@+oMzj+9?-k2xg+s2<8q>wn zI^j8H_*f5@Mxdlo#GIM_Ow7*}vtZbLpIDR?d$SFHas*%h*m~hvrnRypQiW@U5k{Fy zLr@SACsbtC;2ap9P`x<8p;d7NX zW=_TbI%}YRXs011-!e^hcW@Hkyak({=zQ8Ey0=brJ%LU3d4%lyDp{jNem$1E zyt$IT*RH?iT_C0aChIy!=7G$=?d$oJY(!HKOqG2ULK@Qd$iK)Ha*4c2UMJhEQuC(y zf%#kWgn7WMHU3~s8DG$E>F?_^dWXJA!w}xHS|S|saOwnvz7Ea>4&ZiLz+lUkldfN8 z1K5yLT~Bh}pvb9@2mL4#fd>b?`|?@LuKcn3bUHLS`BYNQ1<35|tnFRm6}GW6mLlb0 zKr8Q9NdR#}U^G?Yy{y6aN@v$_&?5mn(T=&ku3G;tvcg&BCvxrJhA%lB=z0VSGhE{k0D&acb zW=vi zXQ^DAjGYZ?4-l5@R&sT*Gl|*!Jh3>l$S$3$-}p~Vdj8temsY}Je9ucaPr@$(aQ!69 zfvtzH#FDXXoD$~3%w#23ut&hz@URRGcMXI6Q89qo0#1#EiSDVJgOcd;h! zn$1ln%x5y6EdzGw;3dXqIDS1$$3I`KU_FoaD8HVWaBTOfj9*%*^!RV8(tD1tUAUP1 z(FZHjI)sln@gJ06@2?$PyxV?f<&qNan?FrUyKy#f(r{(^#XB>voq5Ox^W72;fmskI6II&ZJ;kkt->>u!{`i%1W_*bp7A8l9# z3o`m|bda58rNqsvFChZ9ayD21aEKYW6fnXCHqKb}BAftqyUb?k^YTAFPM1wiKCU{D zK3V_cn`kryl8ZC^s#njcJjZDgmNzKHaAc)Y5AHX4YTcGWSI`X$kg62Yuny*ARmAf= zaVk1>)Dm!8Dhy;7FY#zwJg;%0suqZf#6gOE$U-CmjEJzSe6T>>4IUnpzAJZ?!!4%buC44L6%*RB*|vidpxcwiY^F(3p_946V np.ndarray: np.ndarray A np.ndarray with the residuals of the estimated regression model. """ - return self._u_hat + return self._u_hat.flatten() def ritest( self, From d5e1e1d1d8faf85acb40a9ad3d2c4ed1a82433df Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Fri, 30 Aug 2024 18:47:52 +0200 Subject: [PATCH 02/11] add tests for empty models --- tests/test_vs_fixest.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_vs_fixest.py b/tests/test_vs_fixest.py index 52a9e7d4..75cd5903 100644 --- a/tests/test_vs_fixest.py +++ b/tests/test_vs_fixest.py @@ -74,6 +74,10 @@ # ("Y ~ X1/X2"), # currently does not work as X1/X2 translation not implemented # noqa: W505 # ("Y ~ X1/X2 | f1+f2"), # currently does not work as X1/X2 translation not implemented # noqa: W505 ("Y ~ X1 + poly(X2, 2) | f1"), + # empty models + "Y ~ 1 | f1", + "Y ~ 1 | f1 + f2" "Y ~ 0 | f1", + "Y ~ 0 | f1 + f2", ] ols_but_not_poisson_fml = [ From 1955f68aeda45d1f6610c33df08d4624fe67b6be Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Fri, 30 Aug 2024 18:57:29 +0200 Subject: [PATCH 03/11] bump version, build lock file --- poetry.lock | 141 +++++++++++++++++++++++++++++-------------------- pyproject.toml | 2 +- 2 files changed, 84 insertions(+), 59 deletions(-) diff --git a/poetry.lock b/poetry.lock index af6ad9bd..484c50bd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -290,13 +290,13 @@ redis = ["redis (>=2.10.5)"] [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, ] [[package]] @@ -561,66 +561,87 @@ test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] [[package]] name = "contourpy" -version = "1.2.1" +version = "1.3.0" description = "Python library for calculating contours of 2D quadrilateral grids" optional = false python-versions = ">=3.9" files = [ - {file = "contourpy-1.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd7c23df857d488f418439686d3b10ae2fbf9bc256cd045b37a8c16575ea1040"}, - {file = "contourpy-1.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5b9eb0ca724a241683c9685a484da9d35c872fd42756574a7cfbf58af26677fd"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c75507d0a55378240f781599c30e7776674dbaf883a46d1c90f37e563453480"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11959f0ce4a6f7b76ec578576a0b61a28bdc0696194b6347ba3f1c53827178b9"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb3315a8a236ee19b6df481fc5f997436e8ade24a9f03dfdc6bd490fea20c6da"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39f3ecaf76cd98e802f094e0d4fbc6dc9c45a8d0c4d185f0f6c2234e14e5f75b"}, - {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:94b34f32646ca0414237168d68a9157cb3889f06b096612afdd296003fdd32fd"}, - {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:457499c79fa84593f22454bbd27670227874cd2ff5d6c84e60575c8b50a69619"}, - {file = "contourpy-1.2.1-cp310-cp310-win32.whl", hash = "sha256:ac58bdee53cbeba2ecad824fa8159493f0bf3b8ea4e93feb06c9a465d6c87da8"}, - {file = "contourpy-1.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9cffe0f850e89d7c0012a1fb8730f75edd4320a0a731ed0c183904fe6ecfc3a9"}, - {file = "contourpy-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6022cecf8f44e36af10bd9118ca71f371078b4c168b6e0fab43d4a889985dbb5"}, - {file = "contourpy-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef5adb9a3b1d0c645ff694f9bca7702ec2c70f4d734f9922ea34de02294fdf72"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6150ffa5c767bc6332df27157d95442c379b7dce3a38dff89c0f39b63275696f"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c863140fafc615c14a4bf4efd0f4425c02230eb8ef02784c9a156461e62c965"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00e5388f71c1a0610e6fe56b5c44ab7ba14165cdd6d695429c5cd94021e390b2"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4492d82b3bc7fbb7e3610747b159869468079fe149ec5c4d771fa1f614a14df"}, - {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49e70d111fee47284d9dd867c9bb9a7058a3c617274900780c43e38d90fe1205"}, - {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b59c0ffceff8d4d3996a45f2bb6f4c207f94684a96bf3d9728dbb77428dd8cb8"}, - {file = "contourpy-1.2.1-cp311-cp311-win32.whl", hash = "sha256:7b4182299f251060996af5249c286bae9361fa8c6a9cda5efc29fe8bfd6062ec"}, - {file = "contourpy-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2855c8b0b55958265e8b5888d6a615ba02883b225f2227461aa9127c578a4922"}, - {file = "contourpy-1.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:62828cada4a2b850dbef89c81f5a33741898b305db244904de418cc957ff05dc"}, - {file = "contourpy-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:309be79c0a354afff9ff7da4aaed7c3257e77edf6c1b448a779329431ee79d7e"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e785e0f2ef0d567099b9ff92cbfb958d71c2d5b9259981cd9bee81bd194c9a4"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cac0a8f71a041aa587410424ad46dfa6a11f6149ceb219ce7dd48f6b02b87a7"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af3f4485884750dddd9c25cb7e3915d83c2db92488b38ccb77dd594eac84c4a0"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ce6889abac9a42afd07a562c2d6d4b2b7134f83f18571d859b25624a331c90b"}, - {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a1eea9aecf761c661d096d39ed9026574de8adb2ae1c5bd7b33558af884fb2ce"}, - {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:187fa1d4c6acc06adb0fae5544c59898ad781409e61a926ac7e84b8f276dcef4"}, - {file = "contourpy-1.2.1-cp312-cp312-win32.whl", hash = "sha256:c2528d60e398c7c4c799d56f907664673a807635b857df18f7ae64d3e6ce2d9f"}, - {file = "contourpy-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:1a07fc092a4088ee952ddae19a2b2a85757b923217b7eed584fdf25f53a6e7ce"}, - {file = "contourpy-1.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bb6834cbd983b19f06908b45bfc2dad6ac9479ae04abe923a275b5f48f1a186b"}, - {file = "contourpy-1.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1d59e739ab0e3520e62a26c60707cc3ab0365d2f8fecea74bfe4de72dc56388f"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd3db01f59fdcbce5b22afad19e390260d6d0222f35a1023d9adc5690a889364"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a12a813949e5066148712a0626895c26b2578874e4cc63160bb007e6df3436fe"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe0ccca550bb8e5abc22f530ec0466136379c01321fd94f30a22231e8a48d985"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1d59258c3c67c865435d8fbeb35f8c59b8bef3d6f46c1f29f6123556af28445"}, - {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f32c38afb74bd98ce26de7cc74a67b40afb7b05aae7b42924ea990d51e4dac02"}, - {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d31a63bc6e6d87f77d71e1abbd7387ab817a66733734883d1fc0021ed9bfa083"}, - {file = "contourpy-1.2.1-cp39-cp39-win32.whl", hash = "sha256:ddcb8581510311e13421b1f544403c16e901c4e8f09083c881fab2be80ee31ba"}, - {file = "contourpy-1.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:10a37ae557aabf2509c79715cd20b62e4c7c28b8cd62dd7d99e5ed3ce28c3fd9"}, - {file = "contourpy-1.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a31f94983fecbac95e58388210427d68cd30fe8a36927980fab9c20062645609"}, - {file = "contourpy-1.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef2b055471c0eb466033760a521efb9d8a32b99ab907fc8358481a1dd29e3bd3"}, - {file = "contourpy-1.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b33d2bc4f69caedcd0a275329eb2198f560b325605810895627be5d4b876bf7f"}, - {file = "contourpy-1.2.1.tar.gz", hash = "sha256:4d8908b3bee1c889e547867ca4cdc54e5ab6be6d3e078556814a22457f49423c"}, + {file = "contourpy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:880ea32e5c774634f9fcd46504bf9f080a41ad855f4fef54f5380f5133d343c7"}, + {file = "contourpy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:76c905ef940a4474a6289c71d53122a4f77766eef23c03cd57016ce19d0f7b42"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92f8557cbb07415a4d6fa191f20fd9d2d9eb9c0b61d1b2f52a8926e43c6e9af7"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36f965570cff02b874773c49bfe85562b47030805d7d8360748f3eca570f4cab"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cacd81e2d4b6f89c9f8a5b69b86490152ff39afc58a95af002a398273e5ce589"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69375194457ad0fad3a839b9e29aa0b0ed53bb54db1bfb6c3ae43d111c31ce41"}, + {file = "contourpy-1.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a52040312b1a858b5e31ef28c2e865376a386c60c0e248370bbea2d3f3b760d"}, + {file = "contourpy-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3faeb2998e4fcb256542e8a926d08da08977f7f5e62cf733f3c211c2a5586223"}, + {file = "contourpy-1.3.0-cp310-cp310-win32.whl", hash = "sha256:36e0cff201bcb17a0a8ecc7f454fe078437fa6bda730e695a92f2d9932bd507f"}, + {file = "contourpy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:87ddffef1dbe5e669b5c2440b643d3fdd8622a348fe1983fad7a0f0ccb1cd67b"}, + {file = "contourpy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fa4c02abe6c446ba70d96ece336e621efa4aecae43eaa9b030ae5fb92b309ad"}, + {file = "contourpy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:834e0cfe17ba12f79963861e0f908556b2cedd52e1f75e6578801febcc6a9f49"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbc4c3217eee163fa3984fd1567632b48d6dfd29216da3ded3d7b844a8014a66"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4865cd1d419e0c7a7bf6de1777b185eebdc51470800a9f42b9e9decf17762081"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:303c252947ab4b14c08afeb52375b26781ccd6a5ccd81abcdfc1fafd14cf93c1"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637f674226be46f6ba372fd29d9523dd977a291f66ab2a74fbeb5530bb3f445d"}, + {file = "contourpy-1.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:76a896b2f195b57db25d6b44e7e03f221d32fe318d03ede41f8b4d9ba1bff53c"}, + {file = "contourpy-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e1fd23e9d01591bab45546c089ae89d926917a66dceb3abcf01f6105d927e2cb"}, + {file = "contourpy-1.3.0-cp311-cp311-win32.whl", hash = "sha256:d402880b84df3bec6eab53cd0cf802cae6a2ef9537e70cf75e91618a3801c20c"}, + {file = "contourpy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:6cb6cc968059db9c62cb35fbf70248f40994dfcd7aa10444bbf8b3faeb7c2d67"}, + {file = "contourpy-1.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:570ef7cf892f0afbe5b2ee410c507ce12e15a5fa91017a0009f79f7d93a1268f"}, + {file = "contourpy-1.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:da84c537cb8b97d153e9fb208c221c45605f73147bd4cadd23bdae915042aad6"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0be4d8425bfa755e0fd76ee1e019636ccc7c29f77a7c86b4328a9eb6a26d0639"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c0da700bf58f6e0b65312d0a5e695179a71d0163957fa381bb3c1f72972537c"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb8b141bb00fa977d9122636b16aa67d37fd40a3d8b52dd837e536d64b9a4d06"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3634b5385c6716c258d0419c46d05c8aa7dc8cb70326c9a4fb66b69ad2b52e09"}, + {file = "contourpy-1.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0dce35502151b6bd35027ac39ba6e5a44be13a68f55735c3612c568cac3805fd"}, + {file = "contourpy-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aea348f053c645100612b333adc5983d87be69acdc6d77d3169c090d3b01dc35"}, + {file = "contourpy-1.3.0-cp312-cp312-win32.whl", hash = "sha256:90f73a5116ad1ba7174341ef3ea5c3150ddf20b024b98fb0c3b29034752c8aeb"}, + {file = "contourpy-1.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:b11b39aea6be6764f84360fce6c82211a9db32a7c7de8fa6dd5397cf1d079c3b"}, + {file = "contourpy-1.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3e1c7fa44aaae40a2247e2e8e0627f4bea3dd257014764aa644f319a5f8600e3"}, + {file = "contourpy-1.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:364174c2a76057feef647c802652f00953b575723062560498dc7930fc9b1cb7"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32b238b3b3b649e09ce9aaf51f0c261d38644bdfa35cbaf7b263457850957a84"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d51fca85f9f7ad0b65b4b9fe800406d0d77017d7270d31ec3fb1cc07358fdea0"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:732896af21716b29ab3e988d4ce14bc5133733b85956316fb0c56355f398099b"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d73f659398a0904e125280836ae6f88ba9b178b2fed6884f3b1f95b989d2c8da"}, + {file = "contourpy-1.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c6c7c2408b7048082932cf4e641fa3b8ca848259212f51c8c59c45aa7ac18f14"}, + {file = "contourpy-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f317576606de89da6b7e0861cf6061f6146ead3528acabff9236458a6ba467f8"}, + {file = "contourpy-1.3.0-cp313-cp313-win32.whl", hash = "sha256:31cd3a85dbdf1fc002280c65caa7e2b5f65e4a973fcdf70dd2fdcb9868069294"}, + {file = "contourpy-1.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:4553c421929ec95fb07b3aaca0fae668b2eb5a5203d1217ca7c34c063c53d087"}, + {file = "contourpy-1.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:345af746d7766821d05d72cb8f3845dfd08dd137101a2cb9b24de277d716def8"}, + {file = "contourpy-1.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3bb3808858a9dc68f6f03d319acd5f1b8a337e6cdda197f02f4b8ff67ad2057b"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:420d39daa61aab1221567b42eecb01112908b2cab7f1b4106a52caaec8d36973"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d63ee447261e963af02642ffcb864e5a2ee4cbfd78080657a9880b8b1868e18"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:167d6c890815e1dac9536dca00828b445d5d0df4d6a8c6adb4a7ec3166812fa8"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:710a26b3dc80c0e4febf04555de66f5fd17e9cf7170a7b08000601a10570bda6"}, + {file = "contourpy-1.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:75ee7cb1a14c617f34a51d11fa7524173e56551646828353c4af859c56b766e2"}, + {file = "contourpy-1.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:33c92cdae89ec5135d036e7218e69b0bb2851206077251f04a6c4e0e21f03927"}, + {file = "contourpy-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a11077e395f67ffc2c44ec2418cfebed032cd6da3022a94fc227b6faf8e2acb8"}, + {file = "contourpy-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e8134301d7e204c88ed7ab50028ba06c683000040ede1d617298611f9dc6240c"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e12968fdfd5bb45ffdf6192a590bd8ddd3ba9e58360b29683c6bb71a7b41edca"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fd2a0fc506eccaaa7595b7e1418951f213cf8255be2600f1ea1b61e46a60c55f"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4cfb5c62ce023dfc410d6059c936dcf96442ba40814aefbfa575425a3a7f19dc"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68a32389b06b82c2fdd68276148d7b9275b5f5cf13e5417e4252f6d1a34f72a2"}, + {file = "contourpy-1.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:94e848a6b83da10898cbf1311a815f770acc9b6a3f2d646f330d57eb4e87592e"}, + {file = "contourpy-1.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d78ab28a03c854a873787a0a42254a0ccb3cb133c672f645c9f9c8f3ae9d0800"}, + {file = "contourpy-1.3.0-cp39-cp39-win32.whl", hash = "sha256:81cb5ed4952aae6014bc9d0421dec7c5835c9c8c31cdf51910b708f548cf58e5"}, + {file = "contourpy-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:14e262f67bd7e6eb6880bc564dcda30b15e351a594657e55b7eec94b6ef72843"}, + {file = "contourpy-1.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fe41b41505a5a33aeaed2a613dccaeaa74e0e3ead6dd6fd3a118fb471644fd6c"}, + {file = "contourpy-1.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eca7e17a65f72a5133bdbec9ecf22401c62bcf4821361ef7811faee695799779"}, + {file = "contourpy-1.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1ec4dc6bf570f5b22ed0d7efba0dfa9c5b9e0431aeea7581aa217542d9e809a4"}, + {file = "contourpy-1.3.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:00ccd0dbaad6d804ab259820fa7cb0b8036bda0686ef844d24125d8287178ce0"}, + {file = "contourpy-1.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ca947601224119117f7c19c9cdf6b3ab54c5726ef1d906aa4a69dfb6dd58102"}, + {file = "contourpy-1.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c6ec93afeb848a0845a18989da3beca3eec2c0f852322efe21af1931147d12cb"}, + {file = "contourpy-1.3.0.tar.gz", hash = "sha256:7ffa0db17717a8ffb127efd0c95a4362d996b892c2904db72428d5b52e1938a4"}, ] [package.dependencies] -numpy = ">=1.20" +numpy = ">=1.23" [package.extras] bokeh = ["bokeh", "selenium"] docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] -mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.8.0)", "types-Pillow"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.11.1)", "types-Pillow"] test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] -test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] +test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] [[package]] name = "coverage" @@ -2838,13 +2859,13 @@ type = ["mypy (>=1.8)"] [[package]] name = "plotly" -version = "5.23.0" +version = "5.24.0" description = "An open-source, interactive data visualization library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "plotly-5.23.0-py3-none-any.whl", hash = "sha256:76cbe78f75eddc10c56f5a4ee3e7ccaade7c0a57465546f02098c0caed6c2d1a"}, - {file = "plotly-5.23.0.tar.gz", hash = "sha256:89e57d003a116303a34de6700862391367dd564222ab71f8531df70279fc0193"}, + {file = "plotly-5.24.0-py3-none-any.whl", hash = "sha256:0e54efe52c8cef899f7daa41be9ed97dfb6be622613a2a8f56a86a0634b2b67e"}, + {file = "plotly-5.24.0.tar.gz", hash = "sha256:eae9f4f54448682442c92c1e97148e3ad0c52f0cf86306e1b76daba24add554a"}, ] [package.dependencies] @@ -4228,19 +4249,23 @@ win32 = ["pywin32"] [[package]] name = "setuptools" -version = "73.0.1" +version = "74.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-73.0.1-py3-none-any.whl", hash = "sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e"}, - {file = "setuptools-73.0.1.tar.gz", hash = "sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193"}, + {file = "setuptools-74.0.0-py3-none-any.whl", hash = "sha256:0274581a0037b638b9fc1c6883cc71c0210865aaa76073f7882376b641b84e8f"}, + {file = "setuptools-74.0.0.tar.gz", hash = "sha256:a85e96b8be2b906f3e3e789adec6a9323abf79758ecfa3065bd740d81158b11e"}, ] [package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] [[package]] name = "shellingham" diff --git a/pyproject.toml b/pyproject.toml index 868750c5..584c3539 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pyfixest" -version = "0.24.1" +version = "0.24.2" description = "Fast high dimensional fixed effect estimation following syntax of the fixest R package. Supports OLS, IV and Poisson regression and a range of inference procedures (HC1-3, CRV1 & CRV3, wild bootstrap, randomization inference, simultaneous CIs, Romano-Wolf's multiple testing correction). Additionally, supports (some of) the regression based new Difference-in-Differences Estimators (Did2s, Linear Projections)." authors = ["Alexander Fischer ", "Styfen Schär"] From 97fa66359168b6d667ed515c73eabb2960c03970 Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Fri, 30 Aug 2024 19:15:22 +0200 Subject: [PATCH 04/11] udpate tests --- .coverage | Bin 53248 -> 0 bytes tests/test_vs_fixest.py | 19 +++++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) delete mode 100644 .coverage diff --git a/.coverage b/.coverage deleted file mode 100644 index 43d031a8678d1f310a6baba09cfc10f9e61d7cca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53248 zcmeI4O>7)z8OLWmYtMeaaU5sk*oh~uz_IGMGN^$hrHSLXC23JUn;_LdG3;LD0)6XyH{xSVDqhqwx@r5&9d)_OV6>851c zY43vIZmwK&{R1Q-&E*DPp&t&KPwBR-N?SI{((%1GY*wZ+Q+IA>wBpcE;;!^!GVC(_ zWV@oF1D#OLR!OLA*%kJF$u=708`7E9jg1J)7Wuj6`qA1}{R!97Yi7d>v*DPoX*G1Y zCd(~XR<;aqnxTao!HY&iTGu(C>we4NUJ*K-##^)uE)N=4$+?CVV(m2KTT^4t=SHi( zM95!i)tlTo)WW~9Yi-wZySA>Hk42(E9IJVvqtZ?N=D1Iyw@e_{L(C$+;;|3T5)_lardT|D2%7H zWV+7APP!{;HV$u-I(&Znyx~#Oog_SpYBk-edP9a=>wf1@Hb=+I6Cn)4=7FYL!G+}M zr)vTrNT=O!>nte7~altcA+%OcHqv7eV)sAM?CsYH`+~dzy~!`LKCaI@!^1)>&hDWzzF0TwHjXze0m9 z9AC6kuN#d@uwL;p?5on;&x4ci<4+>gP@kkh>Cg~;Kr<8#&hm^E>d!QZ39HtPia*@B zQzDA1H{>Qce>FN|xY9N2Qs+xNXS~E(H5|QcOFBtw>C~k9acRK4RhnhXRdR~o%C*N6 zTJiD66YW+o82x#s>tv?5z)y&e6#Bsi0w4eaAOHd&00JNY0w4eaAOHd&u=5D0iN1v9*Z&_X;=`R6 zAR+<*5C8!X009sH0T2KI5C8!X0D(u8fJmsL#o#{yd}-$B%xs20B*cFe`oRVQAOHd& z00JNY0w4eaAOHd&00JPelL%zg(RA>S0Q~%aLffT?KZtwcvM3hbE4*H~S{Tj$HUGo> zwfu1Io!l$AC$smnzsy#%qnURy-_AUl{&)Ik>FepS)ZbHYrd~+x*51?J&@Pb(HV^;- z5C8!X_>2-bHIY=>{qx5cUvTKthl@r{t{IDGta7U^8?Lk1T(6pI(s4UGE!V6$i=~p; zFx^s#K7lxYh!nE%735l3HocD|lgLxLs@#sP;rT+XPmHU|t=O$A%T0$G&mAQHwfL>& zN-4bm+<}-9wrpCq8>M)9j3m-Aya*&#Os8ek%x_7GoO(4b$;vmO)bKvG1zVs(B)(cacb(ffY%Bsx(*Fk!J;I z^q7quITAWwAfd;4<5H2XEW0I#z9)sgDu%wv!2_Kq!5%?ZBz;{#gH=xDNF~l9& zTwWoCxhyHfnM9>+TeRLp){&<(BoSx!s+g5%`;%#Euf|}@?W5D@v6QN;$87JeR(a+< zuBpn)F`L$!4EegGu$1zteEtg6at z%;5ddkM+eP9?6!Y2~~08+*B^LmdROu{y(7&D&jTqcK%1=ir80pzwrISwZd5bZ~3oh z$1?Axjr`u+ySdxBquKvtf0bR%+{zqH-%tNMbv1n;^+DHV zj@17L<4SC<{}0S3+vzx7Y*GJ@olLe9J!pg&M|<=kTL15VCfOEoe2A11k+*jvUrn}$ zdX(v^|M$hs&WJx7^?&gpf{N7tdoLy1lRXBtP5nRoT(UjVqvV72|DJQncClBj?)rad zA=%FNDAlR|cRxhmZPfpRag#cd0Ac;V>mjnSBS+PTxR7i=)+3iK>;J+-fbP`)`M8Tf zC#azQ&&8bqH`o8!xU&}*v5_ewb1KK`9E?11V8`;KmY_l00ck)1V8`;KmY`GJ^?)c-}!xv2tfb@KmY_l00ck)1V8`; zKmY_lfS>OS7ylCf6#oz(h`)$Gi$99D#qY)M#BarK#IMCK#81Uf#9QJG z@w&JtzANsCSH!w-g(Y4RQd}1=k_a{s009sH0T2KI5C8!X009sH0T6hk2&faPl2;G0 z(b?Ewn=G3Qn>3pg U8;#8Xn|?M)HY%GwHVHES2YkXaMgRZ+ diff --git a/tests/test_vs_fixest.py b/tests/test_vs_fixest.py index 75cd5903..1d3c593d 100644 --- a/tests/test_vs_fixest.py +++ b/tests/test_vs_fixest.py @@ -213,16 +213,19 @@ def test_single_fit_feols( r_tstat = df_X1["statistic"] r_confint = df_X1[["conf.low", "conf.high"]].values.astype(np.float64) r_nobs = int(stats.nobs(r_fixest)[0]) - r_resid = r_fixest.rx2("working_residuals") # noqa: F841 + r_resid = stats.residuals(r_fixest) r_vcov = stats.vcov(r_fixest)[0, 0] - check_absolute_diff(py_nobs, r_nobs, 1e-08, "py_nobs != r_nobs") - check_absolute_diff(py_coef, r_coef, 1e-08, "py_coef != r_coef") - check_absolute_diff(py_vcov, r_vcov, 1e-08, "py_vcov != r_vcov") - check_absolute_diff(py_se, r_se, 1e-08, "py_se != r_se") - check_absolute_diff(py_pval, r_pval, 1e-08, "py_pval != r_pval") - check_absolute_diff(py_tstat, r_tstat, 1e-07, "py_tstat != r_tstat") - check_absolute_diff(py_confint, r_confint, 1e-08, "py_confint != r_confint") + if not mod._is_empty: + check_absolute_diff(py_nobs, r_nobs, 1e-08, "py_nobs != r_nobs") + check_absolute_diff(py_coef, r_coef, 1e-08, "py_coef != r_coef") + check_absolute_diff(py_vcov, r_vcov, 1e-08, "py_vcov != r_vcov") + check_absolute_diff(py_se, r_se, 1e-08, "py_se != r_se") + check_absolute_diff(py_pval, r_pval, 1e-08, "py_pval != r_pval") + check_absolute_diff(py_tstat, r_tstat, 1e-07, "py_tstat != r_tstat") + check_absolute_diff(py_confint, r_confint, 1e-08, "py_confint != r_confint") + + check_absolute_diff(py_resid[0:5], r_resid[0:5], 1e-08, "py_resid != r_resid") if not weights: py_r2 = mod._r2 From 1a5ad8b929ed9a5a5e5b70c61766609991404914 Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Fri, 30 Aug 2024 22:45:12 +0200 Subject: [PATCH 05/11] add test typo --- tests/test_vs_fixest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_vs_fixest.py b/tests/test_vs_fixest.py index 1d3c593d..189d0d51 100644 --- a/tests/test_vs_fixest.py +++ b/tests/test_vs_fixest.py @@ -216,7 +216,7 @@ def test_single_fit_feols( r_resid = stats.residuals(r_fixest) r_vcov = stats.vcov(r_fixest)[0, 0] - if not mod._is_empty: + if not mod._X_is_empty: check_absolute_diff(py_nobs, r_nobs, 1e-08, "py_nobs != r_nobs") check_absolute_diff(py_coef, r_coef, 1e-08, "py_coef != r_coef") check_absolute_diff(py_vcov, r_vcov, 1e-08, "py_vcov != r_vcov") From 9a6e8c9449f9d9c8642467d50b6f8957201aaa60 Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Sat, 31 Aug 2024 12:16:46 +0200 Subject: [PATCH 06/11] update tests --- tests/test_vs_fixest.py | 21 ++++++++++++--------- tests/texfiles/test.tex | 4 ++-- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/test_vs_fixest.py b/tests/test_vs_fixest.py index 189d0d51..b34c1e4f 100644 --- a/tests/test_vs_fixest.py +++ b/tests/test_vs_fixest.py @@ -131,10 +131,7 @@ def check_absolute_diff(x1, x2, tol, msg=None): @pytest.mark.parametrize("f3_type", ["str", "object", "int", "categorical", "float"]) @pytest.mark.parametrize("fml", ols_fmls + ols_but_not_poisson_fml) @pytest.mark.parametrize("adj", [False, True]) -# see here for why not test against cluster_adj = True -# it triggers the N / (N-1) correction, not sure why -# https://github.com/lrberge/fixest/issues/518#issuecomment-2227365516 -@pytest.mark.parametrize("cluster_adj", [False]) +@pytest.mark.parametrize("cluster_adj", [False, True]) def test_single_fit_feols( N, seed, @@ -201,8 +198,7 @@ def test_single_fit_feols( py_confint = mod.confint().xs("X1").values py_nobs = mod._N py_vcov = mod._vcov[0, 0] - - py_resid = mod._u_hat.flatten() # noqa: F841 + py_resid = mod.resid() # TODO: test residuals df_X1 = _get_r_df(r_fixest) @@ -217,15 +213,22 @@ def test_single_fit_feols( r_vcov = stats.vcov(r_fixest)[0, 0] if not mod._X_is_empty: - check_absolute_diff(py_nobs, r_nobs, 1e-08, "py_nobs != r_nobs") - check_absolute_diff(py_coef, r_coef, 1e-08, "py_coef != r_coef") + if inference == "iid" and adj and cluster_adj: + check_absolute_diff(py_nobs, r_nobs, 1e-08, "py_nobs != r_nobs") + check_absolute_diff(py_coef, r_coef, 1e-08, "py_coef != r_coef") + check_absolute_diff(py_vcov, r_vcov, 1e-08, "py_vcov != r_vcov") check_absolute_diff(py_se, r_se, 1e-08, "py_se != r_se") check_absolute_diff(py_pval, r_pval, 1e-08, "py_pval != r_pval") check_absolute_diff(py_tstat, r_tstat, 1e-07, "py_tstat != r_tstat") check_absolute_diff(py_confint, r_confint, 1e-08, "py_confint != r_confint") - check_absolute_diff(py_resid[0:5], r_resid[0:5], 1e-08, "py_resid != r_resid") + # residuals invariant so to vcov type + if inference == "iid" and adj and cluster_adj: + check_absolute_diff(py_resid[0:5], r_resid[0:5], 1e-08, "py_resid != r_resid") + + if mod._X_is_empty: + assert mod._beta_hat.size == 0 if not weights: py_r2 = mod._r2 diff --git a/tests/texfiles/test.tex b/tests/texfiles/test.tex index b1e56662..e85b0793 100644 --- a/tests/texfiles/test.tex +++ b/tests/texfiles/test.tex @@ -12,9 +12,9 @@ \midrule f1 & x & x \\ \midrule -$R^2$ & 0.489 & - \\ -S.E. type & by: f1 & by: f1+f2 \\ Observations & 1994 & 997 \\ +S.E. type & by: f1 & by: f1+f2 \\ +$R^2$ & 0.489 & - \\ \bottomrule \end{tabular} \footnotesize Significance levels: $*$ p $<$ 0.05, $**$ p $<$ 0.01, $***$ p $<$ 0.001. Format of coefficient cell: Coefficient From b1bc08aecdb4af4fb6700e3fb384d80fe3fe7242 Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Sat, 31 Aug 2024 12:21:23 +0200 Subject: [PATCH 07/11] fix test typo --- tests/test_vs_fixest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_vs_fixest.py b/tests/test_vs_fixest.py index b34c1e4f..e5afaad5 100644 --- a/tests/test_vs_fixest.py +++ b/tests/test_vs_fixest.py @@ -76,7 +76,8 @@ ("Y ~ X1 + poly(X2, 2) | f1"), # empty models "Y ~ 1 | f1", - "Y ~ 1 | f1 + f2" "Y ~ 0 | f1", + "Y ~ 1 | f1 + f2", + "Y ~ 0 | f1", "Y ~ 0 | f1 + f2", ] From 45112d89c767b5ed0791928beb10cf0abdd961bd Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Sat, 31 Aug 2024 12:29:05 +0200 Subject: [PATCH 08/11] cleanups --- tests/test_vs_fixest.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_vs_fixest.py b/tests/test_vs_fixest.py index e5afaad5..35b4ec5f 100644 --- a/tests/test_vs_fixest.py +++ b/tests/test_vs_fixest.py @@ -75,10 +75,10 @@ # ("Y ~ X1/X2 | f1+f2"), # currently does not work as X1/X2 translation not implemented # noqa: W505 ("Y ~ X1 + poly(X2, 2) | f1"), # empty models - "Y ~ 1 | f1", - "Y ~ 1 | f1 + f2", - "Y ~ 0 | f1", - "Y ~ 0 | f1 + f2", + ("Y ~ 1 | f1"), + ("Y ~ 1 | f1 + f2"), + ("Y ~ 0 | f1"), + ("Y ~ 0 | f1 + f2"), ] ols_but_not_poisson_fml = [ From dd1a56de524a35f280bdfc906f8f80a6947222db Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Sat, 31 Aug 2024 15:28:50 +0200 Subject: [PATCH 09/11] fix resid for weights --- pyfixest/estimation/feols_.py | 2 +- tests/test_vs_fixest.py | 60 +++++++++++++++++++++-------------- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/pyfixest/estimation/feols_.py b/pyfixest/estimation/feols_.py index fdec124c..5875817c 100644 --- a/pyfixest/estimation/feols_.py +++ b/pyfixest/estimation/feols_.py @@ -1803,7 +1803,7 @@ def resid(self) -> np.ndarray: np.ndarray A np.ndarray with the residuals of the estimated regression model. """ - return self._u_hat.flatten() + return self._u_hat.flatten() / np.sqrt(self._weights).flatten() def ritest( self, diff --git a/tests/test_vs_fixest.py b/tests/test_vs_fixest.py index 35b4ec5f..3c672f55 100644 --- a/tests/test_vs_fixest.py +++ b/tests/test_vs_fixest.py @@ -74,11 +74,6 @@ # ("Y ~ X1/X2"), # currently does not work as X1/X2 translation not implemented # noqa: W505 # ("Y ~ X1/X2 | f1+f2"), # currently does not work as X1/X2 translation not implemented # noqa: W505 ("Y ~ X1 + poly(X2, 2) | f1"), - # empty models - ("Y ~ 1 | f1"), - ("Y ~ 1 | f1 + f2"), - ("Y ~ 0 | f1"), - ("Y ~ 0 | f1 + f2"), ] ols_but_not_poisson_fml = [ @@ -86,6 +81,11 @@ ("Y~X1|f2^f3"), ("Y~X1|f1 + f2^f3"), ("Y~X1|f2^f3^f1"), + # empty models + ("Y ~ 1 | f1"), + ("Y ~ 1 | f1 + f2"), + ("Y ~ 0 | f1"), + ("Y ~ 0 | f1 + f2"), ] iv_fmls = [ @@ -127,8 +127,8 @@ def check_absolute_diff(x1, x2, tol, msg=None): @pytest.mark.parametrize("error_type", ["2"]) @pytest.mark.parametrize("dropna", [False]) @pytest.mark.parametrize("inference", ["iid", "hetero", {"CRV1": "group_id"}]) -# @pytest.mark.parametrize("inference", ["iid", {"CRV1": "group_id"}]) -@pytest.mark.parametrize("weights", [None, "weights"]) +# @pytest.mark.parametrize("weights", [None, "weights"]) +@pytest.mark.parametrize("weights", ["weights"]) @pytest.mark.parametrize("f3_type", ["str", "object", "int", "categorical", "float"]) @pytest.mark.parametrize("fml", ols_fmls + ols_but_not_poisson_fml) @pytest.mark.parametrize("adj", [False, True]) @@ -200,7 +200,7 @@ def test_single_fit_feols( py_nobs = mod._N py_vcov = mod._vcov[0, 0] py_resid = mod.resid() - # TODO: test residuals + py_predict = mod.predict() df_X1 = _get_r_df(r_fixest) @@ -210,8 +210,9 @@ def test_single_fit_feols( r_tstat = df_X1["statistic"] r_confint = df_X1[["conf.low", "conf.high"]].values.astype(np.float64) r_nobs = int(stats.nobs(r_fixest)[0]) - r_resid = stats.residuals(r_fixest) r_vcov = stats.vcov(r_fixest)[0, 0] + r_resid = stats.residuals(r_fixest) + r_predict = stats.predict(r_fixest) if not mod._X_is_empty: if inference == "iid" and adj and cluster_adj: @@ -225,8 +226,11 @@ def test_single_fit_feols( check_absolute_diff(py_confint, r_confint, 1e-08, "py_confint != r_confint") # residuals invariant so to vcov type - if inference == "iid" and adj and cluster_adj: - check_absolute_diff(py_resid[0:5], r_resid[0:5], 1e-08, "py_resid != r_resid") + if inference == "iid" and adj and not cluster_adj: + check_absolute_diff(py_resid[0:5], r_resid[0:5], 1e-07, "py_resid != r_resid") + check_absolute_diff( + py_predict[0:5], r_predict[0:5], 1e-07, "py_resid != r_resid" + ) if mod._X_is_empty: assert mod._beta_hat.size == 0 @@ -307,9 +311,8 @@ def test_single_fit_fepois( py_nobs = mod._N py_vcov = mod._vcov[0, 0] py_deviance = mod.deviance - - py_resid = mod._u_hat.flatten() # noqa: F841 - # TODO: test residuals + py_resid = mod.resid() + py_predict = mod.predict() df_X1 = _get_r_df(r_fixest) @@ -319,12 +322,19 @@ def test_single_fit_fepois( r_tstat = df_X1["statistic"] r_confint = df_X1[["conf.low", "conf.high"]].values.astype(np.float64) r_nobs = int(stats.nobs(r_fixest)[0]) - r_resid = r_fixest.rx2("working_residuals") # noqa: F841 + r_resid = stats.residuals(r_fixest) + r_predict = stats.predict(r_fixest) r_vcov = stats.vcov(r_fixest)[0, 0] r_deviance = r_fixest.rx2("deviance") - check_absolute_diff(py_nobs, r_nobs, 1e-08, "py_nobs != r_nobs") - check_absolute_diff(py_coef, r_coef, 1e-08, "py_coef != r_coef") + if inference == "iid" and adj and cluster_adj: + check_absolute_diff(py_nobs, r_nobs, 1e-08, "py_nobs != r_nobs") + check_absolute_diff(py_coef, r_coef, 1e-08, "py_coef != r_coef") + check_absolute_diff(py_resid[0:5], r_resid[0:5], 1e-07, "py_resid != r_resid") + check_absolute_diff( + py_predict[0:5], r_predict[0:5], 1e-07, "py_resid != r_resid" + ) + check_absolute_diff(py_vcov, r_vcov, 1e-06, "py_vcov != r_vcov") check_absolute_diff(py_se, r_se, 1e-06, "py_se != r_se") check_absolute_diff(py_pval, r_pval, 1e-06, "py_pval != r_pval") @@ -409,9 +419,8 @@ def test_single_fit_iv( py_confint = mod.confint().xs("X1").values py_nobs = mod._N py_vcov = mod._vcov[0, 0] - - py_resid = mod._u_hat.flatten() # noqa: F841 - # TODO: test residuals + py_resid = mod.resid() + py_predict = mod.predict() df_X1 = _get_r_df(r_fixest) @@ -421,11 +430,16 @@ def test_single_fit_iv( r_tstat = df_X1["statistic"] r_confint = df_X1[["conf.low", "conf.high"]].values.astype(np.float64) r_nobs = int(stats.nobs(r_fixest)[0]) - r_resid = r_fixest.rx2("working_residuals") # noqa: F841 + r_resid = stats.resid(r_fixest) + r_predict = stats.predict(r_fixest) r_vcov = stats.vcov(r_fixest)[0, 0] - check_absolute_diff(py_nobs, r_nobs, 1e-08, "py_nobs != r_nobs") - check_absolute_diff(py_coef, r_coef, 1e-08, "py_coef != r_coef") + if inference == "iid" and adj and cluster_adj: + check_absolute_diff(py_nobs, r_nobs, 1e-08, "py_nobs != r_nobs") + check_absolute_diff(py_coef, r_coef, 1e-08, "py_coef != r_coef") + check_absolute_diff(py_resid[0:5], r_resid[0:5], 1e-07, "py_coef != r_coef") + check_absolute_diff(py_predict[0:5], r_predict[0:5], 1e-07, "py_coef != r_coef") + check_absolute_diff(py_vcov, r_vcov, 1e-07, "py_vcov != r_vcov") check_absolute_diff(py_se, r_se, 1e-07, "py_se != r_se") check_absolute_diff(py_pval, r_pval, 1e-06, "py_pval != r_pval") From c28f64667cd436004f11ce07919e2b1c4374bbf5 Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Sat, 31 Aug 2024 15:54:53 +0200 Subject: [PATCH 10/11] only test predict when fepois without fixef --- tests/test_vs_fixest.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/test_vs_fixest.py b/tests/test_vs_fixest.py index 3c672f55..69221fc5 100644 --- a/tests/test_vs_fixest.py +++ b/tests/test_vs_fixest.py @@ -312,7 +312,6 @@ def test_single_fit_fepois( py_vcov = mod._vcov[0, 0] py_deviance = mod.deviance py_resid = mod.resid() - py_predict = mod.predict() df_X1 = _get_r_df(r_fixest) @@ -323,7 +322,6 @@ def test_single_fit_fepois( r_confint = df_X1[["conf.low", "conf.high"]].values.astype(np.float64) r_nobs = int(stats.nobs(r_fixest)[0]) r_resid = stats.residuals(r_fixest) - r_predict = stats.predict(r_fixest) r_vcov = stats.vcov(r_fixest)[0, 0] r_deviance = r_fixest.rx2("deviance") @@ -331,9 +329,6 @@ def test_single_fit_fepois( check_absolute_diff(py_nobs, r_nobs, 1e-08, "py_nobs != r_nobs") check_absolute_diff(py_coef, r_coef, 1e-08, "py_coef != r_coef") check_absolute_diff(py_resid[0:5], r_resid[0:5], 1e-07, "py_resid != r_resid") - check_absolute_diff( - py_predict[0:5], r_predict[0:5], 1e-07, "py_resid != r_resid" - ) check_absolute_diff(py_vcov, r_vcov, 1e-06, "py_vcov != r_vcov") check_absolute_diff(py_se, r_se, 1e-06, "py_se != r_se") @@ -342,6 +337,13 @@ def test_single_fit_fepois( check_absolute_diff(py_confint, r_confint, 1e-06, "py_confint != r_confint") check_absolute_diff(py_deviance, r_deviance, 1e-08, "py_deviance != r_deviance") + if not mod._has_fixef: + py_predict = mod.predict() + r_predict = stats.predict(r_fixest) + check_absolute_diff( + py_predict[0:5], r_predict[0:5], 1e-07, "py_predict != r_predict" + ) + @pytest.mark.parametrize("N", [1000]) @pytest.mark.parametrize("seed", [76540251]) From 8a12414a4b13222f3c6334bcb4e03aa1eeeedce8 Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Sat, 31 Aug 2024 16:58:43 +0200 Subject: [PATCH 11/11] fix bug in predict method with WLS --- pyfixest/estimation/feols_.py | 2 +- tests/test_vs_fixest.py | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pyfixest/estimation/feols_.py b/pyfixest/estimation/feols_.py index 5875817c..72347de2 100644 --- a/pyfixest/estimation/feols_.py +++ b/pyfixest/estimation/feols_.py @@ -1465,7 +1465,7 @@ def predict( ) if newdata is None: - return self._Y_untransformed.to_numpy().flatten() - self._u_hat.flatten() + return self._Y_untransformed.to_numpy().flatten() - self.resid() newdata = _polars_to_pandas(newdata).reset_index(drop=False) diff --git a/tests/test_vs_fixest.py b/tests/test_vs_fixest.py index 69221fc5..1a3b7fd5 100644 --- a/tests/test_vs_fixest.py +++ b/tests/test_vs_fixest.py @@ -127,8 +127,7 @@ def check_absolute_diff(x1, x2, tol, msg=None): @pytest.mark.parametrize("error_type", ["2"]) @pytest.mark.parametrize("dropna", [False]) @pytest.mark.parametrize("inference", ["iid", "hetero", {"CRV1": "group_id"}]) -# @pytest.mark.parametrize("weights", [None, "weights"]) -@pytest.mark.parametrize("weights", ["weights"]) +@pytest.mark.parametrize("weights", [None, "weights"]) @pytest.mark.parametrize("f3_type", ["str", "object", "int", "categorical", "float"]) @pytest.mark.parametrize("fml", ols_fmls + ols_but_not_poisson_fml) @pytest.mark.parametrize("adj", [False, True]) @@ -227,9 +226,11 @@ def test_single_fit_feols( # residuals invariant so to vcov type if inference == "iid" and adj and not cluster_adj: - check_absolute_diff(py_resid[0:5], r_resid[0:5], 1e-07, "py_resid != r_resid") check_absolute_diff( - py_predict[0:5], r_predict[0:5], 1e-07, "py_resid != r_resid" + (py_resid)[0:5], (r_resid)[0:5], 1e-07, "py_resid != r_resid" + ) + check_absolute_diff( + py_predict[0:5], r_predict[0:5], 1e-07, "py_predict != r_predict" ) if mod._X_is_empty: @@ -328,7 +329,7 @@ def test_single_fit_fepois( if inference == "iid" and adj and cluster_adj: check_absolute_diff(py_nobs, r_nobs, 1e-08, "py_nobs != r_nobs") check_absolute_diff(py_coef, r_coef, 1e-08, "py_coef != r_coef") - check_absolute_diff(py_resid[0:5], r_resid[0:5], 1e-07, "py_resid != r_resid") + check_absolute_diff((py_resid)[0:5], (r_resid)[0:5], 1e-07, "py_coef != r_coef") check_absolute_diff(py_vcov, r_vcov, 1e-06, "py_vcov != r_vcov") check_absolute_diff(py_se, r_se, 1e-06, "py_se != r_se") @@ -439,8 +440,8 @@ def test_single_fit_iv( if inference == "iid" and adj and cluster_adj: check_absolute_diff(py_nobs, r_nobs, 1e-08, "py_nobs != r_nobs") check_absolute_diff(py_coef, r_coef, 1e-08, "py_coef != r_coef") - check_absolute_diff(py_resid[0:5], r_resid[0:5], 1e-07, "py_coef != r_coef") check_absolute_diff(py_predict[0:5], r_predict[0:5], 1e-07, "py_coef != r_coef") + check_absolute_diff((py_resid)[0:5], (r_resid)[0:5], 1e-07, "py_coef != r_coef") check_absolute_diff(py_vcov, r_vcov, 1e-07, "py_vcov != r_vcov") check_absolute_diff(py_se, r_se, 1e-07, "py_se != r_se")