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 all 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
184 changes: 184 additions & 0 deletions docs/how_to/compose_quantum_circuits.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#####################
Join quantum circuits
#####################

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

Create the circuits
===================

Let's first create two circuits, which will be joined together.

.. testcode::

from qiskit import QuantumCircuit

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

qc2 = QuantumCircuit(4,2)
qc2.y(0)
qc2.x(1)
qc2.cx(0,3)
qc2.measure(3,1)

print(qc1.draw())
print(qc2.draw())

.. testoutput::
:options: +NORMALIZE_WHITESPACE

┌───┐
q_0: ┤ H ├──■─────
└───┘┌─┴─┐┌─┐
q_1: ─────┤ X ├┤M├
└───┘└╥┘
c: 1/═══════════╩═
0
┌───┐
q_0: ┤ Y ├──■─────
├───┤ │
q_1: ┤ X ├──┼─────
└───┘ │
q_2: ───────┼─────
┌─┴─┐┌─┐
q_3: ─────┤ X ├┤M├
└───┘└╥┘
c: 2/═══════════╩═
1

Join the circuits
=================

You can join the circuits together using these two methods:

1. Using the :meth:`~.QuantumCircuit.compose` method
2. Using the :meth:`~.QuantumCircuit.append` method

.. warning::

The ``combine`` and ``extend`` methods have been deprecated in Qiskit Terra 0.17 and removed in 0.23. These methods are replaced by the :meth:`~.QuantumCircuit.compose` method which is more powerful. The removal of ``extend`` also means that the ``+`` and ``+=`` operators are no longer defined for :class:`~.QuantumCircuit`. Instead, you can use the ``&`` and ``&=`` operators respectively, which use :meth:`~.QuantumCircuit.compose`.

For both methods, if the two circuits being combined have different sizes, the method needs to be called in the circuit that is bigger (more qubits and more classical bits).

Using the :meth:`~.QuantumCircuit.compose` method
-------------------------------------------------

In order to join two circuits with :meth:`~.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:`~.QuantumCircuit.compose` does not modify the original circuit to which it is applied but returns a new joint circuit object. This can be changed by setting the ``inplace`` argument to ``True``.
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 put this sentence in a note box or a in brackets, as the following code example doesn't actually show how to use the inplace argument

Copy link
Contributor

Choose a reason for hiding this comment

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

alternatively it might be nice to add a short code snippet showing the use of the inplace arg


.. testcode::

qc3 = qc2.compose(qc1)
print(qc3.draw())
HuangJunye marked this conversation as resolved.
Show resolved Hide resolved

.. testoutput::
:options: +NORMALIZE_WHITESPACE

┌───┐ ┌───┐
q_0: ┤ Y ├──■──┤ H ├──■─────
├───┤ │ └───┘┌─┴─┐┌─┐
q_1: ┤ X ├──┼───────┤ X ├┤M├
└───┘ │ └───┘└╥┘
q_2: ───────┼─────────────╫─
┌─┴─┐ ┌─┐ ║
q_3: ─────┤ X ├─┤M├───────╫─
└───┘ └╥┘ ║
c: 2/════════════╩════════╩═
1 0

If you want to insert the qubits and bits into specific positions in the bigger circuit, you can use the ``qubits`` and ``bits`` arguments. The following example joins the two circuits by connecting `q_0` and `q_1` qubits of `qc1` circuit to `q_3` and `q_1` qubits of `qc2` circuit.

.. testcode::

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

.. testoutput::
:options: +NORMALIZE_WHITESPACE

┌───┐
q_0: ┤ Y ├──■──────────────────
├───┤ │ ┌───┐┌─┐
q_1: ┤ X ├──┼──────────┤ X ├┤M├
└───┘ │ └─┬─┘└╥┘
q_2: ───────┼────────────┼───╫─
┌─┴─┐┌─┐┌───┐ │ ║
q_3: ─────┤ X ├┤M├┤ H ├──■───╫─
└───┘└╥┘└───┘ ║
c: 2/═══════════╩════════════╩═
1 1

You can also join the smaller circuit in front of the bigger circuit by setting the ``front`` argument to ``True``.

.. testcode::

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

.. testoutput::
:options: +NORMALIZE_WHITESPACE

┌───┐ ┌───┐
q_0: ┤ H ├──■──┤ Y ├───────■─────
└───┘┌─┴─┐└┬─┬┘┌───┐ │
q_1: ─────┤ X ├─┤M├─┤ X ├──┼─────
└───┘ └╥┘ └───┘ │
q_2: ────────────╫─────────┼─────
║ ┌─┴─┐┌─┐
q_3: ────────────╫───────┤ X ├┤M├
║ └───┘└╥┘
c: 2/════════════╩═════════════╩═
0 1

Using the :meth:`~.QuantumCircuit.append` method
------------------------------------------------

In order to join two circuits with :meth:`~.QuantumCircuit.append`, you need to specify the circuit you want to add, as well as the qubits and classical bits (if there are any) onto which you want the circuit to be applied.

Different from :meth:`~.QuantumCircuit.compose`, this method modifies the circuit it is applied to, instead of returning a new circuit.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Different from :meth:`~.QuantumCircuit.compose`, this method modifies the circuit it is applied to, instead of returning a new circuit.
Unlike :meth:`~.QuantumCircuit.compose`, this method modifies the circuit it is applied to, instead of returning a new circuit.


.. testcode::

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

.. code-block:: text

┌───┐
q_0: ┤ Y ├──■─────────────────────
├───┤ │ ┌──────────────┐
q_1: ┤ X ├──┼─────┤1 ├
└───┘ │ │ │
q_2: ───────┼─────┤ ├
┌─┴─┐┌─┐│ │
q_3: ─────┤ X ├┤M├┤0 circuit-101 ├
└───┘└╥┘│ │
c_0: ═══════════╬═╡ ╞
║ │ │
c_1: ═══════════╩═╡0 ╞
└──────────────┘

Unlike :meth:`~.QuantumCircuit.compose`, :meth:`~.QuantumCircuit.append` turns the smaller circuit into a single :class:`~qiskit.circuit.Instruction`. If you prefer joining the circuits using the individual gates, you can use :meth:`~.QuantumCircuit.decompose` to decompose the joint circuit.

.. testcode::

print(qc2.decompose().draw())

.. testoutput::
:options: +NORMALIZE_WHITESPACE

┌───────────────┐
q_0: ┤ U3(π,π/2,π/2) ├──■──────────────────
└─┬───────────┬─┘ │ ┌───┐┌─┐
q_1: ──┤ U3(π,0,π) ├────┼──────────┤ X ├┤M├
└───────────┘ │ └─┬─┘└╥┘
q_2: ───────────────────┼────────────┼───╫─
┌─┴─┐┌─┐┌───┐ │ ║
q_3: ─────────────────┤ X ├┤M├┤ H ├──■───╫─
└───┘└╥┘└───┘ ║
c: 2/═══════════════════════╩════════════╩═
1 1
114 changes: 114 additions & 0 deletions docs/how_to/create_a_parameterized_circuit.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
######################################
Create a parameterized quantum circuit
######################################

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

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

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

.. testcode::

from qiskit.circuit import Parameter

theta = Parameter('θ')


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

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

.. testcode::

from qiskit import QuantumCircuit

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

.. testoutput::
:options: +NORMALIZE_WHITESPACE

┌───────┐
q: ┤ Rx(θ) ├
└───────┘


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

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

* :meth:`~.QuantumCircuit.bind_parameters`
* :meth:`~.QuantumCircuit.assign_parameters`

:meth:`~.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. If using only numeric values they will be bound to their corresponding parameters in according to the order in :attr:`~.QuantumCircuit.parameters`.

.. testcode::

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):
print(qc_bind_list[i].draw())

.. testoutput::
:options: +NORMALIZE_WHITESPACE

┌───────┐
q: ┤ Rx(0) ├
└───────┘
┌─────────┐
q: ┤ Rx(π/2) ├
└─────────┘
┌───────┐
q: ┤ Rx(π) ├
└───────┘

:meth:`~.QuantumCircuit.assign_parameters`
----------------------------------------------------------

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

.. testcode::

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):
print(qc_assign_list[i].draw())

.. testoutput::
:options: +NORMALIZE_WHITESPACE

┌─────────┐
q: ┤ Rx(π/2) ├
└─────────┘
┌───────┐
q: ┤ Rx(ϕ) ├
└───────┘


Another difference between :meth:`~.QuantumCircuit.bind_parameters` and :meth:`~.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``.
Copy link
Contributor

Choose a reason for hiding this comment

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

This in place argument feels similar to the one in the previous how to guide, I think it would be good to use the same format for the explanation in both.


.. testcode::

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

.. testoutput::
:options: +NORMALIZE_WHITESPACE

┌─────────┐
q: ┤ Rx(π/4) ├
└─────────┘
Loading