Skip to content

Add Common and Individual Feature Extraction Transformers AJIVE and CIFE for Multiblock Data - #20

Open
shuo-zhou wants to merge 4 commits into
mainfrom
cife-jive
Open

Add Common and Individual Feature Extraction Transformers AJIVE and CIFE for Multiblock Data #20
shuo-zhou wants to merge 4 commits into
mainfrom
cife-jive

Conversation

@shuo-zhou

Copy link
Copy Markdown
Member

Description

Add two new algorithms, AJIVE and CIFE, under the transformer API

Status

Work in progress

Types of changes

  • Non-breaking change (fix or new feature that would not break existing functionality).
  • Breaking change (fix or new feature that would cause existing functionality to change).
  • New tests added to cover the changes.
  • In-line docstrings updated and documentation docs updated.

@codecov

codecovBot commented Aug 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.27027% with 36 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.00%. Comparing base (b3c9360) to head (5096296).

Files with missing linesPatch %Lines
kalelinear/transformer/_multiblock.py81.63%18 Missing ⚠️
kalelinear/transformer/_ajive.py92.70%10 Missing ⚠️
kalelinear/transformer/_cife.py93.89%8 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #20 +/- ##
==========================================
+ Coverage 88.71% 89.00% +0.29% 
==========================================
Files 21 24 +3 Lines 1506 1874 +368 ==========================================
+ Hits 1336 1668 +332 - Misses 170 206 +36 

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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 two new multiblock feature transformers—CIFE and AJIVE—to the kalelinear.transformer API, along with tests and documentation updates so they can be used via both kalelinear.transformer and the PyKale-style kalelinear.embed module.

Changes:

  • Implement CIFE and AJIVE, plus a shared multiblock base/validation layer.
  • Add unit tests and shared synthetic multiblock dataset generator for validating common/individual subspace recovery.
  • Update README, tutorials, and Sphinx API docs to surface the new transformers.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
TUTORIALS.mdAdds a usage example for CIFE/AJIVE common + individual feature extraction.
README.mdLists CIFE/AJIVE as supported transformers and adds citations.
tests/utils/test_utils.pyAdds a synthetic multiblock dataset generator for common/individual structure.
tests/transformer/test_cife.pyAdds test coverage for CIFE fit/transform behavior and validation.
tests/transformer/test_ajive.pyAdds test coverage for AJIVE fit/transform behavior and validation.
tests/test_public_api.pyEnsures new transformers are exposed via the public API modules.
kalelinear/transformer/_multiblock.pyIntroduces shared multiblock input handling and a base transformer class.
kalelinear/transformer/_cife.pyImplements the CIFE algorithm and its COBE-based common subspace extraction.
kalelinear/transformer/_ajive.pyImplements the AJIVE algorithm including Wedin-bound based rank selection.
kalelinear/transformer/init.pyExposes CIFE and AJIVE in the transformer package namespace.
kalelinear/embed.pyExposes CIFE and AJIVE via the PyKale-style embed module.
docs/source/introduction.rstUpdates the “Main Features” list to include CIFE/AJIVE.
docs/source/api_transformers.rstAdds API doc entries for CIFE and AJIVE.
docs/source/api_embed.rstAdds API doc entries for CIFE and AJIVE under kalelinear.embed.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threadkalelinear/transformer/_multiblock.py
Comment threadkalelinear/transformer/_multiblock.py
Comment threadkalelinear/transformer/_multiblock.py
Comment threadkalelinear/transformer/_ajive.py

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

Suppressed comments (3)

Previously missed (3) — in code that hasn't changed since the last review.

kalelinear/transformer/_multiblock.py:167

  • transform() uses _check_multiblock_input(X) for list/tuple inputs, which enforces a minimum of two blocks. This prevents projecting a single new block at transform-time even though the common projection does not require multiple blocks (and the docstring suggests any “list of blocks” is acceptable). Consider validating list inputs here without the “>= 2 blocks” constraint, and just stack the blocks for projection.
 if isinstance(X, (list, tuple)):
blocks, _ = _check_multiblock_input(X)
X_stacked = np.vstack(blocks)

kalelinear/transformer/_ajive.py:208

  • percentile is a configurable parameter, but the branch choosing between random_ssv_bound and the Wedin-based bound compares against a hard-coded 5th percentile (np.percentile(wedin_ssv_bounds, 5)). This makes behavior inconsistent when percentile is not 5 and likely ignores the user-configured setting.
 wedin_ssv_bound = np.percentile(wedin_ssv_bounds, self.percentile)
random_ssvs = _random_direction_ssv(D, ranks, 100, self.random_state_)
random_ssv_bound = np.percentile(random_ssvs, 95)
if random_ssv_bound > np.percentile(wedin_ssv_bounds, 5):
joint_rank = int(np.sum(s_stacked**2 + _FERROR > random_ssv_bound))

tests/utils/test_utils.py:133

  • make_common_individual_dataset is parameterized by n_blocks, but it indexes individual_ranks[k] / n_samples[k] without validating their lengths. Calling it with a different n_blocks than the default will raise an IndexError instead of a clear error message.
 for k in range(n_blocks):
individual_basis, _ = np.linalg.qr(random_state.randn(n_features, individual_ranks[k]))
individual_basis -= common_basis @ (common_basis.T @ individual_basis)
individual_basis, _ = np.linalg.qr(individual_basis)
block = random_state.randn(n_samples[k], n_common) @ common_basis.T

@shuo-zhoushuo-zhou changed the title Add AJIVE and CIFEAdd Common and Individual Feature Extraction Transformers AJIVE and CIFE for Multiblock Data Aug 25, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.

Comment threaddocs/source/index.rst
Comment on lines 17 to 22
.. toctree::
:maxdepth: 2

api_embed
api_transformers
api_predict
api_estimators
api_utilities

Comment threadkalelinear/transformer/_multiblock.py Outdated
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@shuo-zhou