Skip to content

Commit

Permalink
Create notebook with technique workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
Misty-W committed Jun 6, 2024
1 parent 837ea83 commit eadf1af
Showing 1 changed file with 269 additions and 0 deletions.
269 changes: 269 additions & 0 deletions docs/source/examples/prob_error_amp.ipynb
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
}

0 comments on commit eadf1af

Please sign in to comment.