-
-
Notifications
You must be signed in to change notification settings - Fork 139
/
cdr_api.myst
192 lines (134 loc) · 4.34 KB
/
cdr_api.myst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
---
jupytext:
text_representation:
extension: .myst
format_name: myst
format_version: 0.13
jupytext_version: 1.11.4
kernelspec:
display_name: Python 3
language: python
name: python3
---
# Clifford data regression API
+++
This example shows how to use Clifford data regression (CDR) by means of a simple example.
```{code-cell} ipython3
import warnings
warnings.filterwarnings("ignore")
import numpy as np
import cirq
from mitiq import cdr, Observable, PauliString
```
## Setup
+++
To use CDR, we call `cdr.execute_with_cdr` with four "ingredients":
1. A quantum circuit to prepare a state $\rho$.
1. A quantum computer or noisy simulator to return a `mitiq.QuantumResult` from $\rho$.
1. An observable $O$ which specifies what we wish to compute via $\text{Tr} [ \rho O ]$.
1. A near-Clifford (classical) circuit simulator.
+++
### (1) Circuit
+++
The circuit can be specified as any quantum circuit supported by Mitiq but **must be compiled into the gateset $\{ \sqrt{X}, Z, \text{CNOT}\}$.**
```{code-cell} ipython3
a, b = cirq.LineQubit.range(2)
circuit = cirq.Circuit(
cirq.rx(0.1).on(a),
cirq.rx(-0.72).on(b),
cirq.rz(0.4).on(a),
cirq.rz(0.2).on(b),
cirq.CNOT.on(a, b),
cirq.rx(-0.1).on(b),
cirq.rz(-0.23).on(a),
cirq.CNOT.on(b, a),
cirq.rx(-0.112).on(a),
)
circuit
```
### (2) Executor
+++
The executor inputs a circuit and returns a `mitiq.QuantumResult`. Typically this function will send the circuit to a quantum computer and wait for the results. Here for sake of example we use a simulator that adds single-qubit depolarizing noise after each moment and returns the final density matrix.
```{code-cell} ipython3
from mitiq.interface.mitiq_cirq import compute_density_matrix
compute_density_matrix(circuit).round(3)
```
### (3) Observable
+++
The observables $O$ indicates what we wish to compute via $\text{Tr} [ \rho O ]$.
```{code-cell} ipython3
# Observable to measure.
obs = Observable(PauliString("ZZ"), PauliString("X", coeff=-1.75))
print(obs)
```
### (4) (Near-clifford) Simulator
+++
The CDR method creates a set of "training circuits" which are related to the input circuit and are efficiently simulable. These circuits are simulated on a classical (noiseless) simulator to collect data for regression. The simulator should also return a `QuantumResult`.
To use CDR at scale, an efficient near-Clifford circuit simulator must be specified. In this example, the circuit is small enough to use any classical simulator, and we use the same density matrix simulator as above but without noise.
```{code-cell} ipython3
def simulate(circuit: cirq.Circuit) -> np.ndarray:
return compute_density_matrix(circuit, noise_level=(0.0,))
simulate(circuit).round(3)
```
## Results
+++
Now we can run CDR. We first compute the noiseless result then the noisy result to compare to the mitigated result from CDR.
+++
### The noiseless result
```{code-cell} ipython3
obs.expectation(circuit, simulate).real
```
### The noisy result
```{code-cell} ipython3
obs.expectation(circuit, compute_density_matrix).real
```
### The mitigated result
```{code-cell} ipython3
cdr.execute_with_cdr(
circuit,
compute_density_matrix,
observable=obs,
simulator=simulate,
).real
```
## Additional options
+++
In addition to the four necessary arguments shown above, there are additional parameters in CDR.
+++
### Training circuits
+++
One option is how many circuits are in the training set (default is 10). This can be changed as follows.
```{code-cell} ipython3
cdr.execute_with_cdr(
circuit,
compute_density_matrix,
observable=obs,
simulator=simulate,
num_training_circuits=20,
).real
```
Another option is which fit function to use for regresstion (default is `cdr.linear_fit_function`).
+++
### Fit function
```{code-cell} ipython3
cdr.execute_with_cdr(
circuit,
compute_density_matrix,
observable=obs,
simulator=simulate,
fit_function=cdr.linear_fit_function_no_intercept,
).real
```
### Variable noise CDR
+++
The circuit + training circuits can also be run at different noise scale factors to implement [variable noise Clifford data regression](https://arxiv.org/abs/2011.01157).
```{code-cell} ipython3
from mitiq.zne import scaling
cdr.execute_with_cdr(
circuit,
compute_density_matrix,
observable=obs,
simulator=simulate,
scale_factors=(3,),
).real
```