2
2
General Noise Model Construction.
3
3
"""
4
4
import logging
5
-
6
5
from typing import Any , Sequence , Optional , List , Dict
7
- from tensorcircuit .abstractcircuit import AbstractCircuit
6
+
7
+ from .abstractcircuit import AbstractCircuit
8
8
from . import gates
9
9
from . import Circuit , DMCircuit
10
10
from .cons import backend
11
+ from .channels import KrausList
11
12
12
13
Gate = gates .Gate
13
14
Tensor = Any
@@ -22,19 +23,17 @@ class NoiseConf:
22
23
23
24
error1 = tc.channels.generaldepolarizingchannel(0.1, 1)
24
25
error2 = tc.channels.thermalrelaxationchannel(300, 400, 100, "ByChoi", 0)
25
- readout_error = [[0.9, 0.75],[0.4, 0.7]]
26
+ readout_error = [[0.9, 0.75], [0.4, 0.7]]
26
27
27
28
noise_conf = NoiseConf()
28
- noise_conf.add_noise("x",error1)
29
- noise_conf.add_noise("h",[error1,error2],[[0],[1]])
29
+ noise_conf.add_noise("x", error1)
30
+ noise_conf.add_noise("h", [error1, error2], [[0], [1]])
30
31
noise_conf.add_noise("readout", readout_error)
31
-
32
32
"""
33
33
34
34
def __init__ (self ) -> None :
35
35
"""
36
36
Establish a noise configuration.
37
-
38
37
"""
39
38
self .nc = {} # type: ignore
40
39
self .has_quantum = False
@@ -43,16 +42,17 @@ def __init__(self) -> None:
43
42
def add_noise (
44
43
self ,
45
44
gate_name : str ,
46
- kraus : Sequence [Gate ],
45
+ kraus : Sequence [KrausList ],
47
46
qubit : Optional [Sequence [Any ]] = None ,
48
47
) -> None :
49
- """Add noise channels on specific gates and specific qubits in form of Kraus operators.
48
+ """
49
+ Add noise channels on specific gates and specific qubits in form of Kraus operators.
50
50
51
51
:param gate_name: noisy gate
52
52
:type gate_name: str
53
53
:param kraus: noise channel
54
54
:type kraus: Sequence[Gate]
55
- :param qubit: the list of noisy qubit, defaults to None
55
+ :param qubit: the list of noisy qubit, defaults to None, indicating applying the noise channel on all qubits
56
56
:type qubit: Optional[Sequence[Any]], optional
57
57
"""
58
58
if gate_name not in self .nc :
@@ -74,25 +74,24 @@ def add_noise(
74
74
75
75
76
76
def apply_qir_with_noise (
77
- c : AbstractCircuit ,
77
+ c : Any ,
78
78
qir : List [Dict [str , Any ]],
79
79
noise_conf : NoiseConf ,
80
- status : Optional [Sequence [ Any ] ] = None ,
81
- ) -> AbstractCircuit :
80
+ status : Optional [Tensor ] = None ,
81
+ ) -> Any :
82
82
"""
83
83
84
84
:param c: A newly defined circuit
85
85
:type c: AbstractCircuit
86
- :param qir: The qir of the objective circuit
86
+ :param qir: The qir of the clean circuit
87
87
:type qir: List[Dict[str, Any]]
88
88
:param noise_conf: Noise Configuration
89
89
:type noise_conf: NoiseConf
90
90
:param status: The status for Monte Carlo sampling, defaults to None
91
- :type status: Optional[Sequence[Any]] , optional
91
+ :type status: 1D Tensor , optional
92
92
:return: A newly constructed circuit with noise
93
93
:rtype: AbstractCircuit
94
94
"""
95
-
96
95
quantum_index = 0
97
96
for d in qir :
98
97
if "parameters" not in d : # paramized gate
@@ -129,13 +128,13 @@ def apply_qir_with_noise(
129
128
noise_kraus = noise_conf .nc [d ["name" ]][d ["index" ]]
130
129
131
130
if noise_kraus .is_unitary is True :
132
- c .unitary_kraus ( # type: ignore
131
+ c .unitary_kraus (
133
132
noise_kraus ,
134
133
* d ["index" ],
135
134
status = status [quantum_index ] # type: ignore
136
135
)
137
136
else :
138
- c .general_kraus ( # type: ignore
137
+ c .general_kraus (
139
138
noise_kraus ,
140
139
* d ["index" ],
141
140
status = status [quantum_index ] # type: ignore
@@ -146,16 +145,16 @@ def apply_qir_with_noise(
146
145
147
146
148
147
def circuit_with_noise (
149
- c : AbstractCircuit , noise_conf : NoiseConf , status : Optional [Sequence [ Any ] ] = None
150
- ) -> AbstractCircuit :
151
- """Noisify an objective circuit.
148
+ c : AbstractCircuit , noise_conf : NoiseConf , status : Optional [Tensor ] = None
149
+ ) -> Any :
150
+ """Noisify a clean circuit.
152
151
153
- :param c: An objective circuit
152
+ :param c: A clean circuit
154
153
:type c: AbstractCircuit
155
154
:param noise_conf: Noise Configuration
156
155
:type noise_conf: NoiseConf
157
156
:param status: The status for Monte Carlo sampling, defaults to None
158
- :type status: Optional[Sequence[Any]] , optional
157
+ :type status: 1D Tensor , optional
159
158
:return: A newly constructed circuit with noise
160
159
:rtype: AbstractCircuit
161
160
"""
@@ -170,13 +169,13 @@ def circuit_with_noise(
170
169
171
170
172
171
def expectation_ps_noisfy (
173
- c : AbstractCircuit ,
172
+ c : Any ,
174
173
x : Optional [Sequence [int ]] = None ,
175
174
y : Optional [Sequence [int ]] = None ,
176
175
z : Optional [Sequence [int ]] = None ,
177
176
noise_conf : Optional [NoiseConf ] = None ,
178
177
nmc : int = 1000 ,
179
- status : Optional [Sequence [ Any ] ] = None ,
178
+ status : Optional [Tensor ] = None ,
180
179
) -> Tensor :
181
180
182
181
if noise_conf is None :
@@ -201,8 +200,8 @@ def expectation_ps_noisfy(
201
200
# monte carlo
202
201
else :
203
202
204
- def mcsim (status ): # type: ignore
205
- cnoise = circuit_with_noise (c , noise_conf , status ) # type: ignore
203
+ def mcsim (status : Optional [ Tensor ]) -> Tensor :
204
+ cnoise = circuit_with_noise (c , noise_conf , status ) # type: ignore
206
205
return cnoise .expectation_ps (x = x , y = y , z = z )
207
206
208
207
mcsim_vmap = backend .vmap (mcsim , vectorized_argnums = 0 )
@@ -219,14 +218,14 @@ def mcsim(status): # type: ignore
219
218
220
219
221
220
def sample_expectation_ps_noisfy (
222
- c : AbstractCircuit ,
221
+ c : Any ,
223
222
x : Optional [Sequence [int ]] = None ,
224
223
y : Optional [Sequence [int ]] = None ,
225
224
z : Optional [Sequence [int ]] = None ,
226
225
noise_conf : Optional [NoiseConf ] = None ,
227
226
nmc : int = 1000 ,
228
227
shots : Optional [int ] = None ,
229
- status : Optional [Sequence [ Any ] ] = None ,
228
+ status : Optional [Tensor ] = None ,
230
229
) -> Tensor :
231
230
232
231
if noise_conf is None :
@@ -245,17 +244,17 @@ def sample_expectation_ps_noisfy(
245
244
246
245
# density matrix
247
246
if isinstance (c , DMCircuit ):
248
- cnoise = circuit_with_noise (c , noise_conf )
249
- return cnoise .sample_expectation_ps ( # type: ignore
247
+ cnoise = circuit_with_noise (c , noise_conf ) # type: ignore
248
+ return cnoise .sample_expectation_ps (
250
249
x = x , y = y , z = z , shots = shots , readout_error = readout_error
251
250
)
252
251
253
252
# monte carlo
254
253
else :
255
254
256
- def mcsim (status ): # type: ignore
257
- cnoise = circuit_with_noise (c , noise_conf , status ) # type: ignore
258
- return cnoise .sample_expectation_ps ( # type: ignore
255
+ def mcsim (status : Optional [ Tensor ]) -> Tensor :
256
+ cnoise = circuit_with_noise (c , noise_conf , status ) # type: ignore
257
+ return cnoise .sample_expectation_ps (
259
258
x = x , y = y , z = z , shots = shots , readout_error = readout_error
260
259
)
261
260
@@ -268,7 +267,7 @@ def mcsim(status): # type: ignore
268
267
return value
269
268
270
269
else :
271
- value = c .sample_expectation_ps ( # type: ignore
270
+ value = c .sample_expectation_ps (
272
271
x = x , y = y , z = z , shots = shots , readout_error = readout_error
273
272
)
274
273
return value
0 commit comments