{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Manipulating and measuring observables\n", "This notebook introduces the Observable class that allows to describe, manipulate and sample observables over quantum states produced by circuits.\n", "\n", "## Defining a new observable\n", "\n", "We will take as example a simple observable that counts the number of ones in a quantum state over 5 qubits.\n", "\n", "This observable can be written as:\n", "\n", "$$ O = \\Sigma_i (1 - \\sigma_z^i)/2 $$\n", "\n", "An observable is initialized with the number of qubits it acts on:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from qat.core import Observable, Term\n", "nbqbits = 5\n", "one_count = Observable(nbqbits)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "New Pauli terms can be added to the observable.\n", "\n", "First, we need to write our observable $O$ as a sum of weighted Pauli operators:\n", "\n", "$$ O = N/2 - \\Sigma_i \\frac{1}{2}\\sigma_z^i $$\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# The sigma Z terms:\n", "for i in range(nbqbits):\n", " one_count.add_term(Term(-0.5, \"Z\", [i]))\n", "# And the constant term:\n", "one_count.constant_coeff += nbqbits/2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can print our observable to check if it is correct" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(one_count)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Sampling an observable over the final state of a circuit\n", "Lets build a simple circuit and approximate the expectation of our observable over its final state.\n", "\n", "Because PyLinalg does not natively supports observable sampling, we will use an intermediate plugin `ObservableSplitter` in order to split the observable carrying job into a collection of basic sampling jobs." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from qat.lang.AQASM import Program, X, CNOT, RX\n", "\n", "prog_2_ones = Program()\n", "qbits = prog_2_ones.qalloc(nbqbits)\n", "prog_2_ones.apply(X, qbits[0])\n", "prog_2_ones.apply(CNOT, qbits[0], qbits[2])\n", "circ_2_ones = prog_2_ones.to_circ()\n", "\n", "from qat.qpus import PyLinalg\n", "from qat.plugins import ObservableSplitter\n", "\n", "qpu = ObservableSplitter() | PyLinalg()\n", "job = circ_2_ones.to_job(\"OBS\", observable=one_count, nbshots=30)\n", "print(\"Number of ones:\", qpu.submit(job).value)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now with a less obvious circuit:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "prog = Program()\n", "qbits = prog.qalloc(5)\n", "for i, qb in enumerate(qbits):\n", " prog.apply(RX(0.324 * i), qb)\n", "circ = prog.to_circ()\n", "job = circ.to_job(\"OBS\", observable=one_count, nbshots=30)\n", "print(\"Number of ones:\", qpu.submit(job).value)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Of course, we can reduce the deviation of this result by increasing the number of samples:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "job = circ.to_job(\"OBS\", observable=one_count, nbshots=1000)\n", "print(\"Number of ones:\", qpu.submit(job).value)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or even compute the exact value of the observable using an \"infinite\" number of shots" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "job = circ.to_job(\"OBS\", observable=one_count)\n", "print(\"Exact number of ones:\", qpu.submit(job).value)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "authors": [ "Simon Martiel" ], "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.8" } }, "nbformat": 4, "nbformat_minor": 2 }