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

Added how-to guides #8624

Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
2f1e42f
Added how-to section
Guillermo-Mijares-Vilarino Aug 26, 2022
d39833c
added how to compose circuits guide
Guillermo-Mijares-Vilarino Aug 26, 2022
bb661fd
added how to visualize circuit guide
Guillermo-Mijares-Vilarino Aug 26, 2022
59e06f9
add how to create parameterized circuit guide
Guillermo-Mijares-Vilarino Aug 26, 2022
9c87269
Merge branch 'main' of https://github.com/Guillermo-Mijares-Vilarino/…
Guillermo-Mijares-Vilarino Aug 26, 2022
109b049
Merge branch 'Qiskit:main' into add-how-tos
Guillermo-Mijares-Vilarino Aug 26, 2022
63d6f81
add guides
Guillermo-Mijares-Vilarino Aug 26, 2022
9cc7f76
Merge branch 'add-how-tos' of https://github.com/Guillermo-Mijares-Vi…
Guillermo-Mijares-Vilarino Aug 26, 2022
d28748a
removed latex circuit visualization
Guillermo-Mijares-Vilarino Aug 29, 2022
e7b2e47
fixed title underlines
Guillermo-Mijares-Vilarino Aug 29, 2022
352a7c4
Fix typo
Guillermo-Mijares-Vilarino Aug 29, 2022
ba14c27
explicitly set cregbundle to False when appending circuit with classi…
Guillermo-Mijares-Vilarino Aug 29, 2022
4cf2634
Fix typo
Guillermo-Mijares-Vilarino Aug 30, 2022
ed2115c
Added explanation about needed latex distribution
Guillermo-Mijares-Vilarino Aug 31, 2022
a7b38d8
added link to qiskit.visualization module
Guillermo-Mijares-Vilarino Aug 31, 2022
861baaa
Simplified references
Guillermo-Mijares-Vilarino Sep 1, 2022
9354aa0
Change 'we' to 'you'
Guillermo-Mijares-Vilarino Sep 12, 2022
02298c6
Changed how_to.rst to how_to/index.rst
Guillermo-Mijares-Vilarino Sep 28, 2022
0dbd593
Merge branch 'main' into add-how-tos
Guillermo-Mijares-Vilarino Feb 28, 2023
6ad73b0
Removed jupyter-execute from create_a_quantum_circuit
Guillermo-Mijares-Vilarino Feb 28, 2023
571db61
Removed jupyter-execute from create_a_parameterized_circuit
Guillermo-Mijares-Vilarino Feb 28, 2023
2081f4a
Removed jupyter-execute from compose_quantum_circuits
Guillermo-Mijares-Vilarino Feb 28, 2023
082b04e
Removed jupyter-execute from visualize_a_quantum_circuit
Guillermo-Mijares-Vilarino Feb 28, 2023
205370c
Add sphinx.ext.doctest to conf.py
Guillermo-Mijares-Vilarino Feb 28, 2023
84f98cf
Change header symbol for index and visualization guide
Guillermo-Mijares-Vilarino Mar 1, 2023
a6053bb
Added guides for sampler and estimator and simplified toctree
Guillermo-Mijares-Vilarino Mar 1, 2023
3ac6be1
Fixed underline
Guillermo-Mijares-Vilarino Mar 1, 2023
3b260e8
Add links to how-to create circuit
Guillermo-Mijares-Vilarino Mar 1, 2023
5a3a74a
Added section about parameterized circuits to primitives how-tos
Guillermo-Mijares-Vilarino Mar 3, 2023
4b43e3c
Merge branch 'main' into add-how-tos
Guillermo-Mijares-Vilarino May 9, 2023
afa30d9
add quantum to parameterized circuits how-to title
Guillermo-Mijares-Vilarino May 10, 2023
6a10dd1
change compose to join in title
Guillermo-Mijares-Vilarino May 10, 2023
6d60a27
Added warning about + operator not supported to combine circuits
Guillermo-Mijares-Vilarino May 10, 2023
5f3d22b
Merge branch 'main' into add-how-tos
Guillermo-Mijares-Vilarino May 10, 2023
20fd583
Apply suggestions from code review
Guillermo-Mijares-Vilarino May 12, 2023
795b35c
Apply suggestions from code review
Guillermo-Mijares-Vilarino May 12, 2023
8f8ec24
rephrase visualization how-to intro
Guillermo-Mijares-Vilarino May 12, 2023
9677372
Apply suggestions from code review
Guillermo-Mijares-Vilarino May 12, 2023
c33605e
fix underline
Guillermo-Mijares-Vilarino May 16, 2023
95537d3
Apply suggestions from code review
HuangJunye Jul 10, 2023
0570733
reverting to use verb instead of ing form
HuangJunye Jul 10, 2023
5e51112
Merge branch 'main' into add-how-tos
HuangJunye Jul 10, 2023
434c25e
Merge branch 'add-how-tos' of https://github.com/Guillermo-Mijares-Vi…
HuangJunye Jul 10, 2023
aa5d2d4
add back notes for including and excluding measurements
HuangJunye Jul 10, 2023
b0a1f6f
revert necessary code changes in use_estimator
HuangJunye Jul 10, 2023
ec0c28c
revert unnecessary code changes in use_sampler
HuangJunye Jul 10, 2023
194302c
change expectation values to sampling probabilities
HuangJunye Jul 10, 2023
65935f3
remove note
HuangJunye Jul 10, 2023
be801cf
remove note
HuangJunye Jul 10, 2023
802b53d
add a sentence explaining joining by specifying qubits
HuangJunye Jul 10, 2023
9f8cd3a
fix indentation
HuangJunye Jul 11, 2023
b304ad8
Merge branch 'main' into add-how-tos
HuangJunye Jul 11, 2023
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
16 changes: 16 additions & 0 deletions docs/how_to.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.. _how_to:

======
How to
======

Create quantum circuits
-----------------------

.. toctree::
:maxdepth: 1

Create a quantum circuit <how_to/create_a_quantum_circuit>
Compose quantum circuits <how_to/compose_quantum_circuits>
Visualize a quantum circuit <how_to/visualize_a_quantum_circuit>
Create a parameterized circuit <how_to/create_a_parameterized_circuit>
86 changes: 86 additions & 0 deletions docs/how_to/compose_quantum_circuits.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
========================
Compose quantum circuits
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved
========================

woodsp-ibm marked this conversation as resolved.
Show resolved Hide resolved
This guide shows how to combine different :class:`~qiskit.circuit.QuantumCircuit` objects.

Build the circuits
==================
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

The first step is creating the circuits we want to combine.

.. jupyter-execute::

from qiskit import QuantumCircuit
qc1 = QuantumCircuit(2,1)
qc1.h(0)
qc1.cx(0,1)
qc1.measure(0,0)

qc2 = QuantumCircuit(4,2)
qc2.y(1)
qc2.measure(1,1)

Combine the circuits
====================
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

Now that we have built the circuits, they can be combined with two different methods:

* :meth:`~qiskit.circuit.QuantumCircuit.compose()`
* :meth:`~qiskit.circuit.QuantumCircuit.append()`

One detail these two methods have in common is that if the circuits have different sizes, they have to be applied to the one that has the most of both qubits and classical bits.
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

:meth:`~qiskit.circuit.QuantumCircuit.compose()`
------------------------------------------------

In order to combine two circuits with :meth:`~qiskit.circuit.QuantumCircuit.compose()`, you only have to specify the circuit you want to insert. That way the qubits and bits of the smaller circuit will be included into the first qubits and bits of the bigger one in the original order they had.

By default, :meth:`~qiskit.circuit.QuantumCircuit.compose()` does not change the circuit to which it is applied but returns the composed circuit. This can be changed by setting the ``inplace`` argument to ``True``.

.. jupyter-execute::

qc3 = qc2.compose(qc1)
qc3.draw()

If you want to insert the qubits and bits into specific positions in the bigger circuit, you can use the ``qubits`` and ``bits`` arguments.
HuangJunye marked this conversation as resolved.
Show resolved Hide resolved

.. jupyter-execute::

qc4 = qc2.compose(qc1, qubits=[3,1], clbits=[1])
qc4.draw()

You can also apply the gates from the smaller circuit before those of the bigger one setting the ``front`` argument to ``True``.
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

.. jupyter-execute::

qc5 = qc2.compose(qc1, front=True)
qc5.draw()

:meth:`~qiskit.circuit.QuantumCircuit.append()`
-----------------------------------------------

In order to combine two circuits with :meth:`~qiskit.circuit.QuantumCircuit.append()`, you have to specify the circuit you want to add and the qubits and classical bits (if there are any) into which you want the circuit to be inserted.
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

This method changes the circuit to which it is applied instead of returning another one.
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

.. jupyter-execute::

qc2.append(qc1, qargs=[3,1], cargs=[1])
qc2.draw(cregbundle=False)
HuangJunye marked this conversation as resolved.
Show resolved Hide resolved

Unlike :meth:`~qiskit.circuit.QuantumCircuit.compose()`, :meth:`~qiskit.circuit.QuantumCircuit.append()` turns the smaller circuit into a single :class:`~qiskit.circuit.Instruction`, so in order to unroll it you can use :meth:`~qiskit.circuit.QuantumCircuit.decompose()`

.. jupyter-execute::

qc2.decompose().draw()


.. jupyter-execute::

import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright



Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved
81 changes: 81 additions & 0 deletions docs/how_to/create_a_parameterized_circuit.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
==============================
Create a parameterized circuit
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved
==============================

This guide will show how to create a :class:`~qiskit.circuit.QuantumCircuit` that includes parameters.

Define the parameters
=====================

In order to define a parameter, you need to create a :class:`~qiskit.circuit.Parameter` object. To do that you only need to choose a ``name``, that can be any unicode string like ``'θ'``.

.. jupyter-execute::

from qiskit.circuit import Parameter

theta = Parameter('θ')

Create the parameterized circuit
================================

When creating the circuit you can include the :class:`~qiskit.circuit.Parameter` as if it was a defined number.

.. jupyter-execute::

from qiskit import QuantumCircuit

qc = QuantumCircuit(1)
qc.rx(theta, 0)
qc.draw('mpl')

Assign values to parameters
===========================

You can use these two methods to assign values to the :class:`~qiskit.circuit.Parameter`\ s in your circuit:

* :meth:`~qiskit.circuit.QuantumCircuit.bind_parameters()`
* :meth:`~qiskit.circuit.QuantumCircuit.assign_parameters()`

:meth:`~qiskit.circuit.QuantumCircuit.bind_parameters()`
--------------------------------------------------------

In order to use this method, you have to specify either a dictionary of the form ``{parameter: value,...}`` or an iterable formed only by numeric values, that will be assigned following the order from :attr:`~qiskit.circuit.QuantumCircuit.parameters`.

.. jupyter-execute::

import numpy as np

theta_values = [0, np.pi/2, np.pi]
qc_bind_list = [qc.bind_parameters({theta: theta_value}) for theta_value in theta_values]

for i in range(3):
display(qc_bind_list[i].draw('mpl'))

:meth:`~qiskit.circuit.QuantumCircuit.assign_parameters()`
----------------------------------------------------------

This method works identically like :meth:`~qiskit.circuit.QuantumCircuit.bind_parameters()` except that you can also assign other :class:`~qiskit.circuit.Parameter` objects instead of only numbers to the :class:`~qiskit.circuit.Parameter`\ s in your circuit.

.. jupyter-execute::

phi = Parameter('ϕ')

theta_values = [np.pi/2, phi]
qc_assign_list = [qc.assign_parameters({theta: theta_value}) for theta_value in theta_values]

for i in range(2):
display(qc_assign_list[i].draw('mpl'))

Another difference between :meth:`~qiskit.circuit.QuantumCircuit.bind_parameters()` and :meth:`~qiskit.circuit.QuantumCircuit.assign_parameters()` is that for the latter, you can make it change your original circuit instead of creating a new one by setting the ``inplace`` argument to ``True``.

.. jupyter-execute::

qc.assign_parameters({theta: np.pi/4}, inplace=True)
qc.draw('mpl')


.. jupyter-execute::

import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
114 changes: 114 additions & 0 deletions docs/how_to/create_a_quantum_circuit.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@

========================
Create a quantum circuit
========================

This guide shows how to initialize a quantum circuit.
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

There are two ways to create a :class:`~qiskit.circuit.QuantumCircuit` object:

* Specifying the number of qubits and bits.
* Creating :class:`~qiskit.circuit.QuantumRegister`\ s and :class:`~qiskit.circuit.ClassicalRegister`\ s

Create from number of qubits and bits
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved
=====================================

In order to create a :class:`~qiskit.circuit.QuantumCircuit` by only specifying the number of bits and qubits, you need to follow these steps.

.. jupyter-execute::

from qiskit import QuantumCircuit

# Initialize number of qubits and classical bits
n_qubits = 3
n_bits = 2

# Create the circuit
qc = QuantumCircuit(n_qubits, n_bits)
qc.draw()


If you don't want to include any classical bits, you don't have to write ``QuantumCircuit(n_qubits,0)`` but you can omit the number of classical bits.

.. jupyter-execute::

from qiskit import QuantumCircuit

qc = QuantumCircuit(n_qubits)
qc.draw()

Create from quantum and classical registers
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above, just using "create" on it's own like this feels a bit odd grammatically. I think using something like "create a circuit from..." is a bit clearer

===========================================
Copy link
Collaborator

Choose a reason for hiding this comment

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

A how to guide should provide tips for users to decide how to choose different options of the same task. Can you comment on when people should use this method and when they should use the simpler method with specifying only number of qubits and classical bits? For example, the simpler method can only create circuits with one quantum register and one classical register. And it also can't specify names to the registers.


Create quantum registers
HuangJunye marked this conversation as resolved.
Show resolved Hide resolved
------------------------

In order to create a quantum register, you have to define a :class:`~qiskit.circuit.QuantumRegister` object, passing as argument the desired number of qubits.

.. jupyter-execute::

from qiskit import QuantumRegister

# Create QuantumRegister formed by 2 qubits
qr1 = QuantumRegister(2)

# Create QuantumRegister formed by 3 qubits
qr2 = QuantumRegister(3)
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

Create classical registers
HuangJunye marked this conversation as resolved.
Show resolved Hide resolved
--------------------------

Analogously to the quantum registers, a classical register can be created by defining a :class:`~qiskit.circuit.ClassicalRegister` object, passing the number of classical bits as an argument.

.. jupyter-execute::

from qiskit import ClassicalRegister

# Create classical register with 2 classical bits
cr1 = ClassicalRegister(2)

# Create classical register with 1 classical bit
cr2 = ClassicalRegister(1)
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

Initialize the quantum circuit
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be good to align the language used in this headings, so either:

Creating quantum registers
...
Creating classical registers
...
Create a quantum circuit
...

or:

Initializing quantum registers
...
Initializing classical registers
...
Initialize a quantum circuit
...

------------------------------

Now that you have defined the quantum and classical registers, you can define a :class:`~qiskit.circuit.QuantumCircuit` from them. Each register has to be introduced as a separate argument.

.. jupyter-execute::

# Create the quantum circuit from the registers
qc = QuantumCircuit(qr1, qr2, cr1, cr2)
qc.draw()

You can put the registers in any order, even mixing classical and quantum. However, the relative order of the :class:`~qiskit.circuit.QuantumRegister`\ s does affect the order of the qubits on the final circuit. In particular, the qubits from the first :class:`~qiskit.circuit.QuantumRegister` will be the first and so on. The same applies to the :class:`~qiskit.circuit.ClassicalRegister`\ s.

.. jupyter-execute::

# Both the classical and quantum registers have the same relative order as in qc
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved
qc1 = QuantumCircuit(qr1, cr1, qr2, cr2)

qc == qc1


.. jupyter-execute::

# We change the order of the quantum registers
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved
qc2 = QuantumCircuit(qr2, qr1, cr1, cr2)

qc == qc2



.. jupyter-execute::

qc2.draw()



.. jupyter-execute::

import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright

97 changes: 97 additions & 0 deletions docs/how_to/visualize_a_quantum_circuit.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
===========================
Visualize a quantum circuit
===========================

This guide shows how to get a visual representation of a quantum circuit.
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

Build the circuit
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved
=================

The first step is to create the circuit.
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

.. jupyter-execute::

from qiskit import QuantumCircuit

qc = QuantumCircuit(3, 3)
qc.h(range(3))
qc.cx(0, 1)
qc.measure(range(3), range(3))

Visualize the circuit
=====================

There are three different ways to visualize a circuit. You can use

* The ``print()`` function.
* The :meth:`~qiskit.circuit.QuantumCircuit.draw()` method.
* The :func:`~qiskit.visualization.circuit_drawer()` function.

``print()``
-----------
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

If you call the ``print()`` function on a :class:`~qiskit.circuit.QuantumCircuit` object, you will get an `ASCII art version <https://en.wikipedia.org/wiki/ASCII_art>`_ of the circuit diagram.

.. jupyter-execute::

print(qc)

:meth:`~qiskit.circuit.QuantumCircuit.draw()`
---------------------------------------------

You can also call the :meth:`~qiskit.circuit.QuantumCircuit.draw()` method on a :class:`~qiskit.circuit.QuantumCircuit` object to visualize it. If you don't specify any arguments you will get a plain text representation of the circuit.

.. jupyter-execute::

qc.draw()

However, if you change the ``output`` argument, you can get other different renderings. The available options for this argument are:

* ``'text'``: renders the circuit with ASCII art. It's the default option.
* ``'mpl'``: uses `matplotlib <https://matplotlib.org/>`_ to render the circuit.
* ``'latex'``: uses :math:`\LaTeX` to render the circuit. It requires a full `LaTeX <https://latex.org/forum/>`_ distribution and the package ``pdflatex``.
* ``'latex_source'``: outputs the :math:`\LaTeX` source code that creates the ``'latex'`` rendering of the circuit.
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

Because this optional or keyword argument is actually the first of this method, one can type ``qc.draw(option)`` instead of ``qc.draw(output=option)``.
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

.. note::
By default, the ``draw()`` method returns the rendered image as an object and does not output anything. The exact class returned depends on the output specified: ``'text'`` (the default) returns a ``TextDrawer`` object, ``'mpl'`` returns a ``matplotlib.figure.Figure`` object, and ``'latex'`` returns a ``PIL.Image`` object. Having the return types enables modifying or directly interacting with the rendered output from the drawers. Jupyter notebooks understand these return types and render them for us in this guide, but when running outside of Jupyter, you do not have this feature automatically. However, the ``draw()`` method has optional arguments to display or save the output. When specified, the ``filename`` kwarg takes a path to which it saves the rendered output. Alternatively, if you're using the ``'mpl'`` or ``'latex'`` outputs, you can leverage the ``interactive`` kwarg to open the image in a new window (this will not always work from within a notebook but will be demonstrated anyway).


``'mpl'``
^^^^^^^^^
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

.. jupyter-execute::

qc.draw('mpl')



HuangJunye marked this conversation as resolved.
Show resolved Hide resolved
``'latex_source'``
^^^^^^^^^^^^^^^^^^
Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved

.. jupyter-execute::

qc.draw('latex_source')


:func:`~qiskit.visualization.circuit_drawer()`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If you prefer to use a self-contained function instead of a :class:`~qiskit.circuit.QuantumCircuit` method to draw your circuit, you can do it with :func:`~qiskit.visualization.circuit_drawer()` from :mod:`qiskit.visualization`. It has the exact same behavior as the :meth:`~qiskit.circuit.QuantumCircuit.draw()` method above, except that it requires the circuit to be included as an argument.

.. note::
In Qiskit Terra :math:`\leq 0.7`, the default behavior for the ``circuit_drawer()`` function is to use the ``'latex'`` output backend, and in :math:`0.6.x` that includes a fallback to ``'mpl'`` if ``'latex'`` fails for any reason. Starting with release :math:`> 0.7`, the default changes to the ``'text'`` output.


.. jupyter-execute::

from qiskit.visualization import circuit_drawer

circuit_drawer(qc, output='mpl')

.. jupyter-execute::

import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Loading