-
Notifications
You must be signed in to change notification settings - Fork 71
Add basic error correction codes in qutip-qip
algorithms
#277
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
base: master
Are you sure you want to change the base?
Conversation
@BoxiLi this is ready for review! |
Thanks a lot! This looks really cool. sorry for the delay. The code looks pretty good to me. Two general questions before a more detailed review:
|
Another question, usually, the dencode circuit has measurement and classically controlled operations (for example here https://quantumcomputing.stackexchange.com/questions/6501/2-ways-to-do-the-three-qubits-bit-flip-code), which I don't see in the code? Could you also add some reference links/papers as inline comments to the code? |
Hello @BoxiLi , thanks for the review. I understood that the code needs to be more modular and reusable. The two circuits given in |
A lot of the structure is taken from https://github.com/qiskit-community/qiskit-community-tutorials/blob/master/awards/teach_me_quantum_2018/intro2qc/10.Quantum%20error%20correction.ipynb?utm_source=chatgpt.com and Neilsen and Chuang. |
@BoxiLi , it's ready for review again! |
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.
Thanks!, yes, indeed the major point is to make the code more reusable.
I have one more suggestions, in the current format, all the information about the qubit indices is saved in the class instance. I would rather argue that this should be given when the method is called rather than saved the class instance is initialized. That is:
qec_generator = BitFlipCode()
circ1 = qec_generator.encode_circuit(data_qubits=[0,1,2], ...=[3,4])
circ2 = qec_generator.encode_circuit(data_qubits=[5,6,7], ...=[8,9])
instead of (current code)
qec_generator = BitFlipCode(data_qubits=[0,1,2], ...=[3,4])
circ1 = qec_generator.encode_circuit()
qec_generator = BitFlipCode(data_qubits=[5,6,7], ...=[8,9])
circ2 = qec_generator.encode_circuit()
I guess the main point is why we need to define a class and make functions like encode_circuit
class methods instead of just define bit_flip_encode_circuit
. I understand that you define the class like this because all the QEC class share similar methods. Later if we have some meta method for all QEC circuits, we can define a parent class. This is fine. I imagine this class
as a gagdet that knows how to generate different QEC methods.
But then it should not save the qubit indices, instead, it should only save information about the QEC circuit as a whole piece. Something that is needed to define this circuit, in a qubit independent way. This could be e.g., the number of data qubit used in the repetition code, right now it is three, but in principle it can be any N! Those are information about the abstract QEC circuit, but not about its embedding in a real N qubit system.
A direct consequence of this is making the code less redundant, as in the above code example.
What do you think?
""" | ||
|
||
def __init__(self, data_qubits=[0, 1, 2], syndrome_qubits=[3, 4]): | ||
assert len(data_qubits) == 3, "Bit-flip code requires 3 data qubits." |
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.
This should raise an InputError with the message "Bit-flip code requires 3 data qubits."
. assert
is used only for internal checking, but here it is meant to tell the user that they gave the wrong input.
If you think it will help improving productivity I am also happy to have a chat online, maybe after 10th of June. |
Sure, should be able to join on 10 June if you could share a link to my email. |
@BoxiLi have made the discussed changes to |
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.
Thanks! Yes it is good to fisrt look at one part of it. I had a look at the BitFlipCode part.
I think you might build the code on the wrong base branch, because I do not see qpe.py
, which you added last time. This could be the reason for the conflict. You can try to rebase the code upon the current upstream master.
It would be cool if we can combine three circuit part (with manually added error maybe?) and test it!
self.n_data = 3 | ||
self.n_syndrome = 2 |
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.
I assume self.n_data
and self.n_syndrome
are things that are specific for this algorithm and we do not want people to change them, right? So I would suggest mark them as private members self._n_data
and self._n_syndrome
. In the Python convention, this means that those are private members and should not be accessed by users.
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.
Yes, makes sense to make them private
self.n_syndrome = 2 | ||
|
||
def encode_circuit(self, data_qubits): | ||
assert len(data_qubits) == self.n_data |
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.
We should raise an error instead of using assert. Assert is for internal checking. A user should in principle never see assert
error. Raise a ValueError
saying the number is wrong is more appropriate here.
assert len(data_qubits) == self.n_data | ||
assert len(syndrome_qubits) == self.n_syndrome |
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.
Same, raise errors.
qc.add_gate("CNOT", controls=dq[2], targets=sq[1]) | ||
|
||
# Measurements into classical bits | ||
qc.add_measurement(sq[0], classical_store=0) |
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.
Should be
qc.add_measurement(sq[0], sq[0], classical_store=0)
The first one is just the name of the measurement operation, the second one is the target qubit.
This triggers an error when plotting the circuit, you can use qc.draw()
to test and see if it is what you expected.
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.
BTW I might find bug in classical controlled gate plotting. If you don't see the control line plotted, that is fine.
This PR aims to add basic error correction codes in
qutip-qip
algorithms. #264phase-flip
,bit flip
, andshor code
.