Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/normalized hypergraph laplacian #648

Open
wants to merge 28 commits into
base: main
Choose a base branch
from

Conversation

kaiser-dan
Copy link

@kaiser-dan kaiser-dan commented Jan 24, 2025

Summary

Rewrote normalized_hypergraph_laplacian implementation to match reference implementation. Fixes #647 .

Description

Rewrote the matrix calculations in normalized_hypergraph_laplacian to match the implementation referenced here: #647 (comment). Also adds a weighted Boolean parameter to allow for differentially weighting edges in the Laplacian calculation, drawn from each edge's "weight" attribute if available (default to 1 if unavailable).

Concerns

I have only added barebone unit tests for the effect of edge weights (only on their acceptable definition). I am unsure how or what the expected behavior would be for non-uniform edge weights.

Other

Currently only supports strictly positive weights - a weight of zero would cause some issues with rank. That said, an edge weight of 0 could be interpreted as the subgraph with that edge removed and could be a nice way to handle zero weights in the future? Deprecated with latest commit 573eaad.

Fixes the implementation of `normalized_hypergraph_laplacian` to prevent
negative eigenvalues. Rewrites core matrix calculations in full
definition.
Adds a proprty test for eigenvalue sign.
Adds error tests for new `weights` variable.
Updated 'Raises' portion of function docstring to include type and
length error catches on `weights` parameter.
@kaiser-dan kaiser-dan marked this pull request as draft January 26, 2025 16:12
@kaiser-dan kaiser-dan marked this pull request as ready for review January 26, 2025 16:24
Copy link

codecov bot commented Jan 26, 2025

Codecov Report

Attention: Patch coverage is 73.91304% with 6 lines in your changes missing coverage. Please review.

Project coverage is 93.35%. Comparing base (b86da86) to head (4881074).

Files with missing lines Patch % Lines
xgi/linalg/laplacian_matrix.py 73.91% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #648      +/-   ##
==========================================
- Coverage   93.45%   93.35%   -0.11%     
==========================================
  Files          64       64              
  Lines        4993     5008      +15     
==========================================
+ Hits         4666     4675       +9     
- Misses        327      333       +6     

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

@maximelucas
Copy link
Collaborator

Thanks for the PR!

It looks good, I only left a few comments to check that everything is okay in the sparse case, and to simplify a few lines.

About the weights, I'm thinking maybe we want the argument to be boolean instead: weighted=False. When it's True, we could just get the weights from the "weight" attribute of the hyperedges encoded in the hypergraph.
What do you think? Or do you see a case where one would want to use other weights?

That's how we have it for the adjacency matrix now.

@kaiser-dan
Copy link
Author

Thanks for the PR!

It looks good, I only left a few comments to check that everything is okay in the sparse case, and to simplify a few lines.

About the weights, I'm thinking maybe we want the argument to be boolean instead: weighted=False. When it's True, we could just get the weights from the "weight" attribute of the hyperedges encoded in the hypergraph. What do you think? Or do you see a case where one would want to use other weights?

That's how we have it for the adjacency matrix now.

Thanks for the feedback!

I agree, I can't think of any use cases where the weights would want to be different than the edge attributes than cannot also be handled with edge attributes. I can make those adjustments soon. I will also implement your suggestions, thank you!

I will ping this for a rereview when those changes are made.

@kaiser-dan kaiser-dan marked this pull request as draft January 28, 2025 15:38
@kaiser-dan
Copy link
Author

Okie I believe this is ready for re-review. I have addressed most of your comments @maximelucas by directly implementing the suggestions, however, to clarify on the remaining, here are two observations:

  • the np.transpose of a SciPy sparse array is still a sparse array
  • np.sum of a sparse matrix is not sparse, so in the middle of the De calculations a dense array is made, then cast back into a sparse diagonal matrix. This is introducing an additional memory allocation of $\Theta(m)$, where m is the number of hyperedges. These default to 64-bit floats in each entry.

@kaiser-dan kaiser-dan marked this pull request as ready for review January 28, 2025 22:12
@maximelucas
Copy link
Collaborator

Thanks a lot @kaiser-dan!

Just added a few more comments for consistency and simplicity:

  • eye and identity are usually almost equivalent, so better to use only one of them
  • SciPy made the switch a few months ago from sparse matrices to sparse arrays, so we update code to use the latter when we can

After these small changes we should be good to go!

kaiser-dan and others added 17 commits January 29, 2025 10:11
Fix docstring typo

Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>
Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>
Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>
Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>
Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>
Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>
Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>
Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>
Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>
Implement suggestion - Edge weight matrix

Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>
Fix docstring typo

Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>

Update xgi/linalg/laplacian_matrix.py

Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>

Update xgi/linalg/laplacian_matrix.py

Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>

Update xgi/linalg/laplacian_matrix.py

Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>

Update xgi/linalg/laplacian_matrix.py

Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>

Update xgi/linalg/laplacian_matrix.py

Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>

Update xgi/linalg/laplacian_matrix.py

Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>

Update xgi/linalg/laplacian_matrix.py

Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>

Update xgi/linalg/laplacian_matrix.py

Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>
Add the minimum(?) working example of issue xgi-org#647 as new `test_`
function.
Tidied `test_normalized_hypergraph_laplacian` and added L2 and L3
comparison.
…er-dan/xgi into fix/normalized_hypergraph_laplacian
@maximelucas
Copy link
Collaborator

Great, thanks a lot! Thanks for bearing with me :)
I just left a last tiny comment (the diags_array is already a sparse matrix), but approved the PR already.
Once you made the tiny change I'll squash and merge (I don't think you can, but if you can feel free to do it yourself).
Congrats on your first approved PR!

Co-authored-by: Maxime Lucas <maximelucas@users.noreply.github.com>
@kaiser-dan
Copy link
Author

Great, thanks a lot! Thanks for bearing with me :) I just left a last tiny comment (the diags_array is already a sparse matrix), but approved the PR already. Once you made the tiny change I'll squash and merge (I don't think you can, but if you can feel free to do it yourself). Congrats on your first approved PR!

Thank you! It's been fun, I hope to contribute as much as I can moving forward as well.

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.

Bug: Negative eigenvalues from normalized_hypergraph_laplacian
3 participants