-
-
Notifications
You must be signed in to change notification settings - Fork 166
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create notebook with technique workflow
- Loading branch information
Showing
1 changed file
with
269 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,269 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Noise scaling by probabilistic error amplification (PEA)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Here we scale the noise by scaling the noise level (probability) of inserting operations. For a \"perfect\" noise model and assuming zero sampling error, in the limit of infinite samples these operations would completely cancel the noise, but by scaling up the noise level of the representations of noisy gates, we instead amplify the noise. " | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 1, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from functools import partial\n", | ||
"import numpy as np\n", | ||
"from typing import List\n", | ||
"from cirq import DensityMatrixSimulator, Circuit, depolarize\n", | ||
"from mitiq import QPROGRAM, Executor\n", | ||
"from mitiq.benchmarks import generate_rb_circuits\n", | ||
"from mitiq.pec import represent_operations_in_circuit_with_local_depolarizing_noise, sample_circuit\n", | ||
"from mitiq.zne import RichardsonFactory, LinearFactory, ExpFactory" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Utilities for PEA scaling\n", | ||
"\n", | ||
"We first define some functions to evaluate the quasi-probability distribution at each noise scale factor." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"def generate_scaled_circuits(ideal_circuit: QPROGRAM, scale_factors: List[float], epsilon: float) -> List[QPROGRAM]:\n", | ||
" \"\"\"Returns a list of represented circuits associated to the input array of scale factors.\"\"\"\n", | ||
" \n", | ||
" # This is based on the Lagrange interpolation formula\n", | ||
" scaled_circuits = []\n", | ||
" for s in scale_factors:\n", | ||
" scaled_circuits.append(represent_operations_in_circuit_with_local_depolarizing_noise(ideal_circuit, s * epsilon))\n", | ||
"\n", | ||
" return scaled_circuits" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 3, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"rnd_state = np.random.RandomState(0) # Set a seed" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## The error mitigation problem" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Let us define a function which executes a circuit with depolarizing noise and returns an expectation value." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 4, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"def ideal_executor(circ: Circuit) -> float:\n", | ||
" \"\"\"Simulates a circuit without noise and returns the expectation value\n", | ||
" of the projector |00...><00...|.\n", | ||
" \"\"\"\n", | ||
" rho = DensityMatrixSimulator().simulate(circ).final_density_matrix\n", | ||
" return np.real(rho[0, 0]) \n", | ||
"\n", | ||
"def noisy_executor(circ: Circuit, noise_level, shot_noise=0) -> float:\n", | ||
" \"\"\"Simulates a circuit with depolarizing noise and returns the expectation value\n", | ||
" of the projector |00...><00...|.\n", | ||
" \"\"\"\n", | ||
" noisy_circuit = circ.with_noise(depolarize(noise_level))\n", | ||
" return ideal_executor(noisy_circuit) + rnd_state.normal(scale=shot_noise)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Let us first define a simple RB circuit (ideally equal to the identity):" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 5, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"Circuit under consideration: \n", | ||
" 0: ───Y───X^-0.5───X^-0.5───Y^0───Y^0.5───X^-0.5───Y───X^0───X^-0.5───Y^-0.5───X───Y^0───\n", | ||
"Circuit under consideration (operations): \n", | ||
" [cirq.Y(cirq.LineQubit(0)), (cirq.X**-0.5).on(cirq.LineQubit(0)), (cirq.X**-0.5).on(cirq.LineQubit(0)), (cirq.Y**0.0).on(cirq.LineQubit(0)), (cirq.Y**0.5).on(cirq.LineQubit(0)), (cirq.X**-0.5).on(cirq.LineQubit(0)), cirq.Y(cirq.LineQubit(0)), (cirq.X**0.0).on(cirq.LineQubit(0)), (cirq.X**-0.5).on(cirq.LineQubit(0)), (cirq.Y**-0.5).on(cirq.LineQubit(0)), cirq.X(cirq.LineQubit(0)), (cirq.Y**0.0).on(cirq.LineQubit(0))]\n", | ||
"Number of gates: 12\n", | ||
"Ideal expectation value: 1.0\n", | ||
"Noisy expectation value: 0.5897836685180664\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"ideal_circuit = generate_rb_circuits(n_qubits=1, num_cliffords=5)[0]\n", | ||
"\n", | ||
"print(\"Circuit under consideration: \\n\", ideal_circuit)\n", | ||
"print(\"Circuit under consideration (operations): \\n\", list(ideal_circuit.all_operations()))\n", | ||
"print(\"Number of gates:\", len(list(ideal_circuit.all_operations())))\n", | ||
"print(\"Ideal expectation value:\", ideal_executor(ideal_circuit))\n", | ||
"print(\"Noisy expectation value:\", noisy_executor(ideal_circuit, noise_level=0.1))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"For reproducibility, we hard code one of the random circuits produced by the previous cell." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 6, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"ename": "NameError", | ||
"evalue": "name 'cirq' is not defined", | ||
"output_type": "error", | ||
"traceback": [ | ||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", | ||
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", | ||
"Cell \u001b[0;32mIn[6], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m ideal_circuit \u001b[38;5;241m=\u001b[39m Circuit([(\u001b[43mcirq\u001b[49m\u001b[38;5;241m.\u001b[39mX\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m0.5\u001b[39m)\u001b[38;5;241m.\u001b[39mon(cirq\u001b[38;5;241m.\u001b[39mLineQubit(\u001b[38;5;241m0\u001b[39m)), (cirq\u001b[38;5;241m.\u001b[39mY\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m0.5\u001b[39m)\u001b[38;5;241m.\u001b[39mon(cirq\u001b[38;5;241m.\u001b[39mLineQubit(\u001b[38;5;241m0\u001b[39m)), (cirq\u001b[38;5;241m.\u001b[39mX\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m0.5\u001b[39m)\u001b[38;5;241m.\u001b[39mon(cirq\u001b[38;5;241m.\u001b[39mLineQubit(\u001b[38;5;241m0\u001b[39m)), (cirq\u001b[38;5;241m.\u001b[39mY\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m0.0\u001b[39m)\u001b[38;5;241m.\u001b[39mon(cirq\u001b[38;5;241m.\u001b[39mLineQubit(\u001b[38;5;241m0\u001b[39m)), (cirq\u001b[38;5;241m.\u001b[39mX\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m0.5\u001b[39m)\u001b[38;5;241m.\u001b[39mon(cirq\u001b[38;5;241m.\u001b[39mLineQubit(\u001b[38;5;241m0\u001b[39m)), (cirq\u001b[38;5;241m.\u001b[39mY\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m0.5\u001b[39m)\u001b[38;5;241m.\u001b[39mon(cirq\u001b[38;5;241m.\u001b[39mLineQubit(\u001b[38;5;241m0\u001b[39m)), (cirq\u001b[38;5;241m.\u001b[39mX\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m0.5\u001b[39m)\u001b[38;5;241m.\u001b[39mon(cirq\u001b[38;5;241m.\u001b[39mLineQubit(\u001b[38;5;241m0\u001b[39m)), (cirq\u001b[38;5;241m.\u001b[39mY\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m0.0\u001b[39m)\u001b[38;5;241m.\u001b[39mon(cirq\u001b[38;5;241m.\u001b[39mLineQubit(\u001b[38;5;241m0\u001b[39m)), (cirq\u001b[38;5;241m.\u001b[39mY\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m0.5\u001b[39m)\u001b[38;5;241m.\u001b[39mon(cirq\u001b[38;5;241m.\u001b[39mLineQubit(\u001b[38;5;241m0\u001b[39m)), (cirq\u001b[38;5;241m.\u001b[39mX\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m0.5\u001b[39m)\u001b[38;5;241m.\u001b[39mon(cirq\u001b[38;5;241m.\u001b[39mLineQubit(\u001b[38;5;241m0\u001b[39m)), (cirq\u001b[38;5;241m.\u001b[39mY\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m0.5\u001b[39m)\u001b[38;5;241m.\u001b[39mon(cirq\u001b[38;5;241m.\u001b[39mLineQubit(\u001b[38;5;241m0\u001b[39m)), (cirq\u001b[38;5;241m.\u001b[39mY\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m0.5\u001b[39m)\u001b[38;5;241m.\u001b[39mon(cirq\u001b[38;5;241m.\u001b[39mLineQubit(\u001b[38;5;241m0\u001b[39m)), (cirq\u001b[38;5;241m.\u001b[39mX\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m0.5\u001b[39m)\u001b[38;5;241m.\u001b[39mon(cirq\u001b[38;5;241m.\u001b[39mLineQubit(\u001b[38;5;241m0\u001b[39m)), (cirq\u001b[38;5;241m.\u001b[39mY\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m0.5\u001b[39m)\u001b[38;5;241m.\u001b[39mon(cirq\u001b[38;5;241m.\u001b[39mLineQubit(\u001b[38;5;241m0\u001b[39m))])\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCircuit under consideration: \u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m, ideal_circuit)\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCircuit under consideration (operations): \u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28mlist\u001b[39m(ideal_circuit\u001b[38;5;241m.\u001b[39mall_operations()))\n", | ||
"\u001b[0;31mNameError\u001b[0m: name 'cirq' is not defined" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"ideal_circuit = Circuit([(cirq.X**0.5).on(cirq.LineQubit(0)), (cirq.Y**-0.5).on(cirq.LineQubit(0)), (cirq.X**-0.5).on(cirq.LineQubit(0)), (cirq.Y**0.0).on(cirq.LineQubit(0)), (cirq.X**-0.5).on(cirq.LineQubit(0)), (cirq.Y**0.5).on(cirq.LineQubit(0)), (cirq.X**0.5).on(cirq.LineQubit(0)), (cirq.Y**0.0).on(cirq.LineQubit(0)), (cirq.Y**-0.5).on(cirq.LineQubit(0)), (cirq.X**0.5).on(cirq.LineQubit(0)), (cirq.Y**-0.5).on(cirq.LineQubit(0)), (cirq.Y**0.5).on(cirq.LineQubit(0)), (cirq.X**0.5).on(cirq.LineQubit(0)), (cirq.Y**0.5).on(cirq.LineQubit(0))])\n", | ||
"print(\"Circuit under consideration: \\n\", ideal_circuit)\n", | ||
"print(\"Circuit under consideration (operations): \\n\", list(ideal_circuit.all_operations()))\n", | ||
"print(\"Number of gates:\", len(list(ideal_circuit.all_operations())))\n", | ||
"print(\"Ideal expectation value:\", ideal_executor(ideal_circuit))\n", | ||
"print(\"Noisy expectation value:\", noisy_executor(ideal_circuit, noise_level=0.1))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Evaluate at specified noise scale factors and try different extrapolation methods" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"TODO: debug strange results" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"[ 5878.47204188 -12853.64182268 -6915.02213355 12673.12681408\n", | ||
" 6323.09180917 12649.8775832 -12860.84327005 -11999.30828589\n", | ||
" -12423.1504578 -12424.31308024 -11984.4187845 6744.31534865\n", | ||
" 12155.47612879 -12059.00405673 6397.2674155 -6469.34585305\n", | ||
" -12829.70688901 12169.96794703 12164.46163181 6761.18300759\n", | ||
" 5833.52644101 -6039.96535747 11912.13951882 -6064.17482793\n", | ||
" -6594.00931971 6667.0034694 6370.96508375 12647.12199779\n", | ||
" -12042.7403315 -6899.75860747 6364.78017489 6366.36511181\n", | ||
" 5858.43344581 6383.33512783 6692.95289302 -12394.64133786\n", | ||
" -12758.31801426 5932.19211577 12608.73876951 -6087.64492271\n", | ||
" 6368.47123325 12169.46782746 -6138.84096235 -12334.66171021\n", | ||
" -6467.6953855 6330.7262836 -6576.89981679 6722.80225312\n", | ||
" -12423.97313491 5821.27036642]\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"scale_factors = [1, 3, 5, 7]\n", | ||
"scaled_circuit_reps = generate_scaled_circuits(ideal_circuit, scale_factors, epsilon=0.05)\n", | ||
"\n", | ||
"scaled_results = []\n", | ||
"for circuit_reps in scaled_circuit_reps:\n", | ||
" sampled_circuits, signs, norm = sample_circuit(ideal_circuit, circuit_reps, random_state=rnd_state, num_samples=50,)\n", | ||
" noisy_execute = partial(noisy_executor, noise_level = 0.05)\n", | ||
" executor = Executor(noisy_execute)\n", | ||
" results = executor.evaluate(sampled_circuits, force_run_all=False)\n", | ||
" scaled_results.append( [norm * s * val for s, val in zip(signs, results)])\n", | ||
"\n", | ||
"print(LinearFactory(scale_factors).extrapolate(scale_factors, scaled_results))\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Test PEA at different noise levels (TODO)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Compare with folding ZNE and PEC (TODO)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Visualize data (TODO)" | ||
] | ||
} | ||
], | ||
"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.10.4" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |