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 circuit plot error for gates with classical controls when reverse_states=False #221

Merged
merged 2 commits into from
Nov 2, 2023

Conversation

kpobrien
Copy link
Contributor

@kpobrien kpobrien commented Nov 1, 2023

For circuits with a classical control and when reverse_state=False, the error reported in #220 occurs. This pull request changes the sign of the argument of \ctrl when reverse_state=False. With this change, the test circuit is plotted without errors:

from qutip_qip.circuit import QubitCircuit
qc = QubitCircuit(1, num_cbits=1, reverse_states=False)
qc.add_gate("X", targets=0, classical_controls=[0])
print(qc.latex_code())
qc.png
\documentclass[border=3pt]{standalone}
\usepackage[braket]{qcircuit}
\begin{document}
\Qcircuit @C=1cm @R=1cm {
 &  &  \gate{X}  & \qw \\ 
 &  &  \ctrl{-1}  & \qw \\ 
}
\end{document}

image

A more complex test case:

from qutip_qip.circuit import QubitCircuit, CircuitSimulator
from qutip_qip.operations import hadamard_transform

qc = QubitCircuit(3, num_cbits=2, reverse_states=False)
qc.user_gates = {"H": hadamard_transform(1)}
qc.add_gate("CNOT", targets=1, controls=2)
qc.add_gate("H", targets=2)
qc.add_measurement("M1", targets=1, classical_store=0)
qc.add_measurement("M2", targets=2, classical_store=1)
qc.add_gate("X", targets=0, classical_controls=0)
qc.add_gate("Z", targets=0, classical_controls=1)
qc.png

image

from qutip_qip.circuit import QubitCircuit, CircuitSimulator
from qutip_qip.operations import hadamard_transform

qc = QubitCircuit(3, num_cbits=2, reverse_states=True)
qc.user_gates = {"H": hadamard_transform(1)}
qc.add_gate("CNOT", targets=1, controls=2)
qc.add_gate("H", targets=2)
qc.add_measurement("M1", targets=1, classical_store=0)
qc.add_measurement("M2", targets=2, classical_store=1)
qc.add_gate("X", targets=0, classical_controls=0)
qc.add_gate("Z", targets=0, classical_controls=1)
qc.png

image

@BoxiLi
Copy link
Member

BoxiLi commented Nov 2, 2023

Thank you! Could you add the simple example to the tests/test_circuit.py? Similar to

def test_latex_code_teleportation_circuit(self):
qc = _teleportation_circuit()
latex = qc.latex_code()
assert latex == self._latex_template % "\n".join([
r" & \lstick{c1} & \qw & \qw & \qw & \qw"
r" & \qw \cwx[4] & \qw & \qw & \ctrl{2} & \qw \\ ",
r" & \lstick{c0} & \qw & \qw & \qw & \qw"
r" & \qw & \qw \cwx[2] & \ctrl{1} & \qw & \qw \\ ",
r" & \lstick{\ket{0}} & \qw & \targ & \qw & \qw"
r" & \qw & \qw & \gate{X} & \gate{Z} & \qw \\ ",
r" & \lstick{\ket{0}} & \gate{{\rm H}} & \ctrl{-1} &"
r" \targ & \qw & \qw & \meter & \qw & \qw & \qw \\ ",
r" & \lstick{\ket{q0}} & \qw & \qw & \ctrl{-1} &"
r" \gate{{\rm H}} & \meter & \qw & \qw & \qw & \qw \\ ",
"",
])

@kpobrien
Copy link
Contributor Author

kpobrien commented Nov 2, 2023

Certainly and thanks for the quick response. Is adding the following code below the function test_latex_code_teleportation_circuit what you had in mind? If yes, I'll revise the PR to reflect this.

    def test_latex_code_classical_controls(self):
        qc = QubitCircuit(1, num_cbits=1, reverse_states=True)
        qc.add_gate("X", targets=0, classical_controls=[0])
        latex = qc.latex_code()
        assert latex == self._latex_template % "\n".join([
            r" &  &  \ctrl{1}  & \qw \\ ",
            r" &  &  \gate{X}  & \qw \\ ",
            "",
        ])

    def test_latex_code_classical_controls_non_reversed(self):
        qc = QubitCircuit(1, num_cbits=1, reverse_states=False)
        qc.add_gate("X", targets=0, classical_controls=[0])
        latex = qc.latex_code()
        assert latex == self._latex_template % "\n".join([
            r" &  &  \gate{X}  & \qw \\ ",
            r" &  &  \ctrl{-1}  & \qw \\ ",
            "",
        ])

@BoxiLi
Copy link
Member

BoxiLi commented Nov 2, 2023

Yes, precisely. Maybe in one test function instead of two.

After being added, these tests will be automatically executed on GitHub. You can also test it locally with pytest tests to verify if everything is correct.

@kpobrien
Copy link
Contributor Author

kpobrien commented Nov 2, 2023

Yes, precisely. Maybe in one test function instead of two.

Done, I updated the PR and it passes the tests locally. I see a message "3 workflows awaiting approval", so you may need to approve running the tests on Github.

@BoxiLi BoxiLi merged commit f41bbb3 into qutip:master Nov 2, 2023
14 checks passed
@BoxiLi
Copy link
Member

BoxiLi commented Nov 2, 2023

All looks good, thanks for your contribution!

@BoxiLi BoxiLi added this to the qutip-qip-0.3.1 milestone Nov 4, 2023
BoxiLi added a commit to BoxiLi/qutip-qip that referenced this pull request Apr 20, 2024
fix circuit plot error for gates with classical controls when reverse_states=False
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.

2 participants