mirror of https://github.com/Qiskit/qiskit.git
Adding terra documentation (Qiskit/qiskit-metapackage#35)
This commit is contained in:
parent
82e5e4f173
commit
f19aa5b456
|
@ -0,0 +1,671 @@
|
|||
|
||||
|
||||
|
||||
Getting Started with Qiskit
|
||||
===========================
|
||||
|
||||
Here, we provide an overview of working with Qiskit. Qiskit provides the
|
||||
basic building blocks necessary to program quantum computers. The
|
||||
foundation of Qiskit is the Terra element. The basic concept of Qiskit
|
||||
Terra is an array of quantum circuits. A workflow using Terra consists
|
||||
of two stages: **Build** and **Execute**. **Build** allows you to make
|
||||
different quantum circuits that represent the problem you are solving,
|
||||
and **Execute** allows you to run them on different backends. After the
|
||||
jobs have been run, the data is collected. There are methods for putting
|
||||
this data together, depending on the program. This either gives you the
|
||||
answer you wanted, or allows you to make a better program for the next
|
||||
instance.
|
||||
|
||||
**Contents**
|
||||
|
||||
`Circuit basics <#circuit_basics>`__
|
||||
|
||||
`Simulating circuits with Qiskit Aer <#aer_simulation>`__
|
||||
|
||||
`Running circuits using the IBMQ provider <#ibmq_provider>`__
|
||||
|
||||
**Code imports**
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
import numpy as np
|
||||
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
|
||||
from qiskit import execute
|
||||
|
||||
Circuit Basics
|
||||
---------------
|
||||
|
||||
Building the circuit
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The basic elements needed for your first program are the QuantumCircuit,
|
||||
and QuantumRegister.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
# Create a Quantum Register with 3 qubits.
|
||||
q = QuantumRegister(3, 'q')
|
||||
|
||||
# Create a Quantum Circuit acting on the q register
|
||||
circ = QuantumCircuit(q)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<div class="alert alert-block alert-info">
|
||||
|
||||
Note: Naming the QuantumRegister is optional and not required.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</div>
|
||||
|
||||
After you create the circuit with its registers, you can add gates
|
||||
(“operations”) to manipulate the registers. As you proceed through the
|
||||
documentation you will find more gates and circuits; the below is an
|
||||
example of a quantum circuit that makes a three-qubit GHZ state
|
||||
|
||||
.. math:: |\psi\rangle = \left(|000\rangle+|111\rangle\right)/\sqrt{2}.
|
||||
|
||||
To create such a state, we start with a 3-qubit quantum register. By
|
||||
default, each qubit in the register is initialized to :math:`|0\rangle`.
|
||||
To make the GHZ state, we apply the following gates: \* A Hadamard gate
|
||||
:math:`H` on qubit 0, which puts it into a superposition state. \* A
|
||||
controlled-Not operation (:math:`C_{X}`) between qubit 0 and qubit 1. \*
|
||||
A controlled-Not operation between qubit 0 and qubit 2.
|
||||
|
||||
On an ideal quantum computer, the state produced by running this circuit
|
||||
would be the GHZ state above.
|
||||
|
||||
In Qiskit Terra, operations can be added to the circuit one-by-one, as
|
||||
shown below.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
# Add a H gate on qubit 0, putting this qubit in superposition.
|
||||
circ.h(q[0])
|
||||
# Add a CX (CNOT) gate on control qubit 0 and target qubit 1, putting
|
||||
# the qubits in a Bell state.
|
||||
circ.cx(q[0], q[1])
|
||||
# Add a CX (CNOT) gate on control qubit 0 and target qubit 2, putting
|
||||
# the qubits in a GHZ state.
|
||||
circ.cx(q[0], q[2])
|
||||
|
||||
|
||||
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
<qiskit.extensions.standard.cx.CnotGate at 0xa20709128>
|
||||
|
||||
|
||||
|
||||
Visualize Circuit
|
||||
-----------------
|
||||
|
||||
You can visualize your circuit using Qiskit Terra
|
||||
``QuantumCircuit.draw()``, which plots circuit in the form found in many
|
||||
textbooks.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
circ.draw()
|
||||
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<pre style="word-wrap: normal;white-space: pre;line-height: 15px;"> ┌───┐
|
||||
q_0: |0>┤ H ├──■────■──
|
||||
└───┘┌─┴─┐ │
|
||||
q_1: |0>─────┤ X ├──┼──
|
||||
└───┘┌─┴─┐
|
||||
q_2: |0>──────────┤ X ├
|
||||
└───┘</pre>
|
||||
|
||||
|
||||
|
||||
In this circuit, the qubits are put in order with qubit zero at the top
|
||||
and qubit two at the bottom. The circuit is read left-to-right (meaning
|
||||
that gates which are applied earlier in the circuit show up further to
|
||||
the left).
|
||||
|
||||
Simulating circuits using Qiskit Aer
|
||||
-------------------------------------
|
||||
|
||||
Qiskit Aer is our package for simulating quantum circuits. It provides
|
||||
many different backends for doing a simulation. Here we use the basic
|
||||
python version.
|
||||
|
||||
Statevector backend
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The most common backend in Qiskit Aer is the ``statevector_simulator``.
|
||||
This simulator returns the quantum state which is a complex vector of
|
||||
dimensions :math:`2^n` where :math:`n` is the number of qubits (so be
|
||||
careful using this as it will quickly get too large to run on your
|
||||
machine).
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<div class="alert alert-block alert-info">
|
||||
|
||||
When representing the state of a multi-qubit system, the tensor order
|
||||
used in qiskit is different than that use in most physics textbooks.
|
||||
Suppose there are :math:`n` qubits, and qubit :math:`j` is labeled as
|
||||
:math:`Q_{j}`. In most textbooks (such as Nielsen and Chuang’s “Quantum
|
||||
Computation and Information”), the basis vectors for the :math:`n`-qubit
|
||||
state space would be labeled as
|
||||
:math:`Q_{0}\otimes Q_{1} \otimes \cdots \otimes Q_{n}`. **This is not
|
||||
the ordering used by qiskit!** Instead, qiskit uses an ordering in which
|
||||
the :math:`n^{\mathrm{th}}` qubit is on the *left* side of the tesnsor
|
||||
product, so that the basis vectors are labeled as
|
||||
:math:`Q_n\otimes \cdots \otimes Q_1\otimes Q_0`.
|
||||
|
||||
For example, if qubit zero is in state 0, qubit 1 is in state 0, and
|
||||
qubit 2 is in state 1, qiskit would represent this state as
|
||||
:math:`|100\rangle`, whereas most physics textbooks would represent it
|
||||
as :math:`|001\rangle`.
|
||||
|
||||
This difference in labeling affects the way multi-qubit operations are
|
||||
represented as matrices. For example, qiskit represents a controlled-X
|
||||
(:math:`C_{X}`) operation with qubit 0 being the control and qubit 1
|
||||
being the target as
|
||||
|
||||
.. math:: C_X = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\\end{pmatrix}.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</div>
|
||||
|
||||
To run the above circuit using the statevector simulator, first you need
|
||||
to import Aer and then set the backend to ``statevector_simulator``.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
# Import Aer
|
||||
from qiskit import BasicAer
|
||||
|
||||
# Run the quantum circuit on a statevector simulator backend
|
||||
backend = BasicAer.get_backend('statevector_simulator')
|
||||
|
||||
Now we have chosen the backend it’s time to compile and run the quantum
|
||||
circuit. In Qiskit Terra we provide the ``execute`` function for this.
|
||||
``execute`` returns a ``job`` object that encapsulates information about
|
||||
the job submitted to the backend.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<div class="alert alert-block alert-info">
|
||||
|
||||
Tip: You can obtain the above parameters in Jupyter. Simply place the
|
||||
text cursor on a function and press Shift+Tab.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</div>
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
# Create a Quantum Program for execution
|
||||
job = execute(circ, backend)
|
||||
|
||||
When you run a program, a job object is made that has the following two
|
||||
useful methods: ``job.status()`` and ``job.result()`` which return the
|
||||
status of the job and a result object respectively.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<div class="alert alert-block alert-info">
|
||||
|
||||
Note: Jobs run asynchronously but when the result method is called it
|
||||
switches to synchronous and waits for it to finish before moving on to
|
||||
another task.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</div>
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
result = job.result()
|
||||
|
||||
The results object contains the data and Qiskit Terra provides the
|
||||
method ``result.get_statevector(circ)`` to return the state vector for
|
||||
the quantum circuit.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
outputstate = result.get_statevector(circ, decimals=3)
|
||||
print(outputstate)
|
||||
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
[0.707+0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j
|
||||
0.707+0.j]
|
||||
|
||||
|
||||
Qiskit Terra also provides a visualization toolbox to allow you to view
|
||||
these results.
|
||||
|
||||
Below, we use the visualization function to plot the real and imaginary
|
||||
components of the state vector.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
from qiskit.tools.visualization import plot_state_city
|
||||
plot_state_city(outputstate)
|
||||
|
||||
|
||||
|
||||
|
||||
.. image:: getting_started_with_qiskit_terra_files/getting_started_with_qiskit_terra_21_0.png
|
||||
|
||||
|
||||
|
||||
Unitary backend
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Qiskit Aer also includes a ``unitary_simulator`` that works *provided
|
||||
all the elements in the circuit are unitary operations*. This backend
|
||||
calculates the :math:`2^n \times 2^n` matrix representing the gates in
|
||||
the quantum circuit.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
# Run the quantum circuit on a unitary simulator backend
|
||||
backend = BasicAer.get_backend('unitary_simulator')
|
||||
job = execute(circ, backend)
|
||||
result = job.result()
|
||||
|
||||
# Show the results
|
||||
print(result.get_unitary(circ, decimals=3))
|
||||
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
[[ 0.707+0.j 0.707+0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j
|
||||
0. +0.j 0. +0.j]
|
||||
[ 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j
|
||||
0.707+0.j -0.707+0.j]
|
||||
[ 0. +0.j 0. +0.j 0.707+0.j 0.707+0.j 0. +0.j 0. +0.j
|
||||
0. +0.j 0. +0.j]
|
||||
[ 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0.707+0.j -0.707+0.j
|
||||
0. +0.j 0. +0.j]
|
||||
[ 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0.707+0.j 0.707+0.j
|
||||
0. +0.j 0. +0.j]
|
||||
[ 0. +0.j 0. +0.j 0.707+0.j -0.707+0.j 0. +0.j 0. +0.j
|
||||
0. +0.j 0. +0.j]
|
||||
[ 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j
|
||||
0.707+0.j 0.707+0.j]
|
||||
[ 0.707+0.j -0.707+0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j
|
||||
0. +0.j 0. +0.j]]
|
||||
|
||||
|
||||
OpenQASM backend
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The simulators above are useful because they provide information about
|
||||
the state output by the ideal circuit and the matrix representation of
|
||||
the circuit. However, a real experiment terminates by *measuring* each
|
||||
qubit (usually in the computational :math:`|0\rangle, |1\rangle` basis).
|
||||
Without measurement, we cannot gain information about the state.
|
||||
Measurements cause the quantum system to collapse into classical bits.
|
||||
|
||||
For example, suppose we make independent measurements on each qubit of
|
||||
the three-qubit GHZ state
|
||||
|
||||
.. math:: |\psi\rangle = |000\rangle +|111\rangle)/\sqrt{2},
|
||||
|
||||
and let :math:`xyz` denote the bitstring that results. Recall that,
|
||||
under the qubit labeling used by Qiskit, :math:`x` would correspond to
|
||||
the outcome on qubit 2, :math:`y` to the outcome on qubit 1, and
|
||||
:math:`z` to the outcome on qubit 0. This representation of the
|
||||
bitstring puts the most significant bit (MSB) on the left, and the least
|
||||
significant bit (LSB) on the right. This is the standard ordering of
|
||||
binary bitstrings. We order the qubits in the same way, which is why
|
||||
Qiskit uses a non-standard tensor product order.
|
||||
|
||||
The probability of obtaining outcome :math:`xyz` is given by
|
||||
|
||||
.. math:: \mathrm{Pr}(xyz) = |\langle xyz | \psi \rangle |^{2}.
|
||||
|
||||
By explicit computation, we see there are only two bitstrings that will
|
||||
occur: :math:`000` and :math:`111`. If the bitstring :math:`000` is
|
||||
obtained, the state of the qubits is :math:`|000\rangle`, and if the
|
||||
bitstring is :math:`111`, the qubits are left in the state
|
||||
:math:`|111\rangle`. The probability of obtaining 000 or 111 is the
|
||||
same; namely, 1/2:
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\mathrm{Pr}(000) &= |\langle 000 | \psi \rangle |^{2} = \frac{1}{2}\\
|
||||
\mathrm{Pr}(111) &= |\langle 111 | \psi \rangle |^{2} = \frac{1}{2}.
|
||||
\end{align}
|
||||
|
||||
To simulate a circuit that includes measurement, we need to add
|
||||
measurements to the original circuit above, and use a different Aer
|
||||
backend.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
# Create a Classical Register with 3 bits.
|
||||
c = ClassicalRegister(3, 'c')
|
||||
# Create a Quantum Circuit
|
||||
meas = QuantumCircuit(q, c)
|
||||
meas.barrier(q)
|
||||
# map the quantum measurement to the classical bits
|
||||
meas.measure(q,c)
|
||||
|
||||
# The Qiskit circuit object supports composition using
|
||||
# the addition operator.
|
||||
qc = circ+meas
|
||||
|
||||
#drawing the circuit
|
||||
qc.draw()
|
||||
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<pre style="word-wrap: normal;white-space: pre;line-height: 15px;"> ┌───┐ ░ ┌─┐
|
||||
q_0: |0>┤ H ├──■────■───░───────┤M├
|
||||
└───┘┌─┴─┐ │ ░ ┌─┐└╥┘
|
||||
q_1: |0>─────┤ X ├──┼───░────┤M├─╫─
|
||||
└───┘┌─┴─┐ ░ ┌─┐└╥┘ ║
|
||||
q_2: |0>──────────┤ X ├─░─┤M├─╫──╫─
|
||||
└───┘ ░ └╥┘ ║ ║
|
||||
c_0: 0 ═══════════════════╬══╬══╩═
|
||||
║ ║
|
||||
c_1: 0 ═══════════════════╬══╩════
|
||||
║
|
||||
c_2: 0 ═══════════════════╩═══════
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
This circuit adds a classical register, and three measurements that are
|
||||
used to map the outcome of qubits to the classical bits.
|
||||
|
||||
To simulate this circuit, we use the ``qasm_simulator`` in Qiskit Aer.
|
||||
Each run of this circuit will yield either the bitstring 000 or 111. To
|
||||
build up statistics about the distribution of the bitstrings (to, e.g.,
|
||||
estimate :math:`\mathrm{Pr}(000)`), we need to repeat the circuit many
|
||||
times. The number of times the circuit is repeated can be specified in
|
||||
the ``execute`` function, via the ``shots`` keyword.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
# Use Aer's qasm_simulator
|
||||
backend_sim = BasicAer.get_backend('qasm_simulator')
|
||||
|
||||
# Execute the circuit on the qasm simulator.
|
||||
# We've set the number of repeats of the circuit
|
||||
# to be 1024, which is the default.
|
||||
job_sim = execute(qc, backend_sim, shots=1024)
|
||||
|
||||
# Grab the results from the job.
|
||||
result_sim = job_sim.result()
|
||||
|
||||
Once you have a result object, you can access the counts via the
|
||||
function ``get_counts(circuit)``. This gives you the *aggregated* binary
|
||||
outcomes of the circuit you submitted.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
counts = result_sim.get_counts(qc)
|
||||
print(counts)
|
||||
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
{'000': 497, '111': 527}
|
||||
|
||||
|
||||
Approximately 50 percent of the time the output bitstring is 000. Qiskit
|
||||
Terra also provides a function ``plot_histogram`` which allows you to
|
||||
view the outcomes.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
from qiskit.tools.visualization import plot_histogram
|
||||
plot_histogram(counts)
|
||||
|
||||
|
||||
|
||||
|
||||
.. image:: getting_started_with_qiskit_terra_files/getting_started_with_qiskit_terra_33_0.png
|
||||
|
||||
|
||||
|
||||
The estimated outcome probabilities :math:`\mathrm{Pr}(000)` and
|
||||
:math:`\mathrm{Pr}(111)` are computed by taking the aggregate counts and
|
||||
dividing by the number of shots (times the circuit was repeated). Try
|
||||
changing the ``shots`` keyword in the ``execute`` function and see how
|
||||
the estimated probabilities change.
|
||||
|
||||
Running circuits using the IBMQ provider
|
||||
-----------------------------------------
|
||||
|
||||
To faciliate access to real quantum computing hardware, we have provided
|
||||
a simple API interface. To access IBMQ devices, you’ll need an API
|
||||
token. For the public IBM Q devices, you can generate an API token
|
||||
`here <https://quantumexperience.ng.bluemix.net/qx/account/advanced>`__
|
||||
(create an account if you don’t already have one). For Q Network
|
||||
devices, login to the q-console, click your hub, group, and project, and
|
||||
expand “Get Access” to generate your API token and access url.
|
||||
|
||||
Our IBMQ provider lets you run your circuit on real devices or on our
|
||||
HPC simulator. Currently, this provider exists within Qiskit, and can be
|
||||
imported as shown below. For details on the provider, see `The IBMQ
|
||||
Provider <the_ibmq_provider.ipynb>`__.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
from qiskit import IBMQ
|
||||
|
||||
After generating your API token, call,
|
||||
``IBMQ.save_account('MY_TOKEN')``. For Q Network users, you’ll also need
|
||||
to include your access url: ``IBMQ.save_account('MY_TOKEN', 'URL')``
|
||||
|
||||
This will store your IBMQ credentials in a local file. Unless your
|
||||
registration information has changed, you only need to do this once. You
|
||||
may now load your accounts by calling,
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
IBMQ.load_accounts()
|
||||
|
||||
Once your account has been loaded, you can view the list of backends
|
||||
available to you.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
print("Available backends:")
|
||||
IBMQ.backends()
|
||||
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
Available backends:
|
||||
|
||||
|
||||
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
[<IBMQBackend('ibmqx4') from IBMQ()>,
|
||||
<IBMQBackend('ibmq_16_melbourne') from IBMQ()>,
|
||||
<IBMQBackend('ibmq_qasm_simulator') from IBMQ()>,
|
||||
<IBMQBackend('ibmq_20_tokyo') from IBMQ(ibm-q-internal, research, yorktown)>,
|
||||
<IBMQBackend('ibmq_qasm_simulator') from IBMQ(ibm-q-internal, research, yorktown)>]
|
||||
|
||||
|
||||
|
||||
Running circuits on real devices
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Today’s quantum information processors are small and noisy, but are
|
||||
advancing at a fast pace. They provide a great opportunity to explore
|
||||
what `noisy, intermediate-scale quantum
|
||||
(NISQ) <https://arxiv.org/abs/1801.00862>`__ computers can do.
|
||||
|
||||
The IBMQ provider uses a queue to allocate the devices to users. We now
|
||||
choose a device with the least busy queue which can support our program
|
||||
(has at least 3 qubits).
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
from qiskit.providers.ibmq import least_busy
|
||||
|
||||
large_enough_devices = IBMQ.backends(filters=lambda x: x.configuration().n_qubits > 4 and
|
||||
not x.configuration().simulator)
|
||||
backend = least_busy(large_enough_devices)
|
||||
print("The best backend is " + backend.name())
|
||||
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
The best backend is ibmqx4
|
||||
|
||||
|
||||
To run the circuit on the backend, we need to specify the number of
|
||||
shots and the number of credits we are willing to spend to run the
|
||||
circuit. Then, we execute the circuit on the backend using the
|
||||
``execute`` function.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
from qiskit.tools.monitor import job_monitor
|
||||
shots = 1024 # Number of shots to run the program (experiment); maximum is 8192 shots.
|
||||
max_credits = 3 # Maximum number of credits to spend on executions.
|
||||
|
||||
job_exp = execute(qc, backend=backend, shots=shots, max_credits=max_credits)
|
||||
job_monitor(job_exp)
|
||||
|
||||
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
HTML(value="<p style='font-size:16px;'>Job Status: job is being initialized </p>")
|
||||
|
||||
|
||||
``job_exp`` has a ``.result()`` method that lets us get the results from
|
||||
running our circuit.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<div class="alert alert-block alert-info">
|
||||
|
||||
Note: When the .result() method is called, the code block will wait
|
||||
until the job has finished before releasing the cell.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</div>
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
result_exp = job_exp.result()
|
||||
|
||||
Like before, the counts from the execution can be obtained using
|
||||
``get_counts(qc)``
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
counts_exp = result_exp.get_counts(qc)
|
||||
plot_histogram([counts_exp,counts])
|
||||
|
||||
|
||||
|
||||
|
||||
.. image:: getting_started_with_qiskit_terra_files/getting_started_with_qiskit_terra_49_0.png
|
||||
|
||||
|
||||
|
||||
Simulating circuits using a HPC simulator
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The IBMQ provider also comes with a remote optimized simulator called
|
||||
``ibmq_qasm_simulator``. This remote simulator is capable of simulating
|
||||
up to 32 qubits. It can be used the same way as the remote real
|
||||
backends.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
backend = IBMQ.get_backend('ibmq_qasm_simulator', hub=None)
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
shots = 1024 # Number of shots to run the program (experiment); maximum is 8192 shots.
|
||||
max_credits = 3 # Maximum number of credits to spend on executions.
|
||||
|
||||
job_hpc = execute(qc, backend=backend, shots=shots, max_credits=max_credits)
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
result_hpc = job_hpc.result()
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
counts_hpc = result_hpc.get_counts(qc)
|
||||
plot_histogram(counts_hpc)
|
||||
|
||||
|
||||
|
||||
|
||||
.. image:: getting_started_with_qiskit_terra_files/getting_started_with_qiskit_terra_54_0.png
|
||||
|
||||
|
||||
|
||||
Retrieving a previously ran job
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If your experiment takes longer to run then you have time to wait
|
||||
around, or if you simply want to retrieve old jobs back, the IBMQ
|
||||
backends allow you to do that. First you would need to note your job’s
|
||||
ID:
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
jobID = job_exp.job_id()
|
||||
|
||||
print('JOB ID: {}'.format(jobID))
|
||||
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
JOB ID: 5c1a2b4f39c21300575b61b0
|
||||
|
||||
|
||||
Given a job ID, that job object can be later reconstructed from the
|
||||
backend using retrieve_job:
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
job_get=backend.retrieve_job(jobID)
|
||||
|
||||
and then the results can be obtained from the new job object.
|
||||
|
||||
.. code:: ipython3
|
||||
|
||||
job_get.result().get_counts(qc)
|
||||
|
||||
|
||||
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
{'000': 393,
|
||||
'110': 32,
|
||||
'111': 340,
|
||||
'010': 43,
|
||||
'101': 124,
|
||||
'001': 14,
|
||||
'011': 48,
|
||||
'100': 30}
|
||||
|
||||
|
|
@ -0,0 +1,648 @@
|
|||
###############
|
||||
Release history
|
||||
###############
|
||||
|
||||
*************
|
||||
Release notes
|
||||
*************
|
||||
|
||||
Qiskit Terra 0.7.0
|
||||
==================
|
||||
|
||||
This release includes several new features and many bug fixes. With this
|
||||
release the interfaces for circuit diagram, histogram, bloch vectors,
|
||||
and state visualizations are declared stable. Additionally, this release includes a
|
||||
defined and standardized bit order/endianness throughout all aspects of Qiskit.
|
||||
These are all declared as stable interfaces in this release which won't have
|
||||
breaking changes made moving forward, unless there is appropriate and lengthy
|
||||
deprecation periods warning of any coming changes.
|
||||
|
||||
There is also the introduction of the following new features:
|
||||
|
||||
* A new ASCII art circuit drawing output mode
|
||||
* A new ciruit drawing interface off of QuantumCircuit objects. Now you can
|
||||
call ``circuit.draw()`` or ``print(circuit)`` and render a drawing of
|
||||
the circuit.
|
||||
* A visualizer for drawing the DAG representation of a circuit
|
||||
* A new quantum state plot type for hinton diagrams in the local matplotlib
|
||||
based state plots.
|
||||
* 2 new constructor methods off the ``QuantumCircuit`` class
|
||||
``from_qasm_str()`` and ``from_qasm_file()`` which let you easily create a
|
||||
circuit object from OpenQASM.
|
||||
* A new function ``plot_bloch_multivector()`` to plot Bloch vectors from a
|
||||
tensored state vector or density matrix
|
||||
* Per-shot measurement results are available in simulators and select devices.
|
||||
These can be accessed by setting the ``memory`` kwarg to ``True`` when
|
||||
calling ``compile()`` or ``execute()`` and then accessed using the
|
||||
``get_memory()`` method on the ``Result`` object.
|
||||
* A ``qiskit.quantum_info`` module with revamped Pauli objects and methods for
|
||||
working with quantum states.
|
||||
* New transpile passes for circuit analysis and transformation:
|
||||
CommutationAnalysis, CommutationTransformation, CXCancellation, Decompose,
|
||||
Unroll, Optimize1QGates, CheckMap, CXDirection, BarrierBeforeFinalMeasurements
|
||||
* New alternative swap mapper passes in the transpiler:
|
||||
BasicSwap, LookaheadSwap, StochasticSwap
|
||||
* More advanced transpiler infrastructure with support for analysis passes,
|
||||
transformation passes, a global property_set for the pass manager, and
|
||||
repeat-until control of passes.
|
||||
|
||||
|
||||
Upgrading to 0.7.0
|
||||
------------------
|
||||
|
||||
Please note that some backwards-incompatible changes have been made during this
|
||||
release. The following notes contain information on how to adapt to these
|
||||
changes.
|
||||
|
||||
Changes to Result objects
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
As part of the rewrite of the Results object to be more consistent and a
|
||||
stable interface moving forward a few changes have been made to how you access
|
||||
the data stored in the result object. First the ``get_data()`` method has been
|
||||
renamed to just ``data()``. Accompanying that change is a change in the data
|
||||
format returned by the function. It is now returning the raw data from the
|
||||
backends instead of doing any post-processing. For example, in previous
|
||||
versions you could call::
|
||||
|
||||
result = execute(circuit, backend).result()
|
||||
unitary = result.get_data()['unitary']
|
||||
print(unitary)
|
||||
|
||||
and that would return the unitary matrix like::
|
||||
|
||||
[[1+0j, 0+0.5j], [0-0.5j][-1+0j]]
|
||||
|
||||
But now if you call (with the renamed method)::
|
||||
|
||||
result.data()['unitary']
|
||||
|
||||
it will return something like::
|
||||
|
||||
[[[1, 0], [0, -0.5]], [[0, -0.5], [-1, 0]]]
|
||||
|
||||
To get the post processed results in the same format as before the 0.7 release
|
||||
you must use the ``get_counts()``, ``get_statevector()``, and ``get_unitary()``
|
||||
methods on the result object instead of ``get_data()['counts']``,
|
||||
``get_data()['statevector']``, and ``get_data()['unitary']`` respectively.
|
||||
|
||||
Additionally, support for ``len()`` and indexing on a ``Result`` object has
|
||||
been removed. Instead you should deal with the output from the post processed
|
||||
methods on the Result objects.
|
||||
|
||||
Also, the ``get_snapshot()`` and ``get_snapshots()`` methods from the
|
||||
``Result`` class have been removed. Instead you can access the snapshots
|
||||
using ``Result.data()['snapshots']``.
|
||||
|
||||
|
||||
Changes to visualization
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The biggest change made to visualization in the 0.7 release is the removal of
|
||||
Matplotlib and other visualization dependencies from the project requirements.
|
||||
This was done to simplify the requirements and configuration required for
|
||||
installing Qiskit. If you plan to use any visualizations (including all the
|
||||
jupyter magics) except for the ``text``, ``latex``, and ``latex_source``
|
||||
output for the circuit drawer you'll you must manually ensure that
|
||||
the visualization dependencies are installed. You can leverage the optional
|
||||
requirements to the Qiskit-Terra package to do this::
|
||||
|
||||
pip install qiskit-terra[visualization]
|
||||
|
||||
Aside from this there have been changes made to several of the interfaces
|
||||
as part of the stabilization which may have an impact on existing code.
|
||||
The first is the the ``basis`` kwarg in the ``circuit_drawer()`` function
|
||||
is no longer accepted. If you were relying on the ``circuit_drawer()`` to
|
||||
adjust the basis gates used in drawing a circuit diagram you will have to
|
||||
do this priort to calling ``circuit_drawer()``. For example::
|
||||
|
||||
from qiskit.tools import visualization
|
||||
visualization.circuit_drawer(circuit, basis_gates='x,U,CX')
|
||||
|
||||
will have to be adjust to be::
|
||||
|
||||
from qiskit import BasicAer
|
||||
from qiskit import transpiler
|
||||
from qiskit.tools import visualization
|
||||
backend = BasicAer.backend('qasm_simulator')
|
||||
draw_circ = transpiler.transpile(circuit, backend, basis_gates='x,U,CX')
|
||||
visualization.circuit_drawer(draw_circ)
|
||||
|
||||
Moving forward the ``circuit_drawer()`` function will be the sole interface
|
||||
for circuit drawing in the visualization module. Prior to the 0.7 release there
|
||||
were several other functions which either used different output backends or
|
||||
changed the output for drawing circuits. However, all those other functions
|
||||
have been deprecated and that functionality has been integrated as options
|
||||
on ``circuit_drawer()``.
|
||||
|
||||
For the other visualization functions, ``plot_histogram()`` and
|
||||
``plot_state()`` there are also a few changes to check when upgrading. First
|
||||
is the output from these functions has changed, in prior releases these would
|
||||
interactively show the output visualization. However that has changed to
|
||||
instead return a ``matplotlib.Figure`` object. This provides much more
|
||||
flexibility and options to interact with the visualization prior to saving or
|
||||
showing it. This will require adjustment to how these functions are consumed.
|
||||
For example, prior to this release when calling::
|
||||
|
||||
plot_histogram(counts)
|
||||
plot_state(rho)
|
||||
|
||||
would open up new windows (depending on matplotlib backend) to display the
|
||||
visualization. However starting in the 0.7 you'll have to call ``show()`` on
|
||||
the output to mirror this behavior. For example::
|
||||
|
||||
plot_histogram(counts).show()
|
||||
plot_state(rho).show()
|
||||
|
||||
or::
|
||||
|
||||
hist_fig = plot_histogram(counts)
|
||||
state_fig = plot_state(rho)
|
||||
hist_fig.show()
|
||||
state_fig.show()
|
||||
|
||||
Note that this is only for when running outside of Jupyter. No adjustment is
|
||||
required inside a Jupyter environment because Jupyter notebooks natively
|
||||
understand how to render ``matplotlib.Figure`` objects.
|
||||
|
||||
However, returning the Figure object provides additional flexibility for
|
||||
dealing with the output. For example instead of just showing the figure you
|
||||
can now directly save it to a file by leveraging the ``savefig()`` method.
|
||||
For example::
|
||||
|
||||
hist_fig = plot_histogram(counts)
|
||||
state_fig = plot_state(rho)
|
||||
hist_fig.savefig('histogram.png')
|
||||
state_fig.savefig('state_plot.png')
|
||||
|
||||
The other key aspect which has changed with these functions is when running
|
||||
under jupyter. In the 0.6 release ``plot_state()`` and ``plot_histogram()``
|
||||
when running under jupyter the default behavior was to use the interactive
|
||||
Javascript plots if the externally hosted Javascript library for rendering
|
||||
the visualization was reachable over the network. If not it would just use
|
||||
the matplotlib version. However in the 0.7 release this no longer the case,
|
||||
and separate functions for the interactive plots, ``iplot_state()`` and
|
||||
``iplot_histogram()`` are to be used instead. ``plot_state()`` and
|
||||
``plot_histogram()`` always use the matplotlib versions.
|
||||
|
||||
Additionally, starting in this release the ``plot_state()`` function is
|
||||
deprecated in favor of calling individual methods for each method of plotting
|
||||
a quantum state. While the ``plot_state()`` function will continue to work
|
||||
until the 0.9 release, it will emit a warning each time it is used. The
|
||||
|
||||
================================== ========================
|
||||
Qiskit Terra 0.6 Qiskit Terra 0.7+
|
||||
================================== ========================
|
||||
plot_state(rho) plot_state_city(rho)
|
||||
plot_state(rho, method='city') plot_state_city(rho)
|
||||
plot_state(rho, method='paulivec') plot_state_paulivec(rho)
|
||||
plot_state(rho, method='qsphere') plot_state_qsphere(rho)
|
||||
plot_state(rho, method='bloch') plot_bloch_multivector(rho)
|
||||
plot_state(rho, method='hinton') plot_state_hinton(rho)
|
||||
================================== ========================
|
||||
|
||||
The same is true for the interactive JS equivalent, ``iplot_state()``. The
|
||||
function names are all the same, just with a prepended `i` for each function.
|
||||
For example, ``iplot_state(rho, method='paulivec')`` is
|
||||
``iplot_state_paulivec(rho)``.
|
||||
|
||||
Changes to Backends
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
With the improvements made in the 0.7 release there are a few things related
|
||||
to backends to keep in mind when upgrading. The biggest change is the
|
||||
restructuring of the provider instances in the root ``qiskit``` namespace.
|
||||
The ``Aer`` provider is not installed by default and requires the installation
|
||||
of the ``qiskit-aer`` package. This package contains the new high performance
|
||||
fully featured simulator. If you installed via ``pip install qiskit`` you'll
|
||||
already have this installed. The python simulators are now available under
|
||||
``qiskit.BasicAer`` and the old C++ simulators are available with
|
||||
``qiskit.LegacySimulators``. This also means that the implicit fallback to
|
||||
python based simulators when the C++ simulators are not found doesn't exist
|
||||
anymore. If you ask for a local C++ based simulator backend, and it can't be
|
||||
found an exception will be raised instead of just using the python simulator
|
||||
instead.
|
||||
|
||||
Additionally the previously deprecation top level functions ``register()`` and
|
||||
``available_backends()`` have been removed. Also, the deprecated
|
||||
``backend.parameters()`` and ``backend.calibration()`` methods have been
|
||||
removed in favor of ``backend.properties()``. You can refer to the 0.6 release
|
||||
notes section :ref:`backends` for more details on these changes.
|
||||
|
||||
The ``backend.jobs()`` and ``backend.retrieve_jobs()`` calls no longer return
|
||||
results from those jobs. Instead you must call the ``result()`` method on the
|
||||
returned jobs objects.
|
||||
|
||||
Changes to the compiler, transpiler, and unrollers
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
As part of an effort to stabilize the compiler interfaces there have been
|
||||
several changes to be aware of when leveraging the compiler functions.
|
||||
First it is important to note that the ``qiskit.transpiler.transpile()``
|
||||
function now takes a QuantumCircuit object (or a list of them) and returns
|
||||
a QuantumCircuit object (or a list of them). The DAG processing is done
|
||||
internally now.
|
||||
|
||||
You can also easily switch between circuits, DAGs, and Qobj now using the
|
||||
functions in ``qiskit.converters``.
|
||||
|
||||
|
||||
Deprecations
|
||||
------------
|
||||
|
||||
As part of the part of the 0.7 release the following things have been
|
||||
deprecated and will either be removed or changed in a backwards incompatible
|
||||
manner in a future release. While not strictly necessary these are things to
|
||||
adjust for before the next release to avoid a breaking change.
|
||||
|
||||
* ``plot_circuit()``, ``latex_circuit_drawer()``, ``generate_latex_source()``,
|
||||
and ``matplotlib_circuit_drawer()`` from qiskit.tools.visualization are
|
||||
deprecated. Instead the ``circuit_drawer()`` function from the same module
|
||||
should be used, there are kwarg options to mirror the functionality of all
|
||||
the deprecated functions.
|
||||
* The current default output of ``circuit_drawer()`` (using latex and falling
|
||||
back on python) is deprecated and will be changed to just use the ``text``
|
||||
output by default in future releases.
|
||||
* The `qiskit.wrapper.load_qasm_string()` and `qiskit.wrapper.load_qasm_file()`
|
||||
functions are deprecated and the `QuantumCircuit.from_qasm_str()` and
|
||||
`QuantumCircuit.from_qasm_file()` constructor methods should be used instead.
|
||||
* The ``plot_barriers`` and ``reverse_bits`` keys in the ``style`` kwarg dict
|
||||
are deprecated, instead the `qiskit.tools.visualization.circuit_drawer()`
|
||||
kwargs ``plot_barriers`` and ``reverse_bits`` should be used instead.
|
||||
* The functions `plot_state()` and `iplot_state()` have been depreciated.
|
||||
Instead the functions `plot_state_*()` and `iplot_state_*()` should be
|
||||
called for the visualization method required.
|
||||
* The ``skip_transpiler`` arg has been deprecated from ``compile()`` and
|
||||
``execute()``. Instead you can use the PassManager directly, just set
|
||||
the ``pass_manager`` to a blank PassManager object with ``PassManager()``
|
||||
* The ``transpile_dag()`` function ``format`` kwarg for emitting different
|
||||
output formats is deprecated, instead you should convert the default output
|
||||
``DAGCircuit`` object to the desired format.
|
||||
* The unrollers have been deprecated, moving forward only DAG to DAG unrolling
|
||||
will be supported.
|
||||
|
||||
|
||||
Qiskit Terra 0.6.0
|
||||
==================
|
||||
|
||||
This release includes a redesign of internal components centered around a new,
|
||||
formal communication format (`qobj`), along with long awaited features to
|
||||
improve the user experience as a whole. The highlights, compared to the 0.5
|
||||
release, are:
|
||||
|
||||
* Improvements for inter-operability (based on the `qobj` specification) and
|
||||
extensibility (facilities for extending Qiskit with new backends in a
|
||||
seamless way).
|
||||
* New options for handling credentials and authentication for the IBM Q
|
||||
backends, aimed at simplifying the process and supporting automatic loading
|
||||
of user credentials.
|
||||
* A revamp of the visualization utilities: stylish interactive visualizations
|
||||
are now available for Jupyter users, along with refinements for the circuit
|
||||
drawer (including a matplotlib-based version).
|
||||
* Performance improvements centered around circuit transpilation: the basis for
|
||||
a more flexible and modular architecture have been set, including
|
||||
paralellization of the circuit compilation and numerous optimizations.
|
||||
|
||||
|
||||
Upgrading to 0.6.0
|
||||
------------------
|
||||
|
||||
Please note that some backwards-incompatible changes have been introduced
|
||||
during this release - the following notes contain information on how to adapt
|
||||
to the new changes.
|
||||
|
||||
Removal of ``QuantumProgram``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
As hinted during the 0.5 release, the deprecation of the ``QuantumProgram``
|
||||
class has now been completed and is no longer available, in favor of working
|
||||
with the individual components (:class:`~qiskit.backends.basejob.BaseJob`,
|
||||
:class:`~qiskit._quantumcircuit.QuantumCircuit`,
|
||||
:class:`~qiskit._classicalregister.ClassicalRegister`,
|
||||
:class:`~qiskit._quantumregister.QuantumRegister`,
|
||||
:mod:`~qiskit`) directly.
|
||||
|
||||
Please check the :ref:`0.5 release notes <quantum-program-0-5>` and the
|
||||
examples for details about the transition::
|
||||
|
||||
|
||||
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
|
||||
from qiskit import Aer, execute
|
||||
|
||||
q = QuantumRegister(2)
|
||||
c = ClassicalRegister(2)
|
||||
qc = QuantumCircuit(q, c)
|
||||
|
||||
qc.h(q[0])
|
||||
qc.cx(q[0], q[1])
|
||||
qc.measure(q, c)
|
||||
|
||||
backend = get_backend('qasm_simulator')
|
||||
|
||||
job_sim = execute(qc, backend)
|
||||
sim_result = job_sim.result()
|
||||
|
||||
print("simulation: ", sim_result)
|
||||
print(sim_result.get_counts(qc))
|
||||
|
||||
|
||||
IBM Q Authentication and ``Qconfig.py``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The managing of credentials for authenticating when using the IBMQ backends has
|
||||
been expanded, and there are new options that can be used for convenience:
|
||||
|
||||
1. save your credentials in disk once, and automatically load them in future
|
||||
sessions. This provides a one-off mechanism::
|
||||
|
||||
from qiskit import IBMQ
|
||||
IBQM.save_account('MY_API_TOKEN', 'MY_API_URL')
|
||||
|
||||
afterwards, your credentials can be automatically loaded from disk by invoking
|
||||
:meth:`~qiskit.backends.ibmq.ibmqprovider.IBMQ.load_accounts`::
|
||||
|
||||
from qiskit import IBMQ
|
||||
IBMQ.load_accounts()
|
||||
|
||||
or you can load only specific accounts if you only want to use those in a session::
|
||||
|
||||
IBMQ.load_accounts(project='MY_PROJECT')
|
||||
|
||||
2. use environment variables. If ``QE_TOKEN`` and ``QE_URL`` is set, the
|
||||
``IBMQ.load_accounts()`` call will automatically load the credentials from
|
||||
them.
|
||||
|
||||
Additionally, the previous method of having a ``Qconfig.py`` file in the
|
||||
program folder and passing the credentials explicitly is still supported.
|
||||
|
||||
|
||||
.. _backends:
|
||||
|
||||
Working with backends
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A new mechanism has been introduced in Terra 0.6 as the recommended way for
|
||||
obtaining a backend, allowing for more powerful and unified filtering and
|
||||
integrated with the new credentials system. The previous top-level methods
|
||||
:meth:`~qiskit.wrapper._wrapper.register`,
|
||||
:meth:`~qiskit.wrapper._wrapper.available_backends` and
|
||||
:meth:`~qiskit.wrapper._wrapper.get_backend` are still supported, but will
|
||||
deprecated in upcoming versions in favor of using the `qiskit.IBMQ` and
|
||||
`qiskit.Aer` objects directly, which allow for more complex filtering.
|
||||
|
||||
For example, to list and use a local backend::
|
||||
|
||||
from qiskit import Aer
|
||||
|
||||
all_local_backends = Aer.backends(local=True) # returns a list of instances
|
||||
qasm_simulator = Aer.backends('qasm_simulator')
|
||||
|
||||
And for listing and using remote backends::
|
||||
|
||||
from qiskit import IBMQ
|
||||
|
||||
IBMQ.enable_account('MY_API_TOKEN')
|
||||
5_qubit_devices = IBMQ.backends(simulator=True, n_qubits=5)
|
||||
ibmqx4 = IBMQ.get_backend('ibmqx4')
|
||||
|
||||
Please note as well that the names of the local simulators have been
|
||||
simplified. The previous names can still be used, but it is encouraged to use
|
||||
the new, shorter names:
|
||||
|
||||
============================= ========================
|
||||
Qiskit Terra 0.5 Qiskit Terra 0.6
|
||||
============================= ========================
|
||||
'local_qasm_simulator' 'qasm_simulator'
|
||||
'local_statevector_simulator' 'statevector_simulator'
|
||||
'local_unitary_simulator_py' 'unitary_simulator'
|
||||
============================= ========================
|
||||
|
||||
|
||||
Backend and Job API changes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* Jobs submitted to IBM Q backends have improved capabilities. It is possible
|
||||
to cancel them and replenish credits (``job.cancel()``), and to retrieve
|
||||
previous jobs executed on a specific backend either by job id
|
||||
(``backend.retrieve_job(job_id)``) or in batch of latest jobs
|
||||
(``backend.jobs(limit)``)
|
||||
|
||||
* Properties for checking each individual job status (``queued``, ``running``,
|
||||
``validating``, ``done`` and ``cancelled``) no longer exist. If you
|
||||
want to check the job status, use the identity comparison against
|
||||
``job.status``::
|
||||
|
||||
from qiskit.backends import JobStatus
|
||||
|
||||
job = execute(circuit, backend)
|
||||
if job.status() is JobStatus.RUNNING:
|
||||
handle_job(job)
|
||||
|
||||
Please consult the new documentation of the
|
||||
:class:`~qiskit.backends.ibmq.ibmqjob.IBMQJob` class to get further insight
|
||||
in how to use the simplified API.
|
||||
|
||||
* A number of members of :class:`~qiskit.backends.basebackend.BaseBackend`
|
||||
and :class:`~qiskit.backends.basejob.BaseJob` are no longer properties,
|
||||
but methods, and as a result they need to be invoked as functions.
|
||||
|
||||
===================== ========================
|
||||
Qiskit Terra 0.5 Qiskit Terra 0.6
|
||||
===================== ========================
|
||||
backend.name backend.name()
|
||||
backend.status backend.status()
|
||||
backend.configuration backend.configuration()
|
||||
backend.calibration backend.properties()
|
||||
backend.parameters backend.jobs()
|
||||
backend.retrieve_job(job_id)
|
||||
job.status job.status()
|
||||
job.cancelled job.queue_position()
|
||||
job.running job.cancel()
|
||||
job.queued
|
||||
job.done
|
||||
===================== ========================
|
||||
|
||||
|
||||
Better Jupyter tools
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The new release contains improvements to the user experience while using
|
||||
Jupyter notebooks.
|
||||
|
||||
First, new interactive visualizations of counts histograms and quantum states
|
||||
are provided:
|
||||
:meth:`~qiskit.tools.visualization.plot_histogram` and
|
||||
:meth:`~qiskit.tools.visualization.plot_state`.
|
||||
These methods will default to the new interactive kind when the environment
|
||||
is Jupyter and internet connection exists.
|
||||
|
||||
Secondly, the new release provides Jupyter cell magics for keeping track of
|
||||
the progress of your code. Use ``%%qiskit_job_status`` to keep track of the
|
||||
status of submitted jobs to IBMQ backends. Use ``%%qiskit_progress_bar`` to
|
||||
keep track of the progress of compilation/execution.
|
||||
|
||||
|
||||
Qiskit Terra 0.5.0
|
||||
==================
|
||||
|
||||
This release brings a number of improvements to Qiskit, both for the user
|
||||
experience and under the hood. Please refer to the full changelog for a
|
||||
detailed description of the changes - the highlights are:
|
||||
|
||||
* new ``statevector`` :mod:`simulators <qiskit.backends.local>` and feature and
|
||||
performance improvements to the existing ones (in particular to the C++
|
||||
simulator), along with a reorganization of how to work with backends focused
|
||||
on extensibility and flexibility (using aliases and backend providers).
|
||||
* reorganization of the asynchronous features, providing a friendlier interface
|
||||
for running jobs asynchronously via :class:`Job` instances.
|
||||
* numerous improvements and fixes throughout the Terra as a whole, both for
|
||||
convenience of the users (such as allowing anonymous registers) and for
|
||||
enhanced functionality (such as improved plotting of circuits).
|
||||
|
||||
|
||||
Upgrading to 0.5.0
|
||||
------------------
|
||||
|
||||
Please note that several backwards-incompatible changes have been introduced
|
||||
during this release as a result of the ongoing development. While some of these
|
||||
features will continue to be supported during a period of time before being
|
||||
fully deprecated, it is recommended to update your programs in order to prepare
|
||||
for the new versions and take advantage of the new functionality.
|
||||
|
||||
.. _quantum-program-0-5:
|
||||
|
||||
|
||||
``QuantumProgram`` changes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Several methods of the :class:`~qiskit.QuantumProgram` class are on their way
|
||||
to being deprecated:
|
||||
|
||||
* methods for interacting **with the backends and the API**:
|
||||
|
||||
The recommended way for opening a connection to the IBMQ API and for using
|
||||
the backends is through the
|
||||
:ref:`top-level functions <qiskit_top_level_functions>` directly instead of
|
||||
the ``QuantumProgram`` methods. In particular, the
|
||||
:func:`qiskit.register` method provides the equivalent of the previous
|
||||
:func:`qiskit.QuantumProgram.set_api` call. In a similar vein, there is a new
|
||||
:func:`qiskit.available_backends`, :func:`qiskit.get_backend` and related
|
||||
functions for querying the available backends directly. For example, the
|
||||
following snippet for version 0.4::
|
||||
|
||||
from qiskit import QuantumProgram
|
||||
|
||||
quantum_program = QuantumProgram()
|
||||
quantum_program.set_api(token, url)
|
||||
backends = quantum_program.available_backends()
|
||||
print(quantum_program.get_backend_status('ibmqx4')
|
||||
|
||||
would be equivalent to the following snippet for version 0.5::
|
||||
|
||||
from qiskit import register, available_backends, get_backend
|
||||
|
||||
register(token, url)
|
||||
backends = available_backends()
|
||||
backend = get_backend('ibmqx4')
|
||||
print(backend.status)
|
||||
|
||||
* methods for **compiling and executing programs**:
|
||||
|
||||
The :ref:`top-level functions <qiskit_top_level_functions>` now also provide
|
||||
equivalents for the :func:`qiskit.QuantumProgram.compile` and
|
||||
:func:`qiskit.QuantumProgram.execute` methods. For example, the following
|
||||
snippet from version 0.4::
|
||||
|
||||
quantum_program.execute(circuit, args, ...)
|
||||
|
||||
would be equivalent to the following snippet for version 0.5::
|
||||
|
||||
from qiskit import execute
|
||||
|
||||
execute(circuit, args, ...)
|
||||
|
||||
In general, from version 0.5 onwards we encourage to try to make use of the
|
||||
individual objects and classes directly instead of relying on
|
||||
``QuantumProgram``. For example, a :class:`~qiskit.QuantumCircuit` can be
|
||||
instantiated and constructed by appending :class:`~qiskit.QuantumRegister`,
|
||||
:class:`~qiskit.ClassicalRegister`, and gates directly. Please check the
|
||||
update example in the Quickstart section, or the
|
||||
``using_qiskit_core_level_0.py`` and ``using_qiskit_core_level_1.py``
|
||||
examples on the main repository.
|
||||
|
||||
Backend name changes
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In order to provide a more extensible framework for backends, there have been
|
||||
some design changes accordingly:
|
||||
|
||||
* **local simulator names**
|
||||
|
||||
The names of the local simulators have been homogenized in order to follow
|
||||
the same pattern: ``PROVIDERNAME_TYPE_simulator_LANGUAGEORPROJECT`` -
|
||||
for example, the C++ simulator previously named ``local_qiskit_simulator``
|
||||
is now ``local_qasm_simulator_cpp``. An overview of the current
|
||||
simulators:
|
||||
|
||||
* ``QASM`` simulator is supposed to be like an experiment. You apply a
|
||||
circuit on some qubits, and observe measurement results - and you repeat
|
||||
for many shots to get a histogram of counts via ``result.get_counts()``.
|
||||
* ``Statevector`` simulator is to get the full statevector (:math:`2^n`
|
||||
amplitudes) after evolving the zero state through the circuit, and can be
|
||||
obtained via ``result.get_statevector()``.
|
||||
* ``Unitary`` simulator is to get the unitary matrix equivalent of the
|
||||
circuit, returned via ``result.get_unitary()``.
|
||||
* In addition, you can get intermediate states from a simulator by applying
|
||||
a ``snapshot(slot)`` instruction at various spots in the circuit. This will
|
||||
save the current state of the simulator in a given slot, which can later
|
||||
be retrieved via ``result.get_snapshot(slot)``.
|
||||
|
||||
* **backend aliases**:
|
||||
|
||||
The SDK now provides an "alias" system that allows for automatically using
|
||||
the most performant simulator of a specific type, if it is available in your
|
||||
system. For example, with the following snippet::
|
||||
|
||||
from qiskit import get_backend
|
||||
|
||||
backend = get_backend('local_statevector_simulator')
|
||||
|
||||
the backend will be the C++ statevector simulator if available, falling
|
||||
back to the Python statevector simulator if not present.
|
||||
|
||||
More flexible names and parameters
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Several functions of the SDK have been made more flexible and user-friendly:
|
||||
|
||||
* **automatic circuit and register names**
|
||||
|
||||
:class:`qiskit.ClassicalRegister`, :class:`qiskit.QuantumRegister` and
|
||||
:class:`qiskit.QuantumCircuit` can now be instantiated without explicitly
|
||||
giving them a name - a new autonaming feature will automatically assign them
|
||||
an identifier::
|
||||
|
||||
q = QuantumRegister(2)
|
||||
|
||||
Please note as well that the order of the parameters have been swapped
|
||||
``QuantumRegister(size, name)``.
|
||||
|
||||
* **methods accepting names or instances**
|
||||
|
||||
In combination with the autonaming changes, several methods such as
|
||||
:func:`qiskit.Result.get_data` now accept both names and instances for
|
||||
convenience. For example, when retrieving the results for a job that has a
|
||||
single circuit such as::
|
||||
|
||||
qc = QuantumCircuit(..., name='my_circuit')
|
||||
job = execute(qc, ...)
|
||||
result = job.result()
|
||||
|
||||
The following calls are equivalent::
|
||||
|
||||
data = result.get_data('my_circuit')
|
||||
data = result.get_data(qc)
|
||||
data = result.get_data()
|
||||
|
||||
|
||||
.. include:: CHANGELOG.rst
|
Loading…
Reference in New Issue