Skip to content

feat: remove _ewm_corr.py and migrate all consumers to cvx.linalg.ewm_covariance#533

Open
tschm wants to merge 6 commits into
mainfrom
corr
Open

feat: remove _ewm_corr.py and migrate all consumers to cvx.linalg.ewm_covariance#533
tschm wants to merge 6 commits into
mainfrom
corr

Conversation

@tschm
Copy link
Copy Markdown
Member

@tschm tschm commented May 18, 2026

Summary

  • Deletes src/basanos/math/_ewm_corr.py (hand-rolled EWM correlation) and all associated tests/notebook
  • Replaces all consumers (optimizer.py, _stream.py, _engine_solve.py) with cvx.linalg.ewm_covariance, which matches pandas.ewm(span).cov(bias=True) to 1e-10
  • Bumps _SAVE_FORMAT_VERSION to 3 (incompatible _StreamState schema: 5 IIR fields → single corr_ret_buf buffer)
  • Adds tests/test_math/test_ewm_covariance.py verifying numerical agreement with pandas on dense and sparse data

Test plan

  • pytest tests/test_math/test_ewm_covariance.py — dense exact match, sparse superset-NaN + value match
  • Full suite passes (752 tests, 0 failures)

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings May 18, 2026 13:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new test module validating cvx.linalg.ewm_covariance against both pandas’ EWM covariance and Basanos’ existing ewm_corr, and simultaneously migrates Basanos’ linear-algebra helpers/exceptions from internal implementations to the external cvx-linalg package.

Changes:

  • Add tests/test_math/test_ewm_covariance.py to compare cvx.linalg.ewm_covariance vs pandas EWM covariance and (dense-only) vs Basanos ewm_corr.
  • Replace internal _linalg usage with cvx.linalg (solve, inv_a_norm, valid, and matrix-related exceptions), and delete src/basanos/math/_linalg.py plus its dedicated test modules.
  • Update packaging to depend on cvx-linalg>=0.5 and adjust dependency constraints.

Reviewed changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
uv.lock Adds cvx-linalg and updates locked metadata/requirements.
pyproject.toml Adds cvx-linalg runtime dependency and updates other dependency minimums; adds deptry module map.
src/basanos/exceptions.py Removes linear-algebra exceptions from Basanos’ exception module and updates docstring guidance.
src/basanos/__init__.py Re-exports selected cvx.linalg exceptions from the top-level basanos namespace.
src/basanos/math/_engine_solve.py Switches solver/norm/error imports from internal _linalg to cvx.linalg.
src/basanos/math/_engine_diagnostics.py Switches valid/solve and SingularMatrixError imports to cvx.linalg.
src/basanos/math/_factor_model.py Switches linalg utilities/exceptions to cvx.linalg.
src/basanos/math/_stream.py Switches SingularMatrixError import to cvx.linalg.
src/basanos/math/_linalg.py Deletes internal linear-algebra helper implementation.
tests/test_math/test_ewm_covariance.py New test suite for ewm_covariance vs pandas and vs Basanos ewm_corr (dense-only).
tests/test_math/test_numerical_stability.py Updates imports to use cvx.linalg for solver/warning/threshold.
tests/test_math/test_factor_model.py Updates imports to use cvx.linalg for exception/warning/threshold.
tests/test_math/test_optimizer.py Updates SingularMatrixError import to cvx.linalg.
tests/test_math/test_optimizer_edge_cases.py Updates SingularMatrixError import to cvx.linalg.
tests/test_math/test_stream.py Updates SingularMatrixError imports to cvx.linalg.
tests/test_math/test_linalg.py Deletes unit tests for the removed internal _linalg module.
tests/test_math/test_linalg_property.py Deletes Hypothesis property tests for the removed internal _linalg module.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/basanos/exceptions.py
Comment on lines 8 to 12

Examples:
>>> raise NonSquareMatrixError(3, 2)
Traceback (most recent call last):
...
basanos.exceptions.NonSquareMatrixError: Matrix must be square, got shape (3, 2).
Linear-algebra exceptions (``NonSquareMatrixError``, ``DimensionMismatchError``,
``SingularMatrixError``, ``IllConditionedMatrixWarning``) are defined in
``cvx.linalg`` and should be imported from there directly.
"""
Comment thread pyproject.toml
Comment on lines 11 to 16
dependencies = [
"jinja2>=3.1",
"jquantstats>=0.2.0",
"cvx-linalg>=0.5",
"jinja2>=3",
"jquantstats>=0.9",
"numpy>=2.4",
"plotly>=6.6.0",
Comment on lines 27 to +31
import numpy as np
import polars as pl
import pytest
from cvx.linalg import IllConditionedMatrixWarning, solve
from cvx.linalg.solve import _DEFAULT_COND_THRESHOLD
Comment on lines +4 to +5
1. ewm_covariance matches pandas.DataFrame.ewm(span).cov(bias=True) to 1e-10
wherever both produce finite values.
Comment on lines +19 to 23
from cvx.linalg import DimensionMismatchError, SingularMatrixError
from cvx.linalg import check_and_warn_condition as _check_and_warn_condition
from cvx.linalg import cholesky_solve as _cholesky_solve
from cvx.linalg.solve import _DEFAULT_COND_THRESHOLD

@tschm tschm changed the title test: verify ewm_covariance against pandas and ewm_corr feat: remove _ewm_corr.py and migrate all consumers to cvx.linalg.ewm_covariance May 20, 2026
tschm and others added 5 commits May 23, 2026 20:48
Add cvx-linalg>=0.4 as a dependency and remove the now-redundant
basanos/math/_linalg.py. All linalg types (SingularMatrixError,
DimensionMismatchError, NonSquareMatrixError, IllConditionedMatrixWarning,
cholesky_solve, is_positive_definite, solve, valid, inv_a_norm) are
imported from cvx.linalg throughout src and tests. Update jquantstats
to >=0.9.1.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add test_ewm_covariance.py documenting that cvx.linalg.ewm_covariance
matches pandas.ewm(span).cov(bias=True) to machine epsilon on dense and
sparse data. Also verifies that normalised covariance matches ewm_corr
exactly on dense inputs, and documents the two known semantic differences
for sparse data: conservative NaN pattern and marginal-vs-joint variance
in the normalisation denominator.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…_covariance

Deletes the hand-rolled ewm_corr implementation and replaces it everywhere
with the cvx-linalg ewm_covariance function, which matches pandas
ewm(span).cov(bias=True) to 1e-10.

- Remove src/basanos/math/_ewm_corr.py and its tests/notebook
- Update _engine_solve.py: WarmupState drops corr_iir_state field
- Update exceptions.py doctest key name (corr_zi_x -> corr_ret_buf)
- Regenerate cor_tensor.npy fixture
- Remove ewm_corr-specific numerical-stability tests (covered by ewm_covariance tests)
- Update test_stream.py for new _StreamState shape (format version 3)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Also adapts to cvx-linalg 0.6.x API: ewm_covariance moved to
cvx.linalg.ewm_cov submodule, cholesky_solve replaced by inv + solve.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Cast corr_ret_buf to ndarray at EWM-only call sites in _stream.py to
  satisfy ty's union narrowing
- Remove extra blank line in exceptions.py (ruff format)
- Remove deleted ewm_benchmark.py from README notebooks table and
  its dead uv run example

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants