Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,7 @@
# 4.0+. The pin can be removed after nbformat is updated.
jsonschema==3.2.0

# jupyter-core 5.0.0 started emitting deprecation warnings with ipywidgets via
# a seaborn import. This pin can be removed when compatibility with those
# packages is fixed
jupyter-core==4.11.2

# ipywidgets 8.0.3 started emitting deprecation warnings via a seaborn import.
# This pin can be removed when compatibility with those packages is fixed.
ipywidgets<8.0.3

# coverage 7.0.0 breaks with Python 3.8.15 upon the import
# from coverage.files import FnmatchMatcher
# since this is in Python 3.8 itself and not Qiskit, pinning this for now.
coverage<7.0
coverage<7.0
5 changes: 4 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
"""Sphinx documentation builder."""

# -- General configuration ---------------------------------------------------
import logging

logging.basicConfig(level=logging.DEBUG)

import datetime

project = "Qiskit"
Expand All @@ -37,7 +41,6 @@
"jupyter_sphinx",
"sphinx_autodoc_typehints",
"reno.sphinxext",
"sphinx_design",
]
templates_path = ["_templates"]

Expand Down
202 changes: 100 additions & 102 deletions qiskit/circuit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,160 +56,158 @@
Supplementary Information
=========================

.. dropdown:: Quantum Circuit with conditionals
:animate: fade-in-slide-down
.. rubric:: Quantum Circuit with conditionals

When building a quantum circuit, there can be interest in applying a certain gate only
if a classical register has a specific value. This can be done with the
:meth:`InstructionSet.c_if` method.
When building a quantum circuit, there can be interest in applying a certain gate only
if a classical register has a specific value. This can be done with the
:meth:`InstructionSet.c_if` method.

In the following example, we start with a single-qubit circuit formed by only a Hadamard gate
(:class:`~.HGate`), in which we expect to get :math:`|0\\rangle` and :math:`|1\\rangle`
with equal probability.
In the following example, we start with a single-qubit circuit formed by only a Hadamard gate
(:class:`~.HGate`), in which we expect to get :math:`|0\\rangle` and :math:`|1\\rangle`
with equal probability.

.. jupyter-execute::

from qiskit import BasicAer, transpile, QuantumRegister, ClassicalRegister

qr = QuantumRegister(1)
cr = ClassicalRegister(1)
qc = QuantumCircuit(qr, cr)
qc.h(0)
qc.measure(0, 0)
qc.draw('mpl')
.. jupyter-execute::

.. jupyter-execute::
from qiskit import BasicAer, transpile, QuantumRegister, ClassicalRegister

backend = BasicAer.get_backend('qasm_simulator')
tqc = transpile(qc, backend)
counts = backend.run(tqc).result().get_counts()
qr = QuantumRegister(1)
cr = ClassicalRegister(1)
qc = QuantumCircuit(qr, cr)
qc.h(0)
qc.measure(0, 0)
qc.draw('mpl')

print(counts)
.. jupyter-execute::

Now, we add an :class:`~.XGate` only if the value of the :class:`~.ClassicalRegister` is 0.
That way, if the state is :math:`|0\\rangle`, it will be changed to :math:`|1\\rangle` and
if the state is :math:`|1\\rangle`, it will not be changed at all, so the final state will
always be :math:`|1\\rangle`.
backend = BasicAer.get_backend('qasm_simulator')
tqc = transpile(qc, backend)
counts = backend.run(tqc).result().get_counts()

.. jupyter-execute::
print(counts)

qc.x(0).c_if(cr, 0)
qc.measure(0, 0)
Now, we add an :class:`~.XGate` only if the value of the :class:`~.ClassicalRegister` is 0.
That way, if the state is :math:`|0\\rangle`, it will be changed to :math:`|1\\rangle` and
if the state is :math:`|1\\rangle`, it will not be changed at all, so the final state will
always be :math:`|1\\rangle`.

qc.draw('mpl')
.. jupyter-execute::

.. jupyter-execute::
qc.x(0).c_if(cr, 0)
qc.measure(0, 0)

tqc = transpile(qc, backend)
counts = backend.run(tqc).result().get_counts()
qc.draw('mpl')

print(counts)
.. jupyter-execute::

tqc = transpile(qc, backend)
counts = backend.run(tqc).result().get_counts()

.. dropdown:: Quantum Circuit Properties
:animate: fade-in-slide-down
print(counts)

When constructing quantum circuits, there are several properties that help quantify
the "size" of the circuits, and their ability to be run on a noisy quantum device.
Some of these, like number of qubits, are straightforward to understand, while others
like depth and number of tensor components require a bit more explanation. Here we will
explain all of these properties, and, in preparation for understanding how circuits change
when run on actual devices, highlight the conditions under which they change.

Consider the following circuit:
.. rubric:: Quantum Circuit Properties

.. jupyter-execute::
When constructing quantum circuits, there are several properties that help quantify
the "size" of the circuits, and their ability to be run on a noisy quantum device.
Some of these, like number of qubits, are straightforward to understand, while others
like depth and number of tensor components require a bit more explanation. Here we will
explain all of these properties, and, in preparation for understanding how circuits change
when run on actual devices, highlight the conditions under which they change.

from qiskit import QuantumCircuit
qc = QuantumCircuit(12)
for idx in range(5):
qc.h(idx)
qc.cx(idx, idx+5)
Consider the following circuit:

qc.cx(1, 7)
qc.x(8)
qc.cx(1, 9)
qc.x(7)
qc.cx(1, 11)
qc.swap(6, 11)
qc.swap(6, 9)
qc.swap(6, 10)
qc.x(6)
qc.draw()
.. jupyter-execute::

From the plot, it is easy to see that this circuit has 12 qubits, and a collection of
Hadamard, CNOT, X, and SWAP gates. But how to quantify this programmatically? Because we
can do single-qubit gates on all the qubits simultaneously, the number of qubits in this
circuit is equal to the **width** of the circuit:
from qiskit import QuantumCircuit
qc = QuantumCircuit(12)
for idx in range(5):
qc.h(idx)
qc.cx(idx, idx+5)

qc.cx(1, 7)
qc.x(8)
qc.cx(1, 9)
qc.x(7)
qc.cx(1, 11)
qc.swap(6, 11)
qc.swap(6, 9)
qc.swap(6, 10)
qc.x(6)
qc.draw()

From the plot, it is easy to see that this circuit has 12 qubits, and a collection of
Hadamard, CNOT, X, and SWAP gates. But how to quantify this programmatically? Because we
can do single-qubit gates on all the qubits simultaneously, the number of qubits in this
circuit is equal to the **width** of the circuit:

.. jupyter-execute::
.. jupyter-execute::

qc.width()
qc.width()


We can also just get the number of qubits directly:
We can also just get the number of qubits directly:

.. jupyter-execute::
.. jupyter-execute::

qc.num_qubits
qc.num_qubits


.. important::
.. important::

For a quantum circuit composed from just qubits, the circuit width is equal
to the number of qubits. This is the definition used in quantum computing. However,
for more complicated circuits with classical registers, and classically controlled gates,
this equivalence breaks down. As such, from now on we will not refer to the number of
qubits in a quantum circuit as the width.
For a quantum circuit composed from just qubits, the circuit width is equal
to the number of qubits. This is the definition used in quantum computing. However,
for more complicated circuits with classical registers, and classically controlled gates,
this equivalence breaks down. As such, from now on we will not refer to the number of
qubits in a quantum circuit as the width.


It is also straightforward to get the number and type of the gates in a circuit using
:meth:`QuantumCircuit.count_ops`:
It is also straightforward to get the number and type of the gates in a circuit using
:meth:`QuantumCircuit.count_ops`:

.. jupyter-execute::
.. jupyter-execute::

qc.count_ops()
qc.count_ops()


We can also get just the raw count of operations by computing the circuits
:meth:`QuantumCircuit.size`:
We can also get just the raw count of operations by computing the circuits
:meth:`QuantumCircuit.size`:

.. jupyter-execute::
.. jupyter-execute::

qc.size()
qc.size()


A particularly important circuit property is known as the circuit **depth**. The depth
of a quantum circuit is a measure of how many "layers" of quantum gates, executed in
parallel, it takes to complete the computation defined by the circuit. Because quantum
gates take time to implement, the depth of a circuit roughly corresponds to the amount of
time it takes the quantum computer to execute the circuit. Thus, the depth of a circuit
is one important quantity used to measure if a quantum circuit can be run on a device.
A particularly important circuit property is known as the circuit **depth**. The depth
of a quantum circuit is a measure of how many "layers" of quantum gates, executed in
parallel, it takes to complete the computation defined by the circuit. Because quantum
gates take time to implement, the depth of a circuit roughly corresponds to the amount of
time it takes the quantum computer to execute the circuit. Thus, the depth of a circuit
is one important quantity used to measure if a quantum circuit can be run on a device.

The depth of a quantum circuit has a mathematical definition as the longest path in a
directed acyclic graph (DAG). However, such a definition is a bit hard to grasp, even for
experts. Fortunately, the depth of a circuit can be easily understood by anyone familiar
with playing `Tetris <https://en.wikipedia.org/wiki/Tetris>`_. Lets see how to compute this
graphically:
The depth of a quantum circuit has a mathematical definition as the longest path in a
directed acyclic graph (DAG). However, such a definition is a bit hard to grasp, even for
experts. Fortunately, the depth of a circuit can be easily understood by anyone familiar
with playing `Tetris <https://en.wikipedia.org/wiki/Tetris>`_. Lets see how to compute this
graphically:

.. image:: /source_images/depth.gif
.. image:: /source_images/depth.gif


.. raw:: html
.. raw:: html

<br><br>
<br><br>


We can verify our graphical result using :meth:`QuantumCircuit.depth`:
We can verify our graphical result using :meth:`QuantumCircuit.depth`:

.. jupyter-execute::
.. jupyter-execute::

qc.depth()
qc.depth()


.. raw:: html
.. raw:: html

<br>
<br>

Quantum Circuit API
===================
Expand Down
Loading