Give White's test statistical power, reject non-square games, make the dependency pins effective under npm - #7
Open
shehio wants to merge 1 commit into
Open
Conversation
White's test regressed the raw residuals on the fitted values, but OLS residuals are orthogonal to the fitted values by construction, so the auxiliary regression had nothing to find whatever the error variance did. It now regresses the SQUARED residuals and returns the standard Lagrange multiplier LM = n * R^2 rather than an F built with the wrong degrees of freedom (p = 2 for a three-parameter regression). On a 200-point sample the old statistic scored 0.7286 with constant error variance and 0.1450 when the variance grew with x - the heteroskedastic sample scored lower, and neither came near the 3.889 critical value. The corrected statistic gives 2.7130 and 19.4002 against a chi-squared(2) critical value of 5.991. Neither econometrics module could be loaded at all: both required './../data/index.js', a path that does not exist, and white.js exported nothing. The require now points at src/economic-data and sits inside quick_test, since that module issues an HTTP request when it is loaded. solve() silently dropped player two's extra probabilities on a 2 x 3 game and failed inside normalization on a 3 x 2 one, because find_equilibrium zips the two probability vectors with a.map. Non-square games are now rejected up front. package.json pinned transitive dependencies under 'resolutions', which npm ignores. Resolving the manifest with npm and no lockfile leaves tough-cookie at 2.5.0, tmp at 0.0.33, flatted at 2.0.2 and a nested braces 2.3.2; under 'overrides' every pin takes effect. Both keys are kept because the committed yarn.lock is currently what makes the pins hold.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three unrelated but individually small correctness fixes, all in code the test suite never executed. Two of the three modules could not even be
required.White's Test Had No Statistical Power
The auxiliary regression used the raw residuals as its dependent variable:
White's test has to explain the variance of the errors, so the dependent variable must be
û². Regressingûitself can never work: OLS residuals are orthogonal to the fitted values by construction, so the slope is zero whether the errors are homoskedastic or not.Measured on two 200-point samples (
y = 2 + 3x + s(x)·e, seeded so the numbers are reproducible):xF(1, 198)χ²(2)The old statistic scored lower on the heteroskedastic sample than on the homoskedastic one, and never came close to rejecting either. Across 400 replications it rejected 0% of the time in both cases; the corrected statistic has 4.5% size and 100% power on this design.
The returned statistic is now the standard Lagrange multiplier
LM = n·R², distributedχ²(2)here. The previous F was also built with the wrong degrees of freedom —p = 2for a three-parameter regression, givingDFM = 1instead of 2.Neither Econometrics Module Could Be Loaded
Both
econometrics/index.jsandeconometrics/white.jsopened withrequire('./../data/index.js'). There is nodata/directory — the module lives atsrc/economic-data/:white.jsalso exported nothing. The require now points at the right path and sits insidequick_test, its only consumer, becausesrc/economic-data/index.jsissues a WorldBank HTTP request at module load — importing it at the top would put a network call in the test suite.Lemke-Howson Silently Mishandles Non-Square Games
find_equilibriumzips player one's probabilities with player two's usinga.map(...), which is bounded by player one's strategy count. I swept 300 random games at each shape from 2×2 to 4×4:A 2×3 game returns a two-element mixed strategy for a player who has three strategies — plausible-looking and wrong. A 3×2 game fails deep inside normalization with
Matrix has probabilities that are not numbers, which points nowhere near the cause.solve()now rejects non-square input up front with a message that names both counts.Note: the reported symptom for this one was
NaN. That did not reproduce — 0 of 2700 random games producedNaNon any shape. The defect is real but the failure mode is silent truncation, notNaN.The Dependency Pins Are Not Effective Under npm
package.jsonpins nine transitive dependencies underresolutions, which is a Yarn key; npm readsoverrides. Resolving the manifest with npm and no lockfile:resolutionsoverridestough-cookie^4.1.3tmp^0.2.6flatted^3.4.2braces^3.0.3qs^6.14.2With
resolutionsthe result is byte-identical to having no pins at all.One correction worth stating: the pins are not currently inert in CI. The repo commits a
yarn.lockthat Yarn generated while honouringresolutions, and npm imports it, so a fresh CI checkout does get the safe versions today. The pins hold only because that lockfile is there — they contribute nothing on their own, and would stop holding the momentyarn.lockis dropped, regenerated by npm, or misses a newly added transitive dependency.overridesis therefore added, mirroringresolutions. Both keys are kept:yarn.lockis still committed and still load-bearing, so removingresolutionsnow would be a regression for anyone running Yarn. Ifyarn.lockis ever dropped, dropresolutionswith it — two lists that can drift apart is not a good resting state.Tests
econometrics/test/white.test.tsis new and is the first test to reach the econometrics package at all; it pins the size and the power of the statistic with a seeded generator. One case was added to the Lemke-Howson suite for non-square input.Suite: 34 tests / 10 suites before → 37 tests / 11 suites after, all passing.
Left Alone
.github/workflows/— there is an open PR against it.🤖 Generated with Claude Code
https://claude.ai/code/session_01THEv7BFJd31NjvBRehbZPL