Initial commit

This commit is contained in:
Jay M. Gambetta 2017-03-03 17:47:50 -05:00
commit 6b10234e6f
7 changed files with 789 additions and 0 deletions

100
.gitignore vendored Normal file
View File

@ -0,0 +1,100 @@
# SDK config file
Qconfig.py
#standard python ignores follow
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# dotenv
.env
# virtualenv
.venv
venv/
ENV/
# Spyder project settings
.spyderproject
# Rope project settings
.ropeproject

View File

@ -0,0 +1,455 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"./images/QISKit-c.gif\" alt=\"Note: In order for images to show up in this jupyter notebook you need to select File => Trusted Notebook\" width=\"250 px\" align=\"left\">"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## _*Getting Started*_ <br />with the Quantum Experience Web API<br />\n",
"© IBM Research\n",
"\n",
"The latest version of this notebook is available on https://github.com/IBM/qiskit-sdk-py/scripts.\n",
"\n",
"For more information about how to use the Quantum Experience consult the [Quantum Experience tutorials](https://quantumexperience.ng.bluemix.net/qstage/#/tutorial?sectionId=c59b3710b928891a1420190148a72cce&pageIndex=0) or check-out the [community](https://quantumexperience.ng.bluemix.net/qstage/#/community).\n",
"\n",
"***\n",
"### Contributors\n",
"Andreas Fuhrer, Jay Gambetta, Andrew Cross"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## About\n",
"The is a simple example script illustrating the Python interface to the web API of the Quantum Experience. It allows you to run experiments on the Quantum Experience by submitting OPENQASM 2.0 code sequences and reading back the results of the experiments when they become available. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Installation\n",
"If you have **not** yet installed the Python interface to the web API of the Quantum Experience you can download it from [here](https://github.com/IBMResearch/python-sdk-quantum-experience). Alternatively you can install it using pip from the commandline or by executing (press shift + enter) the following cell:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"!pip install --upgrade IBMQuantumExperience"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Should you run into problems you can retry to install from the command line (without the leading '!') or by manually installing each package:<br />\n",
"`! pip install --upgrade --no-deps IBMQuantumExperience` <br />\n",
"`! pip install --upgrade --no-deps requests` <br />\n",
"For some users, it may be necessary to install in user space using the \"--user\" option. If you prefer, as a final alternative, you can import and call the pip module directly within this notebook."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Getting Started\n",
"Now it's time to begin doing real work with Python and the Quantum Experience.\n",
"First, we import the Python interface for web API:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import sys\n",
"if sys.version_info < (3,0):\n",
" raise Exception(\"Please use Python version 3 or greater.\")\n",
"from IBMQuantumExperience import IBMQuantumExperience"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Before we can start running experiments on the Quantum Experience, __the API needs to be configured with your personal APItoken__. This is done by setting variables in the Qconfig.py file for accessing the Quantum Experience. You can begin by copying Qconfig.py.default into your own Qconfig.py. In this file, there is a line \"#APItoken = None\" that you need to uncomment. Then replace \"None\" with your personal access token which you can obtain from the Quantum Experience web site under the Accounts button."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import Qconfig\n",
"api = IBMQuantumExperience.IBMQuantumExperience(Qconfig.APItoken, Qconfig.config)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The API provides the following methods: `runJobs,getJob`. The detailed specifications of the API are currently still changing as the Quantum Experience gets updated. However, some basic documentation of these commands can be found below:\n",
"\n",
"```python\n",
"runJobs(qasms, device, shots, maxCredits)```\n",
"> Runs a batch of quantum circuits written in QPENQASM 2.0 <br />\n",
">\n",
"> **Parameters:**\n",
">\n",
">_qasms_: A list of objects with the OPENQASM 2.0 information. <br />\n",
"e.g.: `qasms=[\n",
" { 'qasm': \n",
" 'OPENQASM 2.0; \n",
" include \"qelib1.inc\"; \n",
" qreg q[5];\n",
" creg c[5]; \n",
" h q[0]; \n",
" cx q[0],q[2]; \n",
" measure q[0] -> c[0]; \n",
" measure q[2] -> c[1]; \n",
" '},\n",
" { 'qasm': \n",
" 'OPENQASM 2.0;\n",
" include \"qelib1.inc\";\n",
" qreg q[5];\n",
" creg c[5];\n",
" x q[0];\n",
" measure q[0] -> c[0];\n",
" '}]`\n",
">\n",
">_device_: Type of device to run the experiment on. The two possible options are: _'sim'_ or _'real'_. <br />\n",
"> e.g.: `device = 'real'`<br />\n",
">\n",
">_shots_: Number of shots of the experiments. Maximum 8192 shots. <br />\n",
"> e.g.: `shots = 1024`<br />\n",
">\n",
">_maxCredits_: Maximum number of the credits to spend in the executions. If the executions are more expensives, the job is aborted. <br /> \n",
"> e.g.: `maxCredits = 3`<br />\n",
">\n",
"> **Returns:** \n",
">\n",
"> *out\\_dict* : dictionary with the keys:\n",
">\n",
"> 'backend' : which backend was used\n",
"> 'id' : id of job executions\n",
"> 'maxCredits' : the maximum number of credits set\n",
"> 'qasms' : the results of experiments\n",
"> 'shots' : number of shots set\n",
"> 'status' : status of execution e.g. 'DONE'\n",
"> 'usedCredits' : the credits used"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Example\n",
"\n",
"Now that you are connected to the Quantum Experience, let's try some basic experiments.\n",
"First we define a simple quantum circuit using QASM 2.0. We'll start by encoding a Bell state between qubit 0 and 2."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"makebell = \"\"\"\n",
"OPENQASM 2.0;\n",
"include \"qelib1.inc\";\n",
"qreg q[3];\n",
"creg c[2];\n",
"h q[0];\n",
"cx q[0],q[2];\n",
"measure q[0] -> c[0];\n",
"measure q[2] -> c[1];\n",
"\"\"\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" Lines 1+2 of the QASM string specify code version and interface library. \n",
" Line 3 selects only 3 of the qubits in the quantum register\n",
" Line 4 chooses a 2-bit output register\n",
" Line 5 defines a Hadamard gate on qubit 0\n",
" Line 6 implements a CNOT between qubit 0 and qubit 2\n",
" Lines 7+8 specify the measurement of the qubits and which output bit should be targeted\n",
" \n",
"Next we run the experiment 1024 times using simulation. If you replace `device = 'sim'` with `device = 'real'`, you can run it on the real device. Using the `out['status']` you can see that your job is running over the cloud."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"out = api.runJob(qasms = [{'qasm' : makebell}],device = 'sim',shots = 1024, maxCredits=3)\n",
"print(out['status'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To check if your job has finished use the _getJob_ command using the job id that you sent to the Quantum Expereince "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import time\n",
"jobids=out['id']\n",
"results = api.getJob(jobids)\n",
"print(results['status'])\n",
"while (results['status'] == 'RUNNING'):\n",
" time.sleep(2)\n",
" results = api.getJob(jobids)\n",
" print(results['status'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we can retrive the data using the function _getData_."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"getData = lambda results, i: results['qasms'][i]['result']['data']['counts']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"data=getData(results,0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For visualizing the results of our simple calculation we define a helper function _plotHistogram_ that makes a barchart with the propabilities of the measurement outcomes. Then we plot the results."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from Qhelpers.basicPlotter import plotHistogram"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"plotHistogram(data)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Example 2\n",
"\n",
"Now that you have run a single job, we'll show you how to run a batch of jobs."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"makeground = \"\"\"\n",
"OPENQASM 2.0;\n",
"include \"qelib1.inc\";\n",
"qreg q[1];\n",
"creg c[1];\n",
"measure q[0] -> c[0];\n",
"\"\"\"\n",
"makeexcited = \"\"\"\n",
"OPENQASM 2.0;\n",
"include \"qelib1.inc\";\n",
"qreg q[1];\n",
"creg c[1];\n",
"x q[0];\n",
"measure q[0] -> c[0];\n",
"\"\"\"\n",
"makesuperposition = \"\"\"\n",
"OPENQASM 2.0;\n",
"include \"qelib1.inc\";\n",
"qreg q[1];\n",
"creg c[1];\n",
"h q[0];\n",
"measure q[0] -> c[0];\n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"jobs = [{ 'qasm': makeground},{ 'qasm': makeexcited},{'qasm': makesuperposition}]\n",
"\n",
"print(\"submitting %d jobs ...\" % len(jobs))\n",
"out = api.runJob(jobs, device = 'sim',shots = 1024, maxCredits=3)\n",
"print(out['status'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"jobids=out['id']\n",
"results = api.getJob(jobids)\n",
"print(results['status'])\n",
"while (results['status'] == 'RUNNING'):\n",
" time.sleep(2)\n",
" results = api.getJob(jobids)\n",
" print(results['status'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"plotHistogram(getData(results,0))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"plotHistogram(getData(results,1))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"plotHistogram(getData(results,2))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Python [default]",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
},
"latex_envs": {
"bibliofile": "biblio.bib",
"cite_by": "apalike",
"current_citInitial": 1,
"eqLabelWithNumbers": true,
"eqNumInitial": 0
},
"nav_menu": {},
"toc": {
"navigate_menu": true,
"number_sections": true,
"sideBar": true,
"threshold": 6,
"toc_cell": false,
"toc_section_display": "block",
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 0
}

View File

@ -0,0 +1,13 @@
# Before you can use the jobs API, you need to set up an access token.
# Log in to the Quantum Experience. Under "Account", generate a personal
# access token. Replace "None" below with the quoted token string.
# Uncomment the APItoken variable, and you will be ready to go.
#APItoken = None
config = {
"url": 'https://quantumexperience.ng.bluemix.net/api'
}
if 'APItoken' not in locals():
raise Exception("Please set up your access token. See Qconfig.py.")

View File

@ -0,0 +1,130 @@
"""
Basic plotting methods using matplotlib.
These include methods to plot Bloch vectors and histograms, for example.
Author: Andrew Cross, Jay Gambetta
"""
from mpl_toolkits.mplot3d import proj3d
import matplotlib.pyplot as plt
from matplotlib.patches import FancyArrowPatch
import numpy as np
class Arrow3D(FancyArrowPatch):
"""Standard 3D arrow."""
def __init__(self, xs, ys, zs, *args, **kwargs):
"""Create arrow."""
FancyArrowPatch.__init__(self, (0, 0), (0, 0), *args, **kwargs)
self._verts3d = xs, ys, zs
def draw(self, renderer):
"""Draw the arrow."""
xs3d, ys3d, zs3d = self._verts3d
xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M)
self.set_positions((xs[0], ys[0]), (xs[1], ys[1]))
FancyArrowPatch.draw(self, renderer)
def plotRBData(xdata, ydatas, yavg, fit, survival_prob):
"""Plot randomized benchmarking data.
xdata = list of subsequence lengths
ydatas = list of lists of survival probabilities for each sequence
yavg = mean of the survival probabilities at each sequence length
fit = list of fitting parameters [a, b, alpha]
survival_prob = function that computes survival probability
"""
# Plot the result for each sequence
for ydata in ydatas:
plt.plot(xdata, ydata, 'rx')
# Plot the mean
plt.plot(xdata, yavg, 'bo')
# Plot the fit
plt.plot(xdata, survival_prob(xdata, *fit), 'b-')
plt.show()
def plotBlochVector(bloch, title=""):
"""Plot a Bloch vector.
Plot a sphere, axes, the Bloch vector, and its projections onto each axis.
bloch is a 3-tuple (x,y,z)
title is a string, the plot title
"""
# Set arrow lengths
arlen = 1.3
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_aspect("equal")
# Plot semi-transparent sphere
u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)
x = np.outer(np.cos(u), np.sin(v))
y = np.outer(np.sin(u), np.sin(v))
z = np.outer(np.ones(np.size(u)), np.cos(v))
ax.plot_surface(x, y, z, color="b", alpha=0.1)
# Plot arrows (axes, Bloch vector, its projections)
xa = Arrow3D([0, arlen], [0, 0], [0, 0], mutation_scale=20, lw=1,
arrowstyle="-|>", color="k")
ya = Arrow3D([0, 0], [0, arlen], [0, 0], mutation_scale=20, lw=1,
arrowstyle="-|>", color="k")
za = Arrow3D([0, 0], [0, 0], [0, arlen], mutation_scale=20, lw=1,
arrowstyle="-|>", color="k")
a = Arrow3D([0, bloch[0]], [0, bloch[1]], [0, bloch[2]], mutation_scale=20,
lw=2, arrowstyle="simple", color="k")
bax = Arrow3D([0, bloch[0]], [0, 0], [0, 0], mutation_scale=20, lw=2,
arrowstyle="-", color="r")
bay = Arrow3D([0, 0], [0, bloch[1]], [0, 0], mutation_scale=20, lw=2,
arrowstyle="-", color="g")
baz = Arrow3D([0, 0], [0, 0], [0, bloch[2]], mutation_scale=20, lw=2,
arrowstyle="-", color="b")
arrowlist = [xa, ya, za, a, bax, bay, baz]
for arr in arrowlist:
ax.add_artist(arr)
# Rotate the view
ax.view_init(30, 30)
# Annotate the axes, shifts are ad-hoc for this (30,30) view
xp, yp, _ = proj3d.proj_transform(arlen, 0, 0, ax.get_proj())
plt.annotate("x", xy=(xp, yp), xytext=(-3, -8),
textcoords='offset points', ha='right', va='bottom')
xp, yp, _ = proj3d.proj_transform(0, arlen, 0, ax.get_proj())
plt.annotate("y", xy=(xp, yp), xytext=(6, -5),
textcoords='offset points', ha='right', va='bottom')
xp, yp, _ = proj3d.proj_transform(0, 0, arlen, ax.get_proj())
plt.annotate("z", xy=(xp, yp), xytext=(2, 0),
textcoords='offset points', ha='right', va='bottom')
plt.title(title)
plt.show()
def plotHistogram(data):
"""Plot a histogram of data."""
labels = sorted(data)
values = np.array([data[key] for key in labels], dtype=float)
pvalues = values / sum(values)
numelem = len(values)
ind = np.arange(numelem) # the x locations for the groups
width = 0.35 # the width of the bars
fig, ax = plt.subplots()
rects = ax.bar(ind, pvalues, width, color='seagreen')
# add some text for labels, title and axes ticks
ax.set_ylabel('Probabilities', fontsize=20)
ax.set_xticks(ind)
ax.set_xticklabels(labels, fontsize=20)
ax.set_ylim([0., min([1.2, max([1.2 * val for val in pvalues])])])
# attach some text labels
for rect in rects:
height = rect.get_height()
ax.text(rect.get_x() + rect.get_width() / 2., 1.05 * height,
'%f' % float(height),
ha='center', va='bottom')
plt.show()

91
scripts/Qhelpers/misc.py Normal file
View File

@ -0,0 +1,91 @@
"""
Miscellaneous methods.
These are simple methods for common tasks in our examples, including
minor methods for helping with running jobs and getting results.
Author: Andrew Cross, Jay Gambetta
"""
import time
from collections import Counter
def getData(results, i):
"""Get the dict of labels and counts from the output of getJob."""
return results['qasms'][i]['result']['data']['counts']
def getJobListStatus(jobids, api):
"""Given a list of job ids, return a list of job status.
jobids is a list of id strings.
api is an IBMQuantumExperience object.
"""
status_list = []
for i in jobids:
status_list.append(api.getJob(i)['status'])
return status_list
def waitForJobs(jobids, api, wait=5, timeout=60):
"""Wait until all status results are 'COMPLETED'.
jobids is a list of id strings.
api is an IBMQuantumExperience object.
wait is the time to wait between requests, in seconds
timeout is how long we wait before failing, in seconds
Returns an list of results that correspond to the jobids.
"""
status = dict(Counter(getJobListStatus(jobids, api)))
t = 0
print("status = %s (%d seconds)" % (status, t))
while 'COMPLETED' not in status or status['COMPLETED'] < len(jobids):
if t == timeout:
break
time.sleep(wait)
t += wait
status = dict(Counter(getJobListStatus(jobids, api)))
print("status = %s (%d seconds)" % (status, t))
# Get the results
results = []
for i in jobids:
results.append(api.getJob(i))
return results
def combineJobs(jobids, api, wait=5, timeout=60):
"""Like waitForJobs but with a different return format.
jobids is a list of id strings.
api is an IBMQuantumExperience object.
wait is the time to wait between requests, in seconds
timeout is how long we wait before failing, in seconds
Returns a list of dict outcomes of the flattened in the order
jobids so it works with _getData_.
"""
results = list(map(lambda x: x['qasms'],
waitForJobs(jobids, api, wait, timeout)))
flattened = []
for sublist in results:
for val in sublist:
flattened.append(val)
# Are there other parts from the dictionary that we want to add,
# such as shots?
return {'qasms': flattened}
def averageData(data, observable):
"""Compute the mean value of an observable.
Takes in the data counts(i) and a corresponding observable in dict
form and calculates sum_i value(i) P(i) where value(i) is the value of
the observable for the i state.
"""
temp = 0
tot = sum(data.values())
for key in data:
if key in observable:
temp += data[key]*observable[key]/tot
return temp

BIN
scripts/images/QISKit-c.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
scripts/images/QISKit.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB