[Repo Assist] perf(gcm): vectorise _remove_constant_columns and optimise cross-covariance in kernel independence test - #1780
Open
github-actions[bot] wants to merge 1 commit into
Conversation
…riance in kernel independence test _remove_constant_columns previously called np.unique once per column (O(p * n log n) total). Replace with a vectorised comparison against the first row: np.all(X == X[0], axis=0) is O(n * p) and avoids the sort step entirely. _estimate_column_wise_covariances previously called np.cov(X, Y) which builds the full (dx+dy) × (dx+dy) covariance matrix even though only the dx × dy cross-covariance block is needed. Replacing it with the direct formula X_c.T @ Y_c / (n-1) cuts the computation from O(n*(dx+dy)^2) to O(n*dx*dy). For the default num_random_features=50 this is a ~4× speedup per call. The result is numerically identical. Both functions are called inside every RIT/RCIT permutation iteration (typically 100 iterations per independence test), so the saving compounds. All 22 existing kernel independence-test unit tests pass unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Optimizes hot paths in GCM kernel independence tests.
Changes:
- Vectorizes constant-column detection.
- Computes cross-covariance directly.
- Adds empty-input handling.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+394
to
+395
| if X.shape[0] == 0: | ||
| return X |
Comment on lines
+374
to
+376
| X_c = X - X.mean(axis=0) | ||
| Y_c = Y - Y.mean(axis=0) | ||
| return X_c.T @ Y_c / (n - 1) |
32 tasks
This branch has not been deployed
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.
🤖 This PR was created by Repo Assist, an automated AI assistant.
Summary
Two complementary performance improvements to
dowhy/gcm/independence_test/kernel.py, both on the hot path of everyapprox_kernel_basedandkernel_basedindependence test call.1. Vectorise
_remove_constant_columnsBefore – per-column
np.uniqueloop: O(p · n log n)After – single vectorised comparison: O(p · n)
np.all(X == X[0], axis=0)compares all rows against the first row simultaneously in one NumPy broadcast, avoiding the per-column sort insidenp.unique. The semantics are identical for all valid inputs (NaN values are rejected downstream at the existing check on line 88–89, so the NaN/NaN inequality edge case never reaches this function in practice)._remove_constant_columnsis called 2–3 times per independence test invocation; with large feature matrices the savings compound.2. Optimise
_estimate_column_wise_covariancesBefore – full
(dx+dy) × (dx+dy)covariance vianp.cov: O(n·(dx+dy)2)np.cov(X, Y)stacks both matrices and computes the complete(dx+dy)-square covariance matrix, then discards the auto-covariance blocks and returns only the(dx, dy)cross-covariance slice.After – direct cross-covariance: O(n·dx·dy)
All 22 existing kernel independence-test unit tests (categorical, continuous, conditional, unconditional, determinism, constant-column edge cases) pass unchanged.
Format check:
black– no changes needed;isort– no changes needed.Lint:
flake8– no new errors introduced (pre-existing E501 in docstrings at lines 32–41 are unchanged).