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

Add MajoranaOp class #1270

Merged

Conversation

grossardt
Copy link
Contributor

Summary

Adds a new class .second_q.operators.MajoranaOp implementing a Majorana fermion operator, along with a M̀ajoranaOp.from_fermionic_op constructor method to convert a FermionicOp into a MajoranaOp. Fixes #1257

M̀ajoranaOp is implemented as a SparseLabelOp, closely following the implementation of FermionicOp. The syntax for operator labels is '_0 _1' for $\gamma_0 \gamma_1$ etc.

Details and comments

Label syntax

The reasoning for choosing '_0 _1' as a label style was a compromise between compatibility (MajoranaOp should also be a SparseLabelOp with a syntax close to those of FermionicOp and BosonicOp), readability, and sparsity. Technically, a Majorana operator is defined by just a list of indices, but any non-string format would be incompatible with the other operators. I was considering something like '$_0 $_1' with some character $ in order to have the closest possible format to the other operators, but since there is no canonical choice for the $ symbol ($\gamma$ would be, but is problematic as a non-ASCII character, I was considering 'g_0', '#_0', etc.) I thought, the most reasonable choice is to keep the underscore for readability and clarity that we are dealing with an index but omit the +/-/$/... completely. Since this is clearly a relevant choice and pretty subjective, I post this as a draft pull request and am looking forward to discussing this.

Implementation of MajoranaOp

MajoranaOp is largely copy&paste from FermionicOp with some more or less trivial adaptions. The main differences are

  • there is no method for normal ordering as this makes no sense for Majorana operators
  • there is the constructor method MajoranaOp.from_fermionic_op that converts a Fermionic operator to Majorana. Conversion follows the same convention as in openfermion, i.e. $f_k = (\gamma_{2k} + i \gamma_{2k+1})/2$ is the $k$-th annihilation operator expressed in terms of the Majoranas.
  • num_spin_orbitals is truly meant to count the number of fermionic orbitals, hence indices run from 0 to 2 * num_spin_orbitals - 1 since every orbital with its creation/annihilation operators gets mapped to two Majorana operators.

I documented everything mostly in the exact same style as in the docstrings for FermionicOp - i.e. I believe that the documentation is taken care off, modulo the issue with arguments I opened in #1269 .

I also implemented tests for all methods (again mostly just copy&paste from the corresponding tests of FermionicOp).

Order of operator classes in documentation

In __init__.py I added MajoranaOp directly underneath FermionicOp which makes it the second operator to appear in the list in the API reference before BosonicOp. I guess this is debatable, since BosonicOp is clearly the more important operator, but then I think that it makes sense to group Majorana and Fermionic operators together. Alternatively, one could also put BosonicOp at the top, followed by FermionicOp and MajoranaOp which is the order in which one would most likely find them in a textbook, or simply opt for alphabetical order.

Changes to FermionicOp

I made two changes to FermionicOp:

  • FermionicOp._index_order is turned into a classmethod so it can be called from within MajoranaOp.index_order as well (to avoid redundancy).
  • I removed the reference to FermionicOp.to_matrix in the docstring since such a method does not seem to exist (unrelated to the Majorana changes)

All changes are summarized in the release note.

@coveralls
Copy link

coveralls commented Nov 14, 2023

Pull Request Test Coverage Report for Build 8718939695

Details

  • 168 of 178 (94.38%) changed or added relevant lines in 3 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.1%) to 86.883%

Changes Missing Coverage Covered Lines Changed/Added Lines %
qiskit_nature/second_q/operators/majorana_op.py 165 175 94.29%
Totals Coverage Status
Change from base Build 8662422324: 0.1%
Covered Lines: 8949
Relevant Lines: 10300

💛 - Coveralls

@grossardt
Copy link
Contributor Author

I changed MajoranaOp.terms() to return tuples ("+", index) rather than ("", index). Mainly because I was afraid of breaking something by using the empty string label in QubitMapper. Also added a few more tests.

@grossardt grossardt marked this pull request as ready for review November 27, 2023 06:39
Copy link
Collaborator

@ftroisi ftroisi left a comment

Choose a reason for hiding this comment

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

Thanks for adding this class!
So my question is how would you map a MajoranaOp to thee qubit space? Are you planning to implement a mapper or perhaps to rely on the Fermioni mappers?

qiskit_nature/second_q/operators/majorana_op.py Outdated Show resolved Hide resolved
@grossardt
Copy link
Contributor Author

@ftroisi Thanks for your comments!

So my question is how would you map a MajoranaOp to thee qubit space? Are you planning to implement a mapper or perhaps to rely on the Fermioni mappers?

Yes, the whole point of this exercise is as a means to the end of implementing the ternary tree mapper, cf. #582 (which I have basically completed but need to add some reasonable tests before opening a PR).

Regarding the docstrings, as @woodsp-ibm has pointed out, there are generally no docstrings for classes that inherit and can use the parent docstring. I mainly followed 1:1 the implementation of FermionicOp here. I'm not sure if I like this either - I guess it keeps the code compact but needing to find the parent method to understand what a method is supposed to do can be a bit tedious. Nonetheless, I accepted it as a style choice and tried to be consistent.

Same goes essentially for the .tensor and .expand methods. Simply trying to be as close to FermionicOp as possible which has both these methods.

I have no strong feelings about any of those things, but would argue that if they are changed here one should possibly also discuss them for the other operators and the rest of qiskit-nature.

@woodsp-ibm
Copy link
Member

woodsp-ibm commented Nov 27, 2023

I'm not sure if I like this either - I guess it keeps the code compact but needing to find the parent method to understand what a method is supposed to do can be a bit tedious

The methods are documented in the derived class as well for overridden methods - it takes the docstring from the method in the parent (saves copying the same thing). If you click on the Details in one of the checks that are run by CI (you may need to click the Show all checks you can then click Summary at the top of left pane (has small home image by it) and in the right hand pane, if you scroll down, you will find a link to artifacts that are built by CI. The documentation.zip contains the html that is built so you can download and unzip that and you find a index.html that you can navigate from. The example image I posted above, was taken from such a download. You can see it its the compose method and that is says MajoranaOp in it - as you say you followed FermionicOp you can see that method is there in the live docs https://qiskit.org/ecosystem/nature/stubs/qiskit_nature.second_q.operators.FermionicOp.html#qiskit_nature.second_q.operators.FermionicOp.compose

@grossardt
Copy link
Contributor Author

@woodsp-ibm
Yes, for the documentation that is clear. I was mainly talking about working with the code. Sorry, if I wasn't making that clear enough.

Copy link
Member

@mrossinek mrossinek left a comment

Choose a reason for hiding this comment

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

Alright, I left quite a number of comments but hopefully this gives you everything that you need 👍

qiskit_nature/second_q/operators/__init__.py Show resolved Hide resolved
qiskit_nature/second_q/operators/fermionic_op.py Outdated Show resolved Hide resolved
releasenotes/notes/add-majoranaop-1cbf9d4a1d4c264e.yaml Outdated Show resolved Hide resolved
releasenotes/notes/add-majoranaop-1cbf9d4a1d4c264e.yaml Outdated Show resolved Hide resolved
qiskit_nature/second_q/operators/majorana_op.py Outdated Show resolved Hide resolved
qiskit_nature/second_q/operators/majorana_op.py Outdated Show resolved Hide resolved
qiskit_nature/second_q/operators/majorana_op.py Outdated Show resolved Hide resolved
qiskit_nature/second_q/operators/majorana_op.py Outdated Show resolved Hide resolved
@grossardt grossardt marked this pull request as draft November 28, 2023 22:39
@grossardt
Copy link
Contributor Author

Made some changes regarding the more obvious comments. Will work in the rest later this week. Reverted the PR to draft until then.

@grossardt
Copy link
Contributor Author

That should cover all the points raised now. I hope I didn't forget any.

@grossardt grossardt marked this pull request as ready for review December 2, 2023 00:00
@grossardt grossardt requested a review from mrossinek December 2, 2023 00:00
Copy link
Member

@mrossinek mrossinek left a comment

Choose a reason for hiding this comment

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

Alright, this is looking very good!

I still have some nitpicks and a few more suggestions for unittests but coverage is otherwise very good and I think this is basically good to go.
I did find a semi-related bug (#1298) which we will need to address separately, but this should not hold up the merging of this PR 👍

releasenotes/notes/add-majoranaop-1cbf9d4a1d4c264e.yaml Outdated Show resolved Hide resolved
qiskit_nature/second_q/operators/majorana_op.py Outdated Show resolved Hide resolved
qiskit_nature/second_q/operators/majorana_op.py Outdated Show resolved Hide resolved
qiskit_nature/second_q/operators/majorana_op.py Outdated Show resolved Hide resolved
qiskit_nature/second_q/operators/majorana_op.py Outdated Show resolved Hide resolved
qiskit_nature/second_q/operators/majorana_op.py Outdated Show resolved Hide resolved
qiskit_nature/second_q/operators/majorana_op.py Outdated Show resolved Hide resolved
qiskit_nature/second_q/operators/majorana_op.py Outdated Show resolved Hide resolved
@grossardt grossardt requested a review from mrossinek December 13, 2023 01:06
mrossinek
mrossinek previously approved these changes Feb 23, 2024
Copy link
Member

@mrossinek mrossinek left a comment

Choose a reason for hiding this comment

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

Relying heavily on my previous reviews, I think this LGTM 👍

Just two very minor things about the release note.

releasenotes/notes/add-majoranaop-1cbf9d4a1d4c264e.yaml Outdated Show resolved Hide resolved
releasenotes/notes/add-majoranaop-1cbf9d4a1d4c264e.yaml Outdated Show resolved Hide resolved
@grossardt grossardt requested a review from mrossinek February 26, 2024 00:34
Copy link
Member

@mrossinek mrossinek left a comment

Choose a reason for hiding this comment

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

Thank you for this valuable contribution! 🎉

@mrossinek mrossinek merged commit 27a1460 into qiskit-community:main Apr 17, 2024
16 checks passed
@grossardt grossardt deleted the addfeature-majoranaop-issue1257 branch April 19, 2024 12:53
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.

Implement Majorana Operator
5 participants