{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Example to use ProjectQ to run algorithms on Quantum Inspire" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Copyright 2018 QuTech Delft. Licensed under the Apache License, Version 2.0.\n", "\n", "For more information on Quantum Inspire, see https://www.quantum-inspire.com/.\n", "For more information on ProjectQ, see https://github.com/ProjectQ-Framework/ProjectQ." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import logging\n", "from coreapi.auth import BasicAuthentication\n", "from getpass import getpass\n", "\n", "from projectq import MainEngine\n", "from projectq.setups import linear\n", "from projectq.cengines import ManualMapper\n", "from projectq.ops import H, Rx, Rz, CNOT, CZ, Measure, All\n", "\n", "from quantuminspire.api import QuantumInspireAPI\n", "from quantuminspire.projectq.backend_qx import QIBackend" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "if 'password' not in vars().keys():\n", " print('Enter email')\n", " username = input()\n", " print('Enter password')\n", " password = getpass()\n", " \n", "uri = r'https://api.quantum-inspire.com/'\n", "authentication = BasicAuthentication(username, password)\n", "qi_api = QuantumInspireAPI(uri, authentication)\n", "\n", "projectq_backend = QIBackend(quantum_inspire_api=qi_api)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Execute algorithm on QX simulator" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We create an algorithm to entangle qubit 0 and qubit 4." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Measured 0,0,0,0,0\n", "Probabilities: {'00000': 0.4931640625, '10001': 0.5068359375}\n", "version 1.0\n", "# generated by Quantum Inspire class\n", "qubits 5\n", "\n", "\n", "h q[0]\n", "CNOT q[0], q[4]\n" ] } ], "source": [ "engine_list = [ManualMapper(lambda ii: ii)]\n", "engine = MainEngine(backend=projectq_backend, engine_list=engine_list) # create default compiler (simulator back-end)\n", "\n", "qubits = engine.allocate_qureg(5)\n", "q1 = qubits[0]\n", "q2 = qubits[-1]\n", "\n", "H | q1 # apply a Hadamard gate\n", "CNOT | (q1, q2)\n", "All(Measure) | qubits # measure the qubits\n", "\n", "engine.flush() # flush all gates (and execute measurements)\n", "\n", "print(\"Measured {}\".format(','.join([str(int(q)) for q in qubits])))\n", "print('Probabilities: %s' % (projectq_backend.get_probabilities(qubits),))\n", "print(projectq_backend.cqasm())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The result is as expected: about half of the results is split between 0 and 1 on qubit 0 and 4. The QASM generated by the backend is fairly simple." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Simulate a spin-qubit array" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On a spin-qubit array we have limited connectivity and also a limited set of gates available. With ProjectQ we can handle these cases by adding specific compiler engines.\n", "Our engine lists is generated by the `projectq.setups.linear` module." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Measured 0,0,0,0,0\n", "Probabilities: {'00000': 0.484375, '10001': 0.515625}\n", "version 1.0\n", "# generated by Quantum Inspire class\n", "qubits 5\n", "\n", "\n", "h q[0]\n", "CNOT q[0], q[4]\n" ] } ], "source": [ "engine_list = linear.get_engine_list(num_qubits=5, one_qubit_gates=(Rx, Rz), two_qubit_gates=(CZ,))\n", "engine = MainEngine(backend=projectq_backend, engine_list=engine_list) # create default compiler (simulator back-end)\n", "\n", "qubits = engine.allocate_qureg(5)\n", "q1 = qubits[0]\n", "q2 = qubits[-1]\n", "\n", "H | q1 # apply a Hadamard gate\n", "CNOT | (q1, q2)\n", "All(Measure) | qubits # measure the qubits\n", "\n", "engine.flush() # flush all gates (and execute measurements)\n", "\n", "print(\"Measured {}\".format(','.join([str(int(q)) for q in qubits])))\n", "print('Probabilities: %s' % (projectq_backend.get_probabilities(qubits),))\n", "print(projectq_backend.cqasm())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The result is the same, but if we look at the QASM generated there is quite a difference. The CNOT gate was replaced by a CZ gate with some single qubit operations. Also the qubits 0 and 4 have been mapped to neighboring qubits." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "mapping logical qubit 0 to physical qubit 0\n", "mapping logical qubit 1 to physical qubit 1\n", "mapping logical qubit 2 to physical qubit 2\n", "mapping logical qubit 3 to physical qubit 3\n", "mapping logical qubit 4 to physical qubit 4\n" ] } ], "source": [ "current_mapping = engine.mapper.current_mapping\n", "for l, p in current_mapping.items():\n", " print('mapping logical qubit %d to physical qubit %d' % (l, p))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.6.6" } }, "nbformat": 4, "nbformat_minor": 2 }