-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
656cf9e
commit 3b9811a
Showing
1 changed file
with
281 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,281 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "54191476", | ||
"metadata": {}, | ||
"source": [ | ||
"# Quantum Volume\n", | ||
"\n", | ||
"Here we show off using the expectation value functionality of the M3 distribution classes using Quantum Volume (QV) as an example. Here we formulate QV as an expectation value of a projector onto the heavy-output elements on a distribution." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 1, | ||
"id": "c1b69009", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import numpy as np\n", | ||
"from qiskit import *\n", | ||
"from qiskit.quantum_info import Statevector\n", | ||
"from qiskit.circuit.library import QuantumVolume\n", | ||
"import mthree" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"id": "cdd59933", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from qiskit.test.mock import FakeAthens\n", | ||
"noisy_sim = FakeAthens()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "0118fe34", | ||
"metadata": {}, | ||
"source": [ | ||
"QV is defined in terms of heavy-ouputs of a distribution. Heavy-outputs are those bit-strings that are those that have probabilities above the median value of the distribution. Below we define the projection operator onto the set of bit-strings that are heavy-outputs for a given distribution." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 3, | ||
"id": "ccf57f8b", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"def heavy_projector(qv_probs):\n", | ||
" \"\"\"Forms the projection operator onto the heavy-outputs of a given probability distribution.\n", | ||
" \n", | ||
" Parameters:\n", | ||
" qv_probs (dict): A dictionary of bitstrings and associated probabilities.\n", | ||
" \n", | ||
" Returns:\n", | ||
" dict: Projector onto the heavy-set.\n", | ||
" \"\"\"\n", | ||
" median_prob = np.median(list(qv_probs.values()))\n", | ||
" heavy_strs = {}\n", | ||
" for key, val in qv_probs.items():\n", | ||
" if val > median_prob:\n", | ||
" heavy_strs[key] = 1\n", | ||
" return heavy_strs" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "2134ff49", | ||
"metadata": {}, | ||
"source": [ | ||
"First we begin by calibrating our M3 mitigator over all the qubits on our noisy simulator. (We use the `independent` method since it is much faster to do so on a simulator.)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 4, | ||
"id": "254a4dbe", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"mit = mthree.M3Mitigation(noisy_sim)\n", | ||
"mit.cals_from_system(method='independent')" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "1b267a08", | ||
"metadata": {}, | ||
"source": [ | ||
"Now we generate 10 QV circuits as our dataset." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 5, | ||
"id": "2db632a1", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Generate QV circuits\n", | ||
"N = 10\n", | ||
"qv_circs = [QuantumVolume(5) for _ in range(N)]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "e0698f04", | ||
"metadata": {}, | ||
"source": [ | ||
"Next, we have to determine the heavy-set of each circuit from the ideal answer, and then pass this along to our heavy-set projector function that we defined above." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 6, | ||
"id": "911f8110", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Compute ideal distributions and projectors on the heavy set.\n", | ||
"ideal_probs = [Statevector.from_instruction(circ).probabilities_dict() for circ in qv_circs]\n", | ||
"heavy_projectors = [heavy_projector(probs) for probs in ideal_probs]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "f45f1074", | ||
"metadata": {}, | ||
"source": [ | ||
"Now, in preparation for actual execution, we add measurements to the end of our QV circuits, and compile them for the target device" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 7, | ||
"id": "87e116f2", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Add meauserements to circuits and transpile\n", | ||
"trans_circs = transpile([circ.measure_all(inplace=False) for circ in qv_circs], noisy_sim,\n", | ||
" layout_method='sabre', routing_method='sabre', optimization_level=3)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "460e1859", | ||
"metadata": {}, | ||
"source": [ | ||
"Because the SWAP mapping of the circuit permutes the qubit states, we need the final measurement mapping for each circuit to know which physical qubit corresponds to each measured bit:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 8, | ||
"id": "f2b71415", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Determine final qubit mappings\n", | ||
"qubits = [list(mthree.utils.final_measurement_mapping(circ)) for circ in trans_circs]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "5257a761", | ||
"metadata": {}, | ||
"source": [ | ||
"We are now ready to execute the circuits on the target backend, and mitigate the resulting raw counts:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 9, | ||
"id": "39b5d818", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Execute circuits and mitigate\n", | ||
"raw_counts = noisy_sim.run(trans_circs, shots=8192).result().get_counts()\n", | ||
"quasi_collection = mit.apply_correction(raw_counts, qubits)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "32b82cd1", | ||
"metadata": {}, | ||
"source": [ | ||
"The value needed to determine if each circuit represents a passing QV value is determined by the expectation value of the heavy projector for each circuit:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 10, | ||
"id": "b8136595", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"array([0.64273103, 0.73990926, 0.7367156 , 0.68290608, 0.7421638 ,\n", | ||
" 0.66162356, 0.70204107, 0.67630205, 0.73943566, 0.73140044])" | ||
] | ||
}, | ||
"execution_count": 10, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"# Determine expectation value of heavy set prjector\n", | ||
"expvals = quasi_collection.expval(heavy_projectors)\n", | ||
"expvals" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "42880efe", | ||
"metadata": {}, | ||
"source": [ | ||
"A passing QV score is one where the expectation value is above 2/3:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 12, | ||
"id": "ac23ea82", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"array([False, True, True, True, True, False, True, True, True,\n", | ||
" True])" | ||
] | ||
}, | ||
"execution_count": 12, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"# Check if the scores are passing or not\n", | ||
"expvals > 2/3" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "93b1ff8d", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [] | ||
} | ||
], | ||
"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.9.6" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |