Skip to content

feat: add default zero state to QubitCircuit.run()#376

Merged
BoxiLi merged 5 commits intoqutip:masterfrom
satishkc7:feat/default-zero-state-run
Apr 10, 2026
Merged

feat: add default zero state to QubitCircuit.run()#376
BoxiLi merged 5 commits intoqutip:masterfrom
satishkc7:feat/default-zero-state-run

Conversation

@satishkc7
Copy link
Copy Markdown
Contributor

Closes #374.

Summary

qc.run() previously required an explicit state argument in every call. In the large majority of use cases the initial state is the all-zero ket |00...0>. This PR makes state optional by defaulting to that state when none is provided.

Changes

  • circuit.py: add basis and tensor to the qutip import, change state to state=None, and insert a one-liner that constructs the zero state from self.dims when the argument is omitted.
  • test_circuit.py: add test_run_default_zero_state covering a single-qubit and a two-qubit circuit.

Before

qc = QubitCircuit(2)
qc.add_gate("X", targets=0)
result = qc.run(tensor(basis(2, 0), basis(2, 0)))  # state required

After

qc = QubitCircuit(2)
qc.add_gate("X", targets=0)
result = qc.run()  # defaults to |00>

Passing an explicit state still works exactly as before.

"""Test that qc.run() without a state argument defaults to |00...0>."""
# Single qubit: X gate should map |0> to |1>
qc = QubitCircuit(num_qubits=1)
qc.add_gate("X", targets=0)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
qc.add_gate("X", targets=0)
qc.add_gate(X, targets=0)


# Two qubits: default |00>, apply X on qubit 0, expect |10>
qc2 = QubitCircuit(num_qubits=2)
qc2.add_gate("X", targets=0)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as above

qc = QubitCircuit(num_qubits=1)
qc.add_gate("X", targets=0)
result = qc.run()
fid = pytest.approx(qutip.fidelity(result, basis(2, 1)))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please use relative and absolute tolerances

Copy link
Copy Markdown
Member

@Mayank447 Mayank447 left a comment

Choose a reason for hiding this comment

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

Just some minor changes.

@satishkc7 In case you used AI tools, we expect you to mention that in the PR description as per our Contribution guidelines.

Comment on lines +643 to +644
fid = pytest.approx(qutip.fidelity(result, basis(2, 1)), rel=1e-6, abs=1e-6)
assert fid == 1.0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
fid = pytest.approx(qutip.fidelity(result, basis(2, 1)), rel=1e-6, abs=1e-6)
assert fid == 1.0
assert qutip.fidelity(result, basis(2, 1)) == pytest.approx(1.0, rel=1e-6, abs=1e-6)

Comment on lines +651 to +652
fid2 = pytest.approx(qutip.fidelity(result2, expected), rel=1e-6, abs=1e-6)
assert fid2 == 1.0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as above

@BoxiLi
Copy link
Copy Markdown
Member

BoxiLi commented Apr 7, 2026

Please run the test locally and confirm that it passes before raising a PR and please state explicitly if and how AI tools are used.

@satishkc7
Copy link
Copy Markdown
Contributor Author

Thanks for the review feedback.

All requested changes have been addressed:

  • Replaced string gate names with object references (gates.X)
  • Updated assertions to use inline pytest.approx(1.0, rel=1e-6, abs=1e-6) pattern
  • Fixed an invalid escape sequence (\|) in the docstring that causes a SyntaxError on Python 3.14

Tests confirmed passing locally:

tests/test_circuit.py::TestQubitCircuit::test_run_default_zero_state PASSED

Regarding AI tools - yes, I used Claude (Claude Code) to assist with drafting the implementation and tests. Happy to note this in the PR description as well if needed.

When no state is provided, qc.run() now defaults to the all-zero ket
state |00...0> constructed from the circuit's qubit dimensions.
Resolves qutip#374.
- Use gates.X object instead of string literal
- Add rel and abs tolerances to pytest.approx calls
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates QubitCircuit.run() to make the state argument optional, defaulting to the all-zero computational basis ket for the circuit’s configured subsystem dimensions. This aligns the API with the common workflow where circuits are run from |00…0⟩ unless otherwise specified.

Changes:

  • Make QubitCircuit.run(state=...) accept state=None and synthesize the default initial ket from self.dims.
  • Update the run() docstring to describe the new default behavior.
  • Add tests covering the default initial state for 1- and 2-qubit circuits.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/qutip_qip/circuit/circuit.py Defaults run()’s input state to the all-zero ket constructed from self.dims when omitted.
tests/test_circuit.py Adds regression tests ensuring run() without state starts from |00…0⟩ and produces expected outputs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Mayank447
Copy link
Copy Markdown
Member

Mayank447 commented Apr 9, 2026

@BoxiLi You can merge this PR. Do a squash merge btw.

@BoxiLi BoxiLi merged commit f8109bb into qutip:master Apr 10, 2026
16 of 17 checks passed
@Mayank447 Mayank447 added this to the qutip-qip-0.5.0 milestone Apr 11, 2026
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.

Add default state to qc.run()

4 participants