Skip to content

Commit 18ff8a4

Browse files
committed
updated plan
1 parent 34f377a commit 18ff8a4

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<!-- a86255fd-e559-425e-82e2-e2ad35c50047 f5adc961-97fa-4a2f-b1f7-c67734af5cd0 -->
2+
# Add Fixed Effects Support to feglm (Gaussian Family)
3+
4+
## Current State
5+
6+
The `Feglm` class currently raises `NotImplementedError` at line 99-100 when fixed effects are present. Additionally, `Feglm` hardcodes the numba demeaning backend instead of using the configurable backend system that `feols` uses.
7+
8+
**Key differences from feols:**
9+
10+
- `Feglm` imports `demean` directly from `demean_.py` (line 11) - this is the numba backend
11+
- `Feglm` calls this hardcoded `demean` function in `residualize()` (line 317)
12+
- `Feols` uses a `demeaner_backend` parameter and selects the demean function from the `BACKENDS` dictionary
13+
- `Fepois` tries to pass `demeaner_backend` to `Feglm.__init__`, but `Feglm` doesn't accept it
14+
15+
## Implementation Steps
16+
17+
### 1. Update Feglm to Use Backend Infrastructure
18+
19+
Modify `pyfixest/estimation/feglm_.py`:
20+
21+
**a) Update imports** (line 11):
22+
23+
- Remove: `from pyfixest.estimation.demean_ import demean`
24+
- Add: `from pyfixest.estimation.backends import BACKENDS`
25+
- Add: `from pyfixest.estimation.literals import DemeanerBackendOptions`
26+
27+
**b) Add `demeaner_backend` parameter to `__init__`** (line 21):
28+
29+
- Add `demeaner_backend: DemeanerBackendOptions = "numba"` parameter
30+
- Store as `self._demeaner_backend = demeaner_backend`
31+
- Set `self._demean_func = BACKENDS[demeaner_backend]["demean"]` (similar to how `Feols` does it at line 323-327 of `feols_.py`)
32+
33+
**c) Update `residualize()` method** (line 317):
34+
35+
- Replace `demean(...)` with `self._demean_func(...)`
36+
37+
### 2. Remove Fixed Effects Restriction
38+
39+
In `pyfixest/estimation/feglm_.py`:
40+
41+
- Delete lines 99-100 that raise `NotImplementedError` for fixed effects
42+
43+
### 3. Update Fegaussian Constructor
44+
45+
Modify `pyfixest/estimation/fegaussian_.py`:
46+
47+
- Add `demeaner_backend: DemeanerBackendOptions = "numba"` parameter to `__init__` (around line 29)
48+
- Pass it to the parent `Feglm.__init__` call
49+
50+
### 4. Test the Implementation
51+
52+
**a) Enable skipped test in `test_feols_feglm_internally.py`:**
53+
54+
- Remove the `@pytest.mark.skip` decorator on line 60
55+
56+
**b) Add R comparison tests in `test_vs_fixest.py`:**
57+
58+
- Test formulas: `"Y ~ X1 | f1"`, `"Y ~ X1 | f1 + f2"`, `"Y ~ X1 + X2 | f2"`
59+
- Compare: coefficients, standard errors, residuals against R's `fixest::feglm(family="gaussian")`
60+
61+
### 5. Validation
62+
63+
Ensure the implementation correctly handles:
64+
65+
- Backend selection (numba, rust, jax) works correctly
66+
- Single and multiple fixed effects
67+
- Proper weight handling in demeaning at each IRLS iteration
68+
- Convergence (should still converge in 1 iteration for Gaussian)
69+
70+
## Key Files to Modify
71+
72+
- `pyfixest/estimation/feglm_.py` (add backend infrastructure, remove restriction)
73+
- `pyfixest/estimation/fegaussian_.py` (pass demeaner_backend parameter)
74+
- `tests/test_feols_feglm_internally.py` (enable skipped test)
75+
- `tests/test_vs_fixest.py` (add R comparison tests)
76+
77+
## Expected Behavior
78+
79+
After implementation:
80+
81+
1. Users can specify `demeaner_backend` for `feglm`, just like with `feols`
82+
2. `pf.feglm(fml="Y ~ X1 | f1", family="gaussian", demeaner_backend="rust")` works with any backend
83+
3. Results match R's `fixest::feglm()` with Gaussian family
84+
4. For Gaussian family, effectively matches `feols()` results (with appropriate inference adjustments)
85+
86+
### To-dos
87+
88+
- [ ] Update imports in feglm_.py to use BACKENDS and DemeanerBackendOptions
89+
- [ ] Add demeaner_backend parameter to Feglm.__init__ and set self._demean_func
90+
- [ ] Update residualize() method to use self._demean_func instead of hardcoded demean
91+
- [ ] Remove NotImplementedError for fixed effects in feglm_.py
92+
- [ ] Add demeaner_backend parameter to Fegaussian.__init__ and pass to parent
93+
- [ ] Remove @pytest.mark.skip decorator from test in test_feols_feglm_internally.py
94+
- [ ] Add R comparison tests to test_vs_fixest.py
95+
- [ ] Run tests and validate against R fixest results

0 commit comments

Comments
 (0)