Skip to content

Add IVCSCArray/IVCSRArray with a normalized view (#5) - #6

Open
aarmey wants to merge 1 commit into
mainfrom
ivcsc-ivcsr-types
Open

Add IVCSCArray/IVCSRArray with a normalized view (#5)#6
aarmey wants to merge 1 commit into
mainfrom
ivcsc-ivcsr-types

Conversation

@aarmey

@aarmey aarmey commented Aug 23, 2026

Copy link
Copy Markdown
Member

Summary

Implements #5: an alternative to rapid_load where IVCSR/IVCSC data loaded into memory stays in its packed form instead of being decoded/normalized.

  • IVCSCArray/IVCSRArray (_ivcs.py): keep the minor-axis indices byte-packed (delta+varint, as on disk) in memory. Support indexing/subsetting (result stays packed) and per-axis read sums (sum(axis=0|1) — major-axis sums never decode indices, minor-axis sums decode once and cache). Matrix products, elementwise arithmetic, and ufuncs raise RuntimeError for now.
  • VCSCAnnData now accepts either the existing VCS types or the new IVCS types for X/raw_X, and gained a real (eager-copy) __getitem__ supporting the usual label/int/slice/boolean indexing.
  • load_packed(): reads an on-disk IVCSR/IVCSC .h5ad straight into a VCSCAnnData with X as a packed IVCSCArray/IVCSRArray — no filtering, no normalization, no decode. IO round-trip (read + write) is also registered for the new types via the standard write_h5ad/write_zarr/read_h5ad/read_zarr path.
  • IVCSCArrayNormalized/IVCSRArrayNormalized (_ivcs_norm.py, via .normalized()): a read-depth-normalized, log-transformed, mean-centered view that never materializes the (necessarily dense, once centered) result. Only three small per-row/per-column statistics are precomputed (via parallel numba kernels specialized per storage format); .toarray() and elementwise access apply the transform on the fly from those stats plus the raw packed data.

Test plan

  • pytest -q — 891 passed, 38 skipped
  • ruff check src tests — clean
  • ty check src — clean
  • Manually verified IVCSCArrayNormalized/IVCSRArrayNormalized against a from-scratch numpy reference implementation of the depth-normalize/log-transform/mean-center pipeline, for both storage formats and edge cases (all-zero matrix, zero-count rows, boolean/int slicing).

🤖 Generated with Claude Code

https://claude.ai/code/session_01PswzuSVAmYkh5yNbSMHAnz

…lized view

Implements GH issue #5: an alternative to rapid_load that keeps IVCSR/IVCSC
data byte-packed in memory instead of decoding it. IVCSCArray/IVCSRArray
support indexing/subsetting (staying packed) and per-axis read sums (major-axis
sums skip decoding entirely); anything else (matmul, elementwise arithmetic,
ufuncs) raises RuntimeError. VCSCAnnData now accepts either array family for
X/raw_X and gained real (eager) indexing/view support. load_packed() loads an
on-disk IVCSR/IVCSC .h5ad straight into this packed form, with IO round-trip
support registered for both storage formats.

Also adds IVCSCArrayNormalized/IVCSRArrayNormalized: a read-depth-normalized,
log-transformed, mean-centered view over these arrays that never materializes
the (necessarily dense, once centered) result. Only three O(n_rows)/O(n_cols)
statistics are precomputed, via parallel numba kernels specialized per storage
format; toarray() and elementwise access apply the transform on demand from
those stats plus the raw packed data.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PswzuSVAmYkh5yNbSMHAnz
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.

1 participant