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

Add how-to guides about primitives #9716

Merged
merged 96 commits into from
May 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 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
5a30873
Remove other how-tos
Guillermo-Mijares-Vilarino Mar 3, 2023
54071ee
Remove links
Guillermo-Mijares-Vilarino Mar 3, 2023
89da1ac
Added reference to other implementations of primitives
Guillermo-Mijares-Vilarino Mar 6, 2023
130f5ac
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino Mar 7, 2023
8f83d18
Improved titles
Guillermo-Mijares-Vilarino Mar 9, 2023
6daed2f
set global doctest flags and disable automatic doctests
Guillermo-Mijares-Vilarino Mar 9, 2023
ffbc8de
Added part about changing options
Guillermo-Mijares-Vilarino Mar 9, 2023
bc3da86
Merge branch 'main' into add-primitive-guides
Guillermo-Mijares-Vilarino Mar 10, 2023
8fc6f30
Add new aer docs page to intersphinx
Guillermo-Mijares-Vilarino Mar 10, 2023
e9f7924
Added notes about circuit measurements
Guillermo-Mijares-Vilarino Mar 23, 2023
cdf6745
Improved notes about circuit measurements
Guillermo-Mijares-Vilarino Mar 23, 2023
16977be
Merge branch 'main' into add-primitive-guides
Guillermo-Mijares-Vilarino Mar 28, 2023
6f837cc
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino Mar 30, 2023
9ad583a
Update docs/how_to/use_sampler.rst
Guillermo-Mijares-Vilarino Mar 30, 2023
1dc2ef7
Update docs/how_to/use_sampler.rst
Guillermo-Mijares-Vilarino Mar 30, 2023
25141f2
Update docs/how_to/use_sampler.rst
Guillermo-Mijares-Vilarino Mar 30, 2023
9c92b80
Added numpy to intersphinx and note about doctest and plot directive
Guillermo-Mijares-Vilarino Mar 30, 2023
bbd57b1
Added note about quasi-probabilities
Guillermo-Mijares-Vilarino Mar 30, 2023
ce362e1
Merge branch 'main' into add-primitive-guides
HuangJunye Mar 31, 2023
053b7c6
rename how to to How-to Guides
HuangJunye Mar 31, 2023
cf8def3
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
1e1044c
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
6a7c92c
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
3d7ee62
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
215a0a8
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
919e316
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
f0dd1ab
Update docs/how_to/use_sampler.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
849396f
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
d514216
Update docs/how_to/use_sampler.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
645792f
Update docs/how_to/use_sampler.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
6d89eb0
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
f37e2e5
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
f27d7ee
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
1d6e25a
Update docs/how_to/use_sampler.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
bf39db2
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
bc24efe
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
38ce964
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
80213cc
Update docs/how_to/use_sampler.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
0e170c3
Update docs/how_to/use_sampler.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
af5aceb
Update docs/how_to/use_sampler.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
d653451
Update docs/how_to/use_sampler.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
f46be30
Update docs/how_to/use_sampler.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
87de7c0
Update docs/how_to/use_sampler.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
0255ce8
Update docs/how_to/use_sampler.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
785bdd2
Remove generally
Guillermo-Mijares-Vilarino Apr 4, 2023
47c4e27
Changed sampler initial note to mention BackendSampler
Guillermo-Mijares-Vilarino Apr 4, 2023
18c90cc
Update docs/how_to/use_sampler.rst
Guillermo-Mijares-Vilarino Apr 4, 2023
8906ea8
Added code example for backend primitives and link to providers page
Guillermo-Mijares-Vilarino Apr 5, 2023
e60b253
Merge branch 'main' into add-primitive-guides
Guillermo-Mijares-Vilarino Apr 5, 2023
32ab2f3
Update intersphinx mapping to ecosystem for aer and runtime
Guillermo-Mijares-Vilarino Apr 18, 2023
23fbd02
Merge branch 'main' into add-primitive-guides
Guillermo-Mijares-Vilarino Apr 18, 2023
f819ebe
Change rustworkx link
Guillermo-Mijares-Vilarino Apr 18, 2023
d4c5802
Merge branch 'main' into add-primitive-guides
HuangJunye May 9, 2023
c125f06
Merge branch 'main' into add-primitive-guides
Guillermo-Mijares-Vilarino May 10, 2023
b352958
Add "primitive" to estimator how-to title
Guillermo-Mijares-Vilarino May 10, 2023
278df5a
Change hypothetical import to avoid confusion
Guillermo-Mijares-Vilarino May 10, 2023
e51e29e
Update docs/how_to/use_estimator.rst
Guillermo-Mijares-Vilarino May 10, 2023
644d8c7
Include "primitive" word in sampler how-to title
Guillermo-Mijares-Vilarino May 10, 2023
1607aac
Improve phrasing
Guillermo-Mijares-Vilarino May 10, 2023
36d54f3
Include notice about doctest and plot directive incompatibility in sa…
Guillermo-Mijares-Vilarino May 10, 2023
254c8de
change->modify sampler options
Guillermo-Mijares-Vilarino May 10, 2023
3ee6158
change qiskit_provider to <some_qiskit_provider>
Guillermo-Mijares-Vilarino May 10, 2023
004f4ad
shots->amount of shots in estimator how-to
Guillermo-Mijares-Vilarino May 10, 2023
3d7e5a8
Add quick explanation about using multiple circuits and observables a…
Guillermo-Mijares-Vilarino May 10, 2023
51a1260
singular
1ucian0 May 19, 2023
973f1e0
singular
1ucian0 May 19, 2023
9418b52
Merge branch 'main' into add-primitive-guides
1ucian0 May 19, 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: 6 additions & 10 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@
modindex_common_prefix = ["qiskit."]

intersphinx_mapping = {
"retworkx": ("https://qiskit.org/documentation/retworkx/", None),
"qiskit-ibm-runtime": ("https://qiskit.org/documentation/partners/qiskit_ibm_runtime/", None),
"qiskit-aer": ("https://qiskit.org/documentation/aer/", None),
"rustworkx": ("https://qiskit.org/ecosystem/rustworkx/", None),
"qiskit-ibm-runtime": ("https://qiskit.org/ecosystem/ibm-runtime/", None),
"qiskit-aer": ("https://qiskit.org/ecosystem/aer/", None),
"numpy": ("https://numpy.org/doc/stable/", None)
}

Expand Down Expand Up @@ -116,17 +116,13 @@

autoclass_content = "both"

# -- Options for Doctest --------------------------------------------------------

import sphinx.ext.doctest
# -- Options for Doctest --------------------------------------------------------

# This option will make doctest ignore whitespace when testing code.
# It's specially important for circuit representation as it gives an
# error otherwise
doctest_default_flags = sphinx.ext.doctest.doctest.NORMALIZE_WHITESPACE
doctest_default_flags = doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE | doctest.IGNORE_EXCEPTION_DETAIL | doctest.DONT_ACCEPT_TRUE_FOR_1

# Leaving this string empty disables testing of doctest blocks from docstrings.
# Doctest blocks are structures like this one:
# >> code
# output
doctest_test_doctest_blocks = ""
doctest_test_doctest_blocks = ""
15 changes: 15 additions & 0 deletions docs/how_to/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.. _how_to:

#############
How-to Guides
#############


Use the primitives
==================

.. toctree::
:maxdepth: 1

use_sampler
use_estimator
269 changes: 269 additions & 0 deletions docs/how_to/use_estimator.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
#########################################################
Compute an expectation value with ``Estimator`` primitive
#########################################################

This guide shows how to get the expected value of an observable for a given quantum circuit with the :class:`~qiskit.primitives.Estimator` primitive.

.. note::

While this guide uses Qiskit’s reference implementation, the ``Estimator`` primitive can be run with any provider using :class:`~qiskit.primitives.BackendEstimator` .

.. code-block::

from qiskit.primitives import BackendEstimator
from <some_qiskit_provider> import QiskitProvider

provider = QiskitProvider()
backend = provider.get_backend('backend_name')
estimator = BackendEstimator(backend)

There are some providers that implement primitives natively (see `this page <http://qiskit.org/providers/#primitives>`_ for more details).


Initialize observables
======================

The first step is to define the observables whose expected value you want to compute. Each observable can be any ``BaseOperator``, like the operators from :mod:`qiskit.quantum_info`.
Among them it is preferable to use :class:`~qiskit.quantum_info.SparsePauliOp`.

.. testcode::

from qiskit.quantum_info import SparsePauliOp

observable = SparsePauliOp(["II", "XX", "YY", "ZZ"], coeffs=[1, 1, -1, 1])

Initialize quantum circuit
==========================

Then you need to create the :class:`~qiskit.circuit.QuantumCircuit`\ s for which you want to obtain the expected value.

.. plot::
:include-source:

from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0,1)
qc.draw("mpl")

.. testsetup::

HuangJunye marked this conversation as resolved.
Show resolved Hide resolved
# This code is repeated (but hidden) because we will need to use the variables with the extension sphinx.ext.doctest (testsetup/testcode/testoutput directives)
# and we can't reuse the variables from the plot directive above because they are incompatible.
# The plot directive is used to draw the circuit with matplotlib and the code is shown because of the include-source flag.

from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0,1)

.. note::

The :class:`~qiskit.circuit.QuantumCircuit` you pass to :class:`~qiskit.primitives.Estimator` must not include any measurements.

Initialize the ``Estimator``
============================

Then, you need to instantiate an :class:`~qiskit.primitives.Estimator`.

.. testcode::

from qiskit.primitives import Estimator

estimator = Estimator()
HuangJunye marked this conversation as resolved.
Show resolved Hide resolved

Run and get results
===================

Now that you have defined your ``estimator``, you can run your estimation by calling the :meth:`~qiskit.primitives.Estimator.run` method,
which returns an instance of :class:`~.PrimitiveJob` (subclass of :class:`~qiskit.providers.JobV1`). You can get the results from the job (as a :class:`~qiskit.primitives.EstimatorResult` object)
with the :meth:`~qiskit.providers.JobV1.result` method.

.. testcode::

job = estimator.run(qc, observable)
result = job.result()
print(result)

.. testoutput::

EstimatorResult(values=array([4.]), metadata=[{}])

While this example only uses one :class:`~qiskit.circuit.QuantumCircuit` and one observable, if you want to get expectation values for multiple circuits and observables you can
pass a ``list`` of :class:`~qiskit.circuit.QuantumCircuit`\ s and a list of ``BaseOperator``\ s to the :meth:`~qiskit.primitives.Estimator.run` method. Both ``list``\ s must have
the same length.

Get the expected value
----------------------

From these results you can extract the expected values with the attribute :attr:`~qiskit.primitives.EstimatorResult.values`.

:attr:`~qiskit.primitives.EstimatorResult.values` returns a :class:`numpy.ndarray`
whose ``i``-th element is the expectation value corresponding to the ``i``-th circuit and ``i``-th observable.

.. testcode::

exp_value = result.values[0]
print(exp_value)

Guillermo-Mijares-Vilarino marked this conversation as resolved.
Show resolved Hide resolved
.. testoutput::

3.999999999999999

Parameterized circuit with ``Estimator``
========================================

The :class:`~qiskit.primitives.Estimator` primitive can be run with unbound parameterized circuits like the one below.
You can also manually bind values to the parameters of the circuit and follow the steps
of the previous example.

.. testcode::

from qiskit.circuit import Parameter

theta = Parameter('θ')
param_qc = QuantumCircuit(2)
param_qc.ry(theta, 0)
param_qc.cx(0,1)
print(param_qc.draw())

.. testoutput::

┌───────┐
q_0: ┤ Ry(θ) ├──■──
└───────┘┌─┴─┐
q_1: ─────────┤ X ├
└───┘

The main difference with the previous case is that now you need to specify the sets of parameter values
for which you want to evaluate the expectation value as a ``list`` of ``list``\ s of ``float``\ s.
The ``i``-th element of the outer``list`` is the set of parameter values
that corresponds to the ``i``-th circuit and observable.

.. testcode::

import numpy as np

parameter_values = [[0], [np.pi/6], [np.pi/2]]

job = estimator.run([param_qc]*3, [observable]*3, parameter_values=parameter_values)
values = job.result().values

for i in range(3):
print(f"Parameter: {parameter_values[i][0]:.5f}\t Expectation value: {values[i]}")

.. testoutput::

Parameter: 0.00000 Expectation value: 2.0
Parameter: 0.52360 Expectation value: 3.0
Parameter: 1.57080 Expectation value: 4.0

Change run options
==================

Your workflow might require tuning primitive run options, such as the amount of shots.

By default, the reference :class:`~qiskit.primitives.Estimator` class performs an exact statevector
calculation based on the :class:`~qiskit.quantum_info.Statevector` class. However, this can be
modified to include shot noise if the number of ``shots`` is set.
For reproducibility purposes, a ``seed`` will also be set in the following examples.

There are two main ways of setting options in the :class:`~qiskit.primitives.Estimator`:

* Set keyword arguments in the :meth:`~qiskit.primitives.Estimator.run` method.
* Modify :class:`~qiskit.primitives.Estimator` options.

Set keyword arguments for :meth:`~qiskit.primitives.Estimator.run`
------------------------------------------------------------------

If you only want to change the settings for a specific run, it can be more convenient to
set the options inside the :meth:`~qiskit.primitives.Estimator.run` method. You can do this by
passing them as keyword arguments.

.. testcode::

job = estimator.run(qc, observable, shots=2048, seed=123)
result = job.result()
print(result)

.. testoutput::

EstimatorResult(values=array([4.]), metadata=[{'variance': 3.552713678800501e-15, 'shots': 2048}])

.. testcode::

print(result.values[0])

.. testoutput::

3.999999998697238

Modify :class:`~qiskit.primitives.Estimator` options
-----------------------------------------------------

If you want to keep some configuration values for several runs, it can be better to
change the :class:`~qiskit.primitives.Estimator` options. That way you can use the same
:class:`~qiskit.primitives.Estimator` object as many times as you wish without having to
rewrite the configuration values every time you use :meth:`~qiskit.primitives.Estimator.run`.

Modify existing :class:`~qiskit.primitives.Estimator`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If you prefer to change the options of an already-defined :class:`~qiskit.primitives.Estimator`, you can use
:meth:`~qiskit.primitives.Estimator.set_options` and introduce the new options as keyword arguments.

.. testcode::

estimator.set_options(shots=2048, seed=123)

job = estimator.run(qc, observable)
result = job.result()
print(result)

.. testoutput::

EstimatorResult(values=array([4.]), metadata=[{'variance': 3.552713678800501e-15, 'shots': 2048}])

.. testcode::

print(result.values[0])

.. testoutput::

3.999999998697238


Define a new :class:`~qiskit.primitives.Estimator` with the options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If you prefer to define a new :class:`~qiskit.primitives.Estimator` with new options, you need to
define a ``dict`` like this one:

.. testcode::

options = {"shots": 2048, "seed": 123}

And then you can introduce it into your new :class:`~qiskit.primitives.Estimator` with the
``options`` argument.

.. testcode::

estimator = Estimator(options=options)

job = estimator.run(qc, observable)
result = job.result()
print(result)

.. testoutput::

EstimatorResult(values=array([4.]), metadata=[{'variance': 3.552713678800501e-15, 'shots': 2048}])

.. testcode::

print(result.values[0])

.. testoutput::

3.999999998697238
Loading