-
Notifications
You must be signed in to change notification settings - Fork 18
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
[unitaryhack] Added local complementation function to EGraph class #89
Conversation
Dear Devs, This Pull Request may require some serious review due to my amateur coding. In particular, I attempted to write unit tests for the first time, so I feel a bit insecure about that. I hope you can bear with me! I still hope to complete the "Checklist and integration statements" outlined above. My contributed code is heavily commented for the sake of review. As this Pull Request is being made near the deadline for UnitaryHack, I do not demand nor expect to be eligible for potential bounties. Regardless, I am grateful for the opportunity to participate and happy to continue making revisions after the fact if possible. Cheers, |
Codecov Report
@@ Coverage Diff @@
## main #89 +/- ##
==========================================
+ Coverage 96.19% 96.23% +0.03%
==========================================
Files 36 36
Lines 2209 2308 +99
==========================================
+ Hits 2125 2221 +96
- Misses 84 87 +3
Continue to review full report at Codecov.
|
Awesome @smtsjhr! Thanks a lot for the contribution. I am not sure if we'll be able to get it in today, but I will check the rules to see if there is some slack for reviews. Cheers! |
@smtsjhr I just checked, and we don’t have to merge it before the UnitaryHack ends. To make sure you get the price, we simply have to mark your PR as accepted. |
Thanks, @soosub ! I will follow through with the formatting, linting, and CodeFactor checks this weekend. I am more than happy to participate in further review and make changes as the team sees fit. This is my first major open source pull request, and I hope to follow best practices, so please excuse any friction from me end! |
Hey @smtsjhr, great work! Everything works as it should. I will review next week after all checks are successful. We have accepted your PR as the solution of this unitary hack challenge :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @bestquark (CC: @soosub), I have gone through my code to fix various formatting and linting issues. I ran |
Thanks! For Regarding the other issues you can usually see what went wrong by clicking on "details" (see figure below) The fail for linting is because there is a docstring missing somewhere. |
Dear @smtsjhr, EDIT: Taking a better look at CodeFactor, there are a few minimal issues to be solved, mainly,
could each be made in a smaller private method (e.g. |
Hey @bestquark, thanks for the tips! I will run the formatting tests and do the refactoring as you mentioned. Amusingly, my original implementation did have separate functions exactly how you suggest, but for some reason i bundled them all into one for pull request here! I will gladly make these changes this weekend. With some more time I hope to make a technical review/blog about this algorithm and my implementation, which I can share here with any code reviewers if interested. |
Sounds great @smtsjhr!
Just letting you know: if you feel like it, you could also contribute to our tutorials page that we also keep on our repo 👀 We would happily collaborate on writing something up with you if you want. |
Hi Team! Took me a bit to get to this refactoring but now my most recent commits reflect the following major changes:: The main method The first 4 of these new private methods follow @bestquark 's previous suggestion, while I took my own liberty to introduce the last 2 methods which provide functionality to convert the representation of the local clifford into two different forms: 'tensor' or 'global'. Perhaps I should make these private function names more descriptive? IMPLEMENTATION NOTE:: TESTING NOTE:: Formatting/DocStrings NOTE:: Of course, feel free to let me know of any desired changes and I will happily try my best to make them. |
Dear @smtsjhr, Thank you for making these changes 😄. It seems to be still very few and minor issues with docformatter and code factor (which can be solved quite fast) that make two of the checks fail. The first issue can be easily fix by running The second issue (CodeFactor) refers to a few functions ( My recommendation to solve these second issues would be to take all the refactored methods that can be independent functions (the ones mentioned in the list) for testing lc equivalence and define them outside the With these two changes, I believe all checks should pass and we will be able to merge your PR. |
I have pushed the following changes:
Please do let me know if i missed anything! **POST EDIT::
I am assuming this is still okay. Otherwise, I think i understand how to structure the test script by removing the single test Class and defining its containing test methods individually. However, doing so seems to defeat the purpose of this last change where we mark.parametrize() the Class with |
Hi @smtsjhr and @bestquark, Are the only remaining issues the minor conflict and syncing with the main? If yes and @smtsjhr allows it, I can directly work on the source branch to resolve them myself. |
Hi @nariman87, yes, this PR is ready and reviewed. |
Thanks, @bestquark, however, best to first resolve the conflict and sync issues as I suggested. |
Actually @nariman87 @bestquark, I was going to have a quick look myself as well - let me finalize the review and we can take it from there. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent! This is a useful, interesting, and convenient addition that can be used to analyze the local equivalence of graph states. It's a product of a lot of work.
I have left some minor suggestions for names and docstrings. To finalize the PR, I think we should do the following:
- Place all new functions in a separate file in the
utils' directory (say,
linalg.py`).is_lc_equivalent
would then have to be modified very slightly, and it should be renamed toare_lc_equivalent
.- The existing
is_lc_equivalent
inEGraph
(the name can stay) should be a wrapper ofare_lc_equivalent
. - The name
test_is_lc_equivalent
should be renamed to something more general, liketest_linalg
.
- A small example of the functionality should be added to
examples\graphstates.py
.
Hi @ilan-tz and team, I am happy to try to make these changes this weekend, if thats okay. I may circle back for some more clarification if needed. I am excited and determined to see this UnitaryHack contribution through! Thanks for your review and all of your suggestions. |
Hey @ilan-tz. I attempted to make all the changes you suggested, EXCEPT the last one for adding an example to I am not sure if my way of "wrapping" the new utility function The contents of the renamed test file The other commits I recently made were minor formatting changes to clean up the code. Again, an example of the functionality still needs to be added to |
Hi @smtsjhr ! Thanks for your quick turnaround on this. On first glance the wrapping looks exactly as I intended. I'd say we don't have to add more linalg tests to this PR. For the example, I propose the following:
This is a quick way to verify the validity of the function and show users that we have a small existing database of graph states. Please let me know if you're able to put this example inl if so, once it's ready I'll be happy to re-review. Thanks again for your work! |
Hi @ilan-tz, I added a new example file: I feel my example code is a bit redundant, and considered using some kind of loop to log all the different graph comparisons. Also, I opted to include some global parameters Previously, I think you suggested adding a new example for testing LC equivalence to the already existing example file I will wait for further review to make more changes... Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@smtsjhr Looks great! Just a few tiny suggestions made -- please also delete .DS_Store & sync with the latest main, and then this is ready to merge (if you are done with changes on your end).
🚨 🚨 🚨 I made a big mistake and need advice to fix! When trying to sync my fork to the latest main I accidentally "force-pushed", which discarded 45 commits from my original fork. This seemed to have "merged" the forks to the latest main, and closed this pull request (without my intention). What is the best action I should take to revert this merge on my fork, and preserve my commits? OPTION 1:: OPTION 2:: OPTION 3:: OPTION 4:: Sorry to spoil this so close to completion. I am nervous now of making things worse, so will wait for any tips. Thanks! 🙏 |
Hi @smtsjhr, In this case and after the mistakes and changes above, XanaduAI:main flamingpy is, of course, mostly unaffected (by design only mistakes from admins and some other users can harm the project -- we may change permissions as needed). The only downside is that some lines of unnecessary history are now added to the project forever, such as this PR or a history line saying Now, what I suggest in your situation (and indeed you are free to do as you wish with smtsjhr's files and branches):
|
Hi @nariman87 (CC @ilan-tz ), Hoping I correctly recovered from my accidental merge. Feel free to let me know if any more action is needed on my end. Please refer to Pull #117 for followup on this resubmitted pull request. |
…class #89" (#117) * added is_lc_equivalent() method to EGgraph class * Create test_is_lc_equivalent.py * ran black -l 100 * ran black -l 100 * cleaned code * cleaned code * cleaned code * format comment line length * cleaned code * Added module docstring * ran 'black -l 100 tests flamingpy' * ran 'docformatter --in-place tests/*/*.py' * ran 'docformatter --in-place tests/*/*.py' * refactored is_lc_equivalent with private methods * ran black -l 100 tests flamingpy * fixed too long comment lines * edits to comments * moved some utility function definitions to outside the Egraph class * ran `docformatter --in-place flamingpy/*/*/*.py` * simplified test function parametrization The main testing class is now parametrized for two modes "global" and "tensor", instead of parametrizing individual methods of the class. Unused utility functions are also removed. * ran `black -l 100 tests flamingpy` * Delete myscript.py File not needed (used for scratch testing) * pylint disable test * disable = no-self-use * update .pylintrc * update changelog and version * Update CHANGELOG.md * Apply suggestions from code review Code review by @ilan-tz Co-authored-by: ilan-tz <57886357+ilan-tz@users.noreply.github.com> * update changed function names * added algo citation link to doc string " Implemented as in arXiv:quant-ph/0405023." * Create linalg.py Contains helper functions for linear algebra (moved from egraph.py), and also a function 'are-lc_equivalent' to be wrapped in egraph.py * Removed linear algebra helper functions and wrapped 'is_lc_equivalent' method of EGraph class All linear algebra functions were moved to utils/linalg.py, and the 'is_lc_equivalent' method of the class is now wrapped using 'are_lc_equivalent' function from linalg.py * renamed 'test_is_lc_equivalent.py' to 'test_linalg.py' Only the filename was renamed. No modifications or additional tests were introduced. * ran 'docformatter --in-place flamingpy/*/*/*.py' * ran 'docformatter --in-place flamingpy/utils/linalg.py' * ran 'black -l 100 flamingpy tests' * fixed "Line too Long" * Create lc_equivalence.py Example Example script for testing LC equivalence * Create "lc_equivalence.py" example script * Update fp.utils.rst * Apply suggestions from code review Co-authored-by: ilan-tz <57886357+ilan-tz@users.noreply.github.com> * Delete .DS_Store * Update flamingpy/codes/graphs/egraph.py suggested change by @ilan-tz Co-authored-by: ilan-tz <57886357+ilan-tz@users.noreply.github.com> * Run black * Update CHANGELOG.md * Update _version.py Co-authored-by: Luis Mantilla <luismantilla99@outlook.com> Co-authored-by: Luis Mantilla <52287586+BestQuark@users.noreply.github.com> Co-authored-by: ilan-tz <57886357+ilan-tz@users.noreply.github.com>
Context for changes
New features:
A method is added to the EGraph class to check "LC equivalence" of two graphs.
This method goes beyond the specifications given is issue 71, and also returns the Local Clifford operation which satisfies the equivalence. The desired output form of the clifford should be discussed. This pull request adds an optional string argument named
clifford_form
to the method, discussed in more detail below. Perhaps this option can be removed from the implementation once a single desired form is agreed uponThis method's call signature does not use the @staticmethod as suggested in comment here. I chose the original requested signature of issue 71 due to the Asymmetry of the returned Clifford when checking equivalence in two directions: graph1 --> graph2 compared to graph2 --> graph1. See more comments about this below.
A test file named 'test_is_lc_equivalent.py' is added in the directory './Tests/qubit_codes'
Bug fixes:
Improvements:
Documentation changes:
Example usage and tests
This method checks if two graphs are LC equivalent. Here, "LC" means "Local Complementation / Local Clifford". When two graphs are LC equivalent they are related by a Local Clifford operation, and this method also returns this Local Clifford operation expressed in binary symplectic form.
The call signature of this method is:
graph1.is_lc_equivalent(graph2, clifford_form) --> (equiv, clifford)
Args::
Here
graph1
andgraph2
are EGraph objects.clifford_form
is a string (either'global'
or'tensor'
) which specifies the output form of the clifford if the equivalence isTrue
.clifford_form
is an optional argument with a default value of'global'
.Returns:
The method returns a tuple of the form
(equiv, clifford)
.If the graphs are equivalent,
equiv
isTrue
andclifford
is the corresponding local clifford.If the graphs are not equivalent,
equiv
isFalse
andclifford
isNone
.When two graphs are equivalent the following applies:
If
clifford_form = 'global'
, the returnedclifford
is a single 2nx2n binary matrix, where n is the number of nodes of the graphs.If
clifford_form = 'tensor'
, the returnedclifford
is given as a length n list of 2x2 binary matrices corresponding to the n (Hilbert space) tensor factors, where the k-th elemenet of the list is the tensor factor acting on the k-th node/qubit.Note the following asymmetry if graph1 and graph2 are LC equivalent:
We can compare the graphs in two ways:
graph1 --> graph2 :: by calling
graph1.is_lc_equivalent(graph2)
graph2 --> graph1 :: by calling
graph2.is_lc_equivalent(graph1)
If the two graphs are LC equivalent then both calls return
True
equivalence, but the resulting cliffords may be distinct.Therefore, we define test functions for both comparisons in order to test both cases.
Performance results justifying changes
Workflow actions and tests
TESTING METHODOLOGY:
The defined test functions run tests on various families of graphs known to be equivalent or not.
These include:
When two graphs are equivalent, in order to verify the returned local clifford we perform the following algebraic check:
Let
G1
andG2
be the adjacency matrices of the two LC equivalent graphs, and let the local clifford operation be given in block form as:[A | B]
[C | D]
Then the following matrix block equation must hold True:
G2*(C*G1+D) == (A*G1+B)
Expected benefits and drawbacks
Expected benefits:
Possible drawbacks:
Related Github issues
This PR closes #71 which was marked for a UnitaryHack bounty.
Checklist and integration statements
My Python and C++ codes follow this project's coding and commenting styles as indicated by existing files. Precisely, the changes conform to given
black
,docformatter
andpylint
configurations.I have performed a self-review of these changes, checked my code (including for codefactor compliance), and corrected misspellings to the best of my capacity. I have synced this branch with others as required.
I have added context for corresponding changes in documentation and
README.md
as needed.I have added new workflow CI tests for corresponding changes, ensuring codecoverage is 95% or better, and these pass locally for me.
I have updated
CHANGELOG.md
following the template. I recognize that the developers may revisitCHANGELOG.md
and the versioning, and create a Special Release including my changes.