pyGSTi 0.9.12.1__cp310-cp310-win32.whl → 0.9.13__cp310-cp310-win32.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (221) hide show
  1. pyGSTi-0.9.13.dist-info/METADATA +197 -0
  2. {pyGSTi-0.9.12.1.dist-info → pyGSTi-0.9.13.dist-info}/RECORD +207 -217
  3. {pyGSTi-0.9.12.1.dist-info → pyGSTi-0.9.13.dist-info}/WHEEL +1 -1
  4. pygsti/_version.py +2 -2
  5. pygsti/algorithms/contract.py +1 -1
  6. pygsti/algorithms/core.py +42 -28
  7. pygsti/algorithms/fiducialselection.py +17 -8
  8. pygsti/algorithms/gaugeopt.py +2 -2
  9. pygsti/algorithms/germselection.py +87 -77
  10. pygsti/algorithms/mirroring.py +0 -388
  11. pygsti/algorithms/randomcircuit.py +165 -1333
  12. pygsti/algorithms/rbfit.py +0 -234
  13. pygsti/baseobjs/basis.py +94 -396
  14. pygsti/baseobjs/errorgenbasis.py +0 -132
  15. pygsti/baseobjs/errorgenspace.py +0 -10
  16. pygsti/baseobjs/label.py +52 -168
  17. pygsti/baseobjs/opcalc/fastopcalc.cp310-win32.pyd +0 -0
  18. pygsti/baseobjs/opcalc/fastopcalc.pyx +2 -2
  19. pygsti/baseobjs/polynomial.py +13 -595
  20. pygsti/baseobjs/statespace.py +1 -0
  21. pygsti/circuits/__init__.py +1 -1
  22. pygsti/circuits/circuit.py +682 -505
  23. pygsti/circuits/circuitconstruction.py +0 -4
  24. pygsti/circuits/circuitlist.py +47 -5
  25. pygsti/circuits/circuitparser/__init__.py +8 -8
  26. pygsti/circuits/circuitparser/fastcircuitparser.cp310-win32.pyd +0 -0
  27. pygsti/circuits/circuitstructure.py +3 -3
  28. pygsti/circuits/cloudcircuitconstruction.py +1 -1
  29. pygsti/data/datacomparator.py +2 -7
  30. pygsti/data/dataset.py +46 -44
  31. pygsti/data/hypothesistest.py +0 -7
  32. pygsti/drivers/bootstrap.py +0 -49
  33. pygsti/drivers/longsequence.py +2 -1
  34. pygsti/evotypes/basereps_cython.cp310-win32.pyd +0 -0
  35. pygsti/evotypes/chp/opreps.py +0 -61
  36. pygsti/evotypes/chp/statereps.py +0 -32
  37. pygsti/evotypes/densitymx/effectcreps.cpp +9 -10
  38. pygsti/evotypes/densitymx/effectreps.cp310-win32.pyd +0 -0
  39. pygsti/evotypes/densitymx/effectreps.pyx +1 -1
  40. pygsti/evotypes/densitymx/opreps.cp310-win32.pyd +0 -0
  41. pygsti/evotypes/densitymx/opreps.pyx +2 -2
  42. pygsti/evotypes/densitymx/statereps.cp310-win32.pyd +0 -0
  43. pygsti/evotypes/densitymx/statereps.pyx +1 -1
  44. pygsti/evotypes/densitymx_slow/effectreps.py +7 -23
  45. pygsti/evotypes/densitymx_slow/opreps.py +16 -23
  46. pygsti/evotypes/densitymx_slow/statereps.py +10 -3
  47. pygsti/evotypes/evotype.py +39 -2
  48. pygsti/evotypes/stabilizer/effectreps.cp310-win32.pyd +0 -0
  49. pygsti/evotypes/stabilizer/effectreps.pyx +0 -4
  50. pygsti/evotypes/stabilizer/opreps.cp310-win32.pyd +0 -0
  51. pygsti/evotypes/stabilizer/opreps.pyx +0 -4
  52. pygsti/evotypes/stabilizer/statereps.cp310-win32.pyd +0 -0
  53. pygsti/evotypes/stabilizer/statereps.pyx +1 -5
  54. pygsti/evotypes/stabilizer/termreps.cp310-win32.pyd +0 -0
  55. pygsti/evotypes/stabilizer/termreps.pyx +0 -7
  56. pygsti/evotypes/stabilizer_slow/effectreps.py +0 -22
  57. pygsti/evotypes/stabilizer_slow/opreps.py +0 -4
  58. pygsti/evotypes/stabilizer_slow/statereps.py +0 -4
  59. pygsti/evotypes/statevec/effectreps.cp310-win32.pyd +0 -0
  60. pygsti/evotypes/statevec/effectreps.pyx +1 -1
  61. pygsti/evotypes/statevec/opreps.cp310-win32.pyd +0 -0
  62. pygsti/evotypes/statevec/opreps.pyx +2 -2
  63. pygsti/evotypes/statevec/statereps.cp310-win32.pyd +0 -0
  64. pygsti/evotypes/statevec/statereps.pyx +1 -1
  65. pygsti/evotypes/statevec/termreps.cp310-win32.pyd +0 -0
  66. pygsti/evotypes/statevec/termreps.pyx +0 -7
  67. pygsti/evotypes/statevec_slow/effectreps.py +0 -3
  68. pygsti/evotypes/statevec_slow/opreps.py +0 -5
  69. pygsti/extras/__init__.py +0 -1
  70. pygsti/extras/drift/stabilityanalyzer.py +3 -1
  71. pygsti/extras/interpygate/__init__.py +12 -0
  72. pygsti/extras/interpygate/core.py +0 -36
  73. pygsti/extras/interpygate/process_tomography.py +44 -10
  74. pygsti/extras/rpe/rpeconstruction.py +0 -2
  75. pygsti/forwardsims/__init__.py +1 -0
  76. pygsti/forwardsims/forwardsim.py +14 -55
  77. pygsti/forwardsims/mapforwardsim.py +69 -18
  78. pygsti/forwardsims/mapforwardsim_calc_densitymx.cp310-win32.pyd +0 -0
  79. pygsti/forwardsims/mapforwardsim_calc_densitymx.pyx +65 -66
  80. pygsti/forwardsims/mapforwardsim_calc_generic.py +91 -13
  81. pygsti/forwardsims/matrixforwardsim.py +63 -15
  82. pygsti/forwardsims/termforwardsim.py +8 -110
  83. pygsti/forwardsims/termforwardsim_calc_stabilizer.cp310-win32.pyd +0 -0
  84. pygsti/forwardsims/termforwardsim_calc_statevec.cp310-win32.pyd +0 -0
  85. pygsti/forwardsims/termforwardsim_calc_statevec.pyx +0 -651
  86. pygsti/forwardsims/torchfwdsim.py +265 -0
  87. pygsti/forwardsims/weakforwardsim.py +2 -2
  88. pygsti/io/__init__.py +1 -2
  89. pygsti/io/mongodb.py +0 -2
  90. pygsti/io/stdinput.py +6 -22
  91. pygsti/layouts/copalayout.py +10 -12
  92. pygsti/layouts/distlayout.py +0 -40
  93. pygsti/layouts/maplayout.py +103 -25
  94. pygsti/layouts/matrixlayout.py +99 -60
  95. pygsti/layouts/prefixtable.py +1534 -52
  96. pygsti/layouts/termlayout.py +1 -1
  97. pygsti/modelmembers/instruments/instrument.py +3 -3
  98. pygsti/modelmembers/instruments/tpinstrument.py +2 -2
  99. pygsti/modelmembers/modelmember.py +0 -17
  100. pygsti/modelmembers/operations/__init__.py +2 -4
  101. pygsti/modelmembers/operations/affineshiftop.py +1 -0
  102. pygsti/modelmembers/operations/composederrorgen.py +1 -1
  103. pygsti/modelmembers/operations/composedop.py +1 -24
  104. pygsti/modelmembers/operations/denseop.py +5 -5
  105. pygsti/modelmembers/operations/eigpdenseop.py +2 -2
  106. pygsti/modelmembers/operations/embeddederrorgen.py +1 -1
  107. pygsti/modelmembers/operations/embeddedop.py +0 -1
  108. pygsti/modelmembers/operations/experrorgenop.py +2 -2
  109. pygsti/modelmembers/operations/fullarbitraryop.py +1 -0
  110. pygsti/modelmembers/operations/fullcptpop.py +2 -2
  111. pygsti/modelmembers/operations/fulltpop.py +28 -6
  112. pygsti/modelmembers/operations/fullunitaryop.py +5 -4
  113. pygsti/modelmembers/operations/lindbladcoefficients.py +93 -78
  114. pygsti/modelmembers/operations/lindbladerrorgen.py +268 -441
  115. pygsti/modelmembers/operations/linearop.py +7 -27
  116. pygsti/modelmembers/operations/opfactory.py +1 -1
  117. pygsti/modelmembers/operations/repeatedop.py +1 -24
  118. pygsti/modelmembers/operations/staticstdop.py +1 -1
  119. pygsti/modelmembers/povms/__init__.py +3 -3
  120. pygsti/modelmembers/povms/basepovm.py +7 -36
  121. pygsti/modelmembers/povms/complementeffect.py +4 -9
  122. pygsti/modelmembers/povms/composedeffect.py +0 -320
  123. pygsti/modelmembers/povms/computationaleffect.py +1 -1
  124. pygsti/modelmembers/povms/computationalpovm.py +3 -1
  125. pygsti/modelmembers/povms/effect.py +3 -5
  126. pygsti/modelmembers/povms/marginalizedpovm.py +0 -79
  127. pygsti/modelmembers/povms/tppovm.py +74 -2
  128. pygsti/modelmembers/states/__init__.py +2 -5
  129. pygsti/modelmembers/states/composedstate.py +0 -317
  130. pygsti/modelmembers/states/computationalstate.py +3 -3
  131. pygsti/modelmembers/states/cptpstate.py +4 -4
  132. pygsti/modelmembers/states/densestate.py +6 -4
  133. pygsti/modelmembers/states/fullpurestate.py +0 -24
  134. pygsti/modelmembers/states/purestate.py +1 -1
  135. pygsti/modelmembers/states/state.py +5 -6
  136. pygsti/modelmembers/states/tpstate.py +28 -10
  137. pygsti/modelmembers/term.py +3 -6
  138. pygsti/modelmembers/torchable.py +50 -0
  139. pygsti/modelpacks/_modelpack.py +1 -1
  140. pygsti/modelpacks/smq1Q_ZN.py +3 -1
  141. pygsti/modelpacks/smq2Q_XXYYII.py +2 -1
  142. pygsti/modelpacks/smq2Q_XY.py +3 -3
  143. pygsti/modelpacks/smq2Q_XYI.py +2 -2
  144. pygsti/modelpacks/smq2Q_XYICNOT.py +3 -3
  145. pygsti/modelpacks/smq2Q_XYICPHASE.py +3 -3
  146. pygsti/modelpacks/smq2Q_XYXX.py +1 -1
  147. pygsti/modelpacks/smq2Q_XYZICNOT.py +3 -3
  148. pygsti/modelpacks/smq2Q_XYZZ.py +1 -1
  149. pygsti/modelpacks/stdtarget.py +0 -121
  150. pygsti/models/cloudnoisemodel.py +1 -2
  151. pygsti/models/explicitcalc.py +3 -3
  152. pygsti/models/explicitmodel.py +3 -13
  153. pygsti/models/fogistore.py +5 -3
  154. pygsti/models/localnoisemodel.py +1 -2
  155. pygsti/models/memberdict.py +0 -12
  156. pygsti/models/model.py +800 -65
  157. pygsti/models/modelconstruction.py +4 -4
  158. pygsti/models/modelnoise.py +2 -2
  159. pygsti/models/modelparaminterposer.py +1 -1
  160. pygsti/models/oplessmodel.py +1 -1
  161. pygsti/models/qutrit.py +15 -14
  162. pygsti/objectivefns/objectivefns.py +73 -138
  163. pygsti/objectivefns/wildcardbudget.py +2 -7
  164. pygsti/optimize/__init__.py +1 -0
  165. pygsti/optimize/arraysinterface.py +28 -0
  166. pygsti/optimize/customcg.py +0 -12
  167. pygsti/optimize/customlm.py +129 -323
  168. pygsti/optimize/customsolve.py +2 -2
  169. pygsti/optimize/optimize.py +0 -84
  170. pygsti/optimize/simplerlm.py +841 -0
  171. pygsti/optimize/wildcardopt.py +19 -598
  172. pygsti/protocols/confidenceregionfactory.py +28 -14
  173. pygsti/protocols/estimate.py +31 -14
  174. pygsti/protocols/gst.py +142 -68
  175. pygsti/protocols/modeltest.py +6 -10
  176. pygsti/protocols/protocol.py +9 -37
  177. pygsti/protocols/rb.py +450 -79
  178. pygsti/protocols/treenode.py +8 -2
  179. pygsti/protocols/vb.py +108 -206
  180. pygsti/protocols/vbdataframe.py +1 -1
  181. pygsti/report/factory.py +0 -15
  182. pygsti/report/fogidiagram.py +1 -17
  183. pygsti/report/modelfunction.py +12 -3
  184. pygsti/report/mpl_colormaps.py +1 -1
  185. pygsti/report/plothelpers.py +8 -2
  186. pygsti/report/reportables.py +41 -37
  187. pygsti/report/templates/offline/pygsti_dashboard.css +6 -0
  188. pygsti/report/templates/offline/pygsti_dashboard.js +12 -0
  189. pygsti/report/workspace.py +2 -14
  190. pygsti/report/workspaceplots.py +326 -504
  191. pygsti/tools/basistools.py +9 -36
  192. pygsti/tools/edesigntools.py +124 -96
  193. pygsti/tools/fastcalc.cp310-win32.pyd +0 -0
  194. pygsti/tools/fastcalc.pyx +35 -81
  195. pygsti/tools/internalgates.py +151 -15
  196. pygsti/tools/jamiolkowski.py +5 -5
  197. pygsti/tools/lindbladtools.py +19 -11
  198. pygsti/tools/listtools.py +0 -114
  199. pygsti/tools/matrixmod2.py +1 -1
  200. pygsti/tools/matrixtools.py +173 -339
  201. pygsti/tools/nameddict.py +1 -1
  202. pygsti/tools/optools.py +154 -88
  203. pygsti/tools/pdftools.py +0 -25
  204. pygsti/tools/rbtheory.py +3 -320
  205. pygsti/tools/slicetools.py +64 -12
  206. pyGSTi-0.9.12.1.dist-info/METADATA +0 -155
  207. pygsti/algorithms/directx.py +0 -711
  208. pygsti/evotypes/qibo/__init__.py +0 -33
  209. pygsti/evotypes/qibo/effectreps.py +0 -78
  210. pygsti/evotypes/qibo/opreps.py +0 -376
  211. pygsti/evotypes/qibo/povmreps.py +0 -98
  212. pygsti/evotypes/qibo/statereps.py +0 -174
  213. pygsti/extras/rb/__init__.py +0 -13
  214. pygsti/extras/rb/benchmarker.py +0 -957
  215. pygsti/extras/rb/dataset.py +0 -378
  216. pygsti/extras/rb/io.py +0 -814
  217. pygsti/extras/rb/simulate.py +0 -1020
  218. pygsti/io/legacyio.py +0 -385
  219. pygsti/modelmembers/povms/denseeffect.py +0 -142
  220. {pyGSTi-0.9.12.1.dist-info → pyGSTi-0.9.13.dist-info}/LICENSE +0 -0
  221. {pyGSTi-0.9.12.1.dist-info → pyGSTi-0.9.13.dist-info}/top_level.txt +0 -0
@@ -1,1020 +0,0 @@
1
- """ Clifford circuits with Pauli errors simulation functions """
2
- #***************************************************************************************************
3
- # Copyright 2015, 2019 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
4
- # Under the terms of Contract DE-NA0003525 with NTESS, the U.S. Government retains certain rights
5
- # in this software.
6
- # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7
- # in compliance with the License. You may obtain a copy of the License at
8
- # http://www.apache.org/licenses/LICENSE-2.0 or in the LICENSE file in the root pyGSTi directory.
9
- #***************************************************************************************************
10
-
11
- import os as _os
12
- import time as _time
13
-
14
- import numpy as _np
15
-
16
- from pygsti.baseobjs.label import Label as _Lbl
17
- from pygsti.data.dataset import DataSet as _DataSet
18
- from pygsti.tools import symplectic as _symp
19
-
20
- #from . import sample as _samp
21
- _samp = None # MOVED - and this module is deprecated & broken now, so just set to None
22
-
23
-
24
- def random_paulierror_in_chp(q):
25
- """
26
- todo.
27
- """
28
- i = _np.random.randint(0, 3)
29
-
30
- if i == 0:
31
- return ('p ' + str(q) + '\n') * 2
32
-
33
- elif i == 1:
34
- return 'h ' + str(q) + '\n' + ('p ' + str(q) + '\n') * 2 + 'h ' + str(q) + '\n'
35
-
36
- else:
37
- return ('p ' + str(q) + '\n') * 2 + 'h ' + str(q) + '\n' + ('p ' + str(q) + '\n') * 2 + 'h ' + str(q) + '\n'
38
-
39
-
40
- def random_pauli_in_chp(q):
41
- """
42
- todo.
43
- """
44
- i = _np.random.randint(0, 4)
45
-
46
- if i == 0:
47
- return ''
48
-
49
- elif i == 1:
50
- return ('p ' + str(q) + '\n') * 2
51
-
52
- elif i == 2:
53
- return 'h ' + str(q) + '\n' + ('p ' + str(q) + '\n') * 2 + 'h ' + str(q) + '\n'
54
-
55
- else:
56
- return ('p ' + str(q) + '\n') * 2 + 'h ' + str(q) + '\n' + ('p ' + str(q) + '\n') * 2 + 'h ' + str(q) + '\n'
57
-
58
-
59
- def stdgate_to_chp(gate, chpqubits):
60
- """
61
- todo
62
- Converts any of the standard Clifford gates to a chp string.
63
- """
64
- gatestr = str(gate).split(':')
65
- name = gatestr[0]
66
- qubits = [chpqubits[q] for q in gatestr[1:]]
67
-
68
- if name == 'Gi':
69
- return ''
70
-
71
- elif name == 'Gxpi':
72
- s = 'h ' + str(qubits[0]) + '\n'
73
- s += ('p ' + str(qubits[0]) + '\n') * 2
74
- s += 'h ' + str(qubits[0]) + '\n'
75
- return s
76
-
77
- elif name == 'Gypi':
78
- s = ('p ' + str(qubits[0]) + '\n') * 2
79
- s += 'h ' + str(qubits[0]) + '\n'
80
- s += ('p ' + str(qubits[0]) + '\n') * 2
81
- s += 'h ' + str(qubits[0]) + '\n'
82
- return s
83
-
84
- elif name == 'Gzpi':
85
- return ('p ' + str(qubits[0]) + '\n') * 2
86
-
87
- elif name == 'Gxpi2':
88
- s = 'h ' + str(qubits[0]) + '\n'
89
- s += 'p ' + str(qubits[0]) + '\n'
90
- s += 'h ' + str(qubits[0]) + '\n'
91
- return s
92
-
93
- elif name == 'Gxmpi2':
94
- s = 'h ' + str(qubits[0]) + '\n'
95
- s += ('p ' + str(qubits[0]) + '\n') * 3
96
- s += 'h ' + str(qubits[0]) + '\n'
97
- return s
98
-
99
- elif name == 'Gzpi2' or name == 'Gp':
100
- return 'p ' + str(qubits[0]) + '\n'
101
-
102
- elif name == 'Gzmpi2' or name == 'Gpdag':
103
- return ('p ' + str(qubits[0]) + '\n') * 3
104
-
105
- elif name == 'Gh':
106
- return ('h ' + str(qubits[0]) + '\n')
107
-
108
- elif name == 'Gc0':
109
- return ''
110
-
111
- elif name == 'Gc1':
112
- s = 'h ' + str(qubits[0]) + '\n'
113
- s += 'p ' + str(qubits[0]) + '\n'
114
- s += 'h ' + str(qubits[0]) + '\n'
115
- s += 'p ' + str(qubits[0]) + '\n'
116
- return s
117
-
118
- elif name == 'Gc2':
119
- s = 'h ' + str(qubits[0]) + '\n'
120
- s += 'p ' + str(qubits[0]) + '\n'
121
- return s
122
-
123
- elif name == 'Gc3':
124
- s = 'h ' + str(qubits[0]) + '\n'
125
- s += 'p ' + str(qubits[0]) + '\n'
126
- s += 'p ' + str(qubits[0]) + '\n'
127
- s += 'h ' + str(qubits[0]) + '\n'
128
- return s
129
-
130
- elif name == 'Gc4':
131
- s = 'p ' + str(qubits[0]) + '\n'
132
- s += 'h ' + str(qubits[0]) + '\n'
133
- s += 'p ' + str(qubits[0]) + '\n'
134
- s += 'p ' + str(qubits[0]) + '\n'
135
- return s
136
-
137
- elif name == 'Gc5':
138
- s = 'h ' + str(qubits[0]) + '\n'
139
- s += 'p ' + str(qubits[0]) + '\n'
140
- s += 'p ' + str(qubits[0]) + '\n'
141
- s += 'p ' + str(qubits[0]) + '\n'
142
- return s
143
-
144
- elif name == 'Gc6':
145
- s = 'h ' + str(qubits[0]) + '\n'
146
- s += 'p ' + str(qubits[0]) + '\n'
147
- s += 'p ' + str(qubits[0]) + '\n'
148
- s += 'h ' + str(qubits[0]) + '\n'
149
- s += 'p ' + str(qubits[0]) + '\n'
150
- s += 'p ' + str(qubits[0]) + '\n'
151
- return s
152
-
153
- elif name == 'Gc7':
154
- s = 'h ' + str(qubits[0]) + '\n'
155
- s += 'p ' + str(qubits[0]) + '\n'
156
- s += 'h ' + str(qubits[0]) + '\n'
157
- s += 'p ' + str(qubits[0]) + '\n'
158
- s += 'p ' + str(qubits[0]) + '\n'
159
- s += 'p ' + str(qubits[0]) + '\n'
160
- return s
161
-
162
- elif name == 'Gc8':
163
- s = 'h ' + str(qubits[0]) + '\n'
164
- s += 'p ' + str(qubits[0]) + '\n'
165
- s += 'h ' + str(qubits[0]) + '\n'
166
- s += 'p ' + str(qubits[0]) + '\n'
167
- s += 'p ' + str(qubits[0]) + '\n'
168
- s += 'h ' + str(qubits[0]) + '\n'
169
- return s
170
-
171
- elif name == 'Gc9':
172
- s = 'p ' + str(qubits[0]) + '\n'
173
- s += 'p ' + str(qubits[0]) + '\n'
174
- return s
175
-
176
- elif name == 'Gc10':
177
- s = 'p ' + str(qubits[0]) + '\n'
178
- s += 'h ' + str(qubits[0]) + '\n'
179
- return s
180
-
181
- elif name == 'Gc11':
182
- s = 'p ' + str(qubits[0]) + '\n'
183
- s += 'p ' + str(qubits[0]) + '\n'
184
- s += 'h ' + str(qubits[0]) + '\n'
185
- s += 'p ' + str(qubits[0]) + '\n'
186
- return s
187
-
188
- elif name == 'Gc12':
189
- s = 'h ' + str(qubits[0]) + '\n'
190
- return s
191
-
192
- elif name == 'Gc13':
193
- s = 'p ' + str(qubits[0]) + '\n'
194
- s += 'h ' + str(qubits[0]) + '\n'
195
- s += 'p ' + str(qubits[0]) + '\n'
196
- return s
197
-
198
- elif name == 'Gc14':
199
- s = 'p ' + str(qubits[0]) + '\n'
200
- return s
201
-
202
- elif name == 'Gc15':
203
- s = 'h ' + str(qubits[0]) + '\n'
204
- s += 'p ' + str(qubits[0]) + '\n'
205
- s += 'p ' + str(qubits[0]) + '\n'
206
- return s
207
-
208
- elif name == 'Gc16':
209
- s = 'h ' + str(qubits[0]) + '\n'
210
- s += 'p ' + str(qubits[0]) + '\n'
211
- s += 'h ' + str(qubits[0]) + '\n'
212
- return s
213
-
214
- elif name == 'Gc17':
215
- s = 'h ' + str(qubits[0]) + '\n'
216
- s += 'p ' + str(qubits[0]) + '\n'
217
- s += 'p ' + str(qubits[0]) + '\n'
218
- s += 'h ' + str(qubits[0]) + '\n'
219
- s += 'p ' + str(qubits[0]) + '\n'
220
- return s
221
-
222
- elif name == 'Gc18':
223
- s = 'p ' + str(qubits[0]) + '\n'
224
- s += 'p ' + str(qubits[0]) + '\n'
225
- s += 'h ' + str(qubits[0]) + '\n'
226
- s += 'p ' + str(qubits[0]) + '\n'
227
- s += 'p ' + str(qubits[0]) + '\n'
228
- return s
229
-
230
- elif name == 'Gc19':
231
- s = 'p ' + str(qubits[0]) + '\n'
232
- s += 'h ' + str(qubits[0]) + '\n'
233
- s += 'p ' + str(qubits[0]) + '\n'
234
- s += 'p ' + str(qubits[0]) + '\n'
235
- s += 'p ' + str(qubits[0]) + '\n'
236
- return s
237
-
238
- elif name == 'Gc20':
239
- s = 'p ' + str(qubits[0]) + '\n'
240
- s += 'h ' + str(qubits[0]) + '\n'
241
- s += 'p ' + str(qubits[0]) + '\n'
242
- s += 'p ' + str(qubits[0]) + '\n'
243
- s += 'h ' + str(qubits[0]) + '\n'
244
- return s
245
-
246
- elif name == 'Gc21':
247
- s = 'p ' + str(qubits[0]) + '\n'
248
- s += 'p ' + str(qubits[0]) + '\n'
249
- s += 'h ' + str(qubits[0]) + '\n'
250
- return s
251
-
252
- elif name == 'Gc22':
253
- s = 'h ' + str(qubits[0]) + '\n'
254
- s += 'p ' + str(qubits[0]) + '\n'
255
- s += 'h ' + str(qubits[0]) + '\n'
256
- s += 'p ' + str(qubits[0]) + '\n'
257
- s += 'p ' + str(qubits[0]) + '\n'
258
- return s
259
-
260
- elif name == 'Gc23':
261
- s = 'p ' + str(qubits[0]) + '\n'
262
- s += 'p ' + str(qubits[0]) + '\n'
263
- s += 'p ' + str(qubits[0]) + '\n'
264
- return s
265
-
266
- elif name == 'Gcnot':
267
- return 'c ' + str(qubits[0]) + ' ' + str(qubits[1]) + '\n'
268
-
269
- elif name == 'Gcphase':
270
- s = 'h ' + str(qubits[1]) + '\n'
271
- s += 'c ' + str(qubits[0]) + ' ' + str(qubits[1]) + '\n'
272
- s = 'h ' + str(qubits[1]) + '\n'
273
- return s
274
-
275
- else:
276
- raise ValueError("{} is an unknown gate! You must make your own `gateinchp` function!".format(gate))
277
-
278
-
279
- class IndDepolErrorModel(object):
280
- """
281
- todo
282
-
283
- """
284
-
285
- def __init__(self, gate_errors, readout_errors):
286
- """
287
- todo
288
-
289
- """
290
- self.gate_errors = gate_errors
291
- self.readout_errors = readout_errors
292
-
293
- def layer_uniform_pauli_probability(self, layer, qubitorder):
294
- """
295
- todo.
296
-
297
- """
298
- if len(layer) > 0:
299
- return 1 - _np.prod([1 - _np.array([4 * self.gate_errors[gate].get(q, 0) / 3
300
- for q in qubitorder]) for gate in layer], axis=0)
301
- else:
302
- return _np.zeros(len(qubitorder), float)
303
-
304
- def readout_uniform_pauli_probability(self, qubitorder):
305
- """
306
- todo
307
-
308
- """
309
- return 1 - _np.prod([1 - _np.array([4 * self.readout_errors[q1].get(q2, 0) / 3
310
- for q2 in qubitorder]) for q1 in qubitorder], axis=0)
311
-
312
-
313
- def depolarizing_errors_circuit_simulator(circuitlist, shots, errormodel, gate_to_chp=None,
314
- aux_info_list=None, collision_action='keepseparate',
315
- outdir='', perge_chp_files=True, returnds=True,
316
- verbosity=1):
317
- """
318
- todo.
319
-
320
- """
321
- if returnds:
322
- ds = _DataSet(collision_action=collision_action)
323
- else:
324
- ds = []
325
- assert(_os.path.isfile("chp")), "This simulator uses the chp.c code.\n" + \
326
- "It must be compiled to an executable called `chp` and situated in this folder!"
327
-
328
- try:
329
- _os.mkdir(outdir)
330
- if perge_chp_files:
331
- perge_dir = True
332
- else:
333
- perge_dir = False
334
- except:
335
- perge_dir = False
336
- pass
337
-
338
- time0 = _time.time()
339
-
340
- if gate_to_chp is None: gate_to_chp = stdgate_to_chp
341
-
342
- percentdone = 0
343
- for cind, circuit in enumerate(circuitlist):
344
- print(cind)
345
- time1 = _time.time()
346
-
347
- if verbosity > 0:
348
- if verbosity > 1:
349
- print("{0:.2f}".format(cind / len(circuitlist)), end=' ')
350
- else:
351
- if int(_np.floor(cind / len(circuitlist))) > percentdone:
352
- percentdone += 1
353
- print(" - Simulation {} percent complete.".format(percentdone))
354
-
355
- n = circuit.num_lines
356
- depth = circuit.depth
357
-
358
- # Set up the CHP qubit labels: could be different CHP labels for each circuit.
359
- aschpq = {label: str(i) for i, label in enumerate(circuit.line_labels)}
360
-
361
- # A list containing the CHP string for each error-free circuit layer.
362
- perfect_chpstrings = [''.join([gate_to_chp(gate, aschpq) for gate in circuit.layer(i)])
363
- for i in range(depth)]
364
-
365
- # Find the probability of error in each circuit layer.
366
- errorprobs = [errormodel.layer_uniform_pauli_probability(circuit.layer(lind), circuit.line_labels)
367
- for lind in range(circuit.depth)]
368
- # Add measurement error at the end
369
- errorprobs.append(errormodel.readout_uniform_pauli_probability(circuit.line_labels))
370
-
371
- time2 = _time.time()
372
-
373
- for sample in range(shots):
374
-
375
- # Sample errors for the circuit. Note that if 1 then a uniformly random Pauli is sampled, so
376
- # there is a 1/4 chance of no error even if this is 1. This is correct.
377
- #print(errorprobs)
378
- haserror = [_np.random.binomial(1, ep) for ep in errorprobs]
379
- #for lind in range(depth):
380
- # print('-', lind)
381
- # print(haserror[lind])
382
- # print([random_pauli_in_chp(q) for q in range(n) if haserror[lind][q] == 1])
383
- # Construct the CHP string for each error layer.
384
- error_chpstrings = [''.join([''] + [random_pauli_in_chp(q) for q in range(n) if haserror[lind][q] == 1])
385
- for lind in range(depth)]
386
-
387
- # Interleave the perfect and error CHP strings and then join.
388
- chpstring = '#\n' + ''.join([val for pair in zip(perfect_chpstrings, error_chpstrings) for val in pair])
389
-
390
- # Add the readout error
391
- chpstring += ''.join([''] + [random_pauli_in_chp(q) for q in range(n) if haserror[depth][q] == 1])
392
-
393
- # Add a measurement on all the qubits.
394
- chpstring += '\n'.join(['m ' + aschpq[q] for q in circuit.line_labels]) + '\n'
395
- #print(chpstring)
396
- with open(outdir + "/circuit-{}-instance-{}.chp".format(cind, sample), 'w') as f:
397
- f.write(chpstring)
398
-
399
- # Run CHP on this file.
400
- _os.system("./chp " + outdir + "/circuit-{}-instance-{}.chp > ".format(cind, sample)
401
- + outdir + "/circuit-{}-instance-{}-out.txt".format(cind, sample))
402
-
403
- countdict = {}
404
- for sample in range(shots):
405
-
406
- with open(outdir + "/circuit-{}-instance-{}-out.txt".format(cind, sample), 'r') as f:
407
- #print(cind,sample)
408
- outasdict = {}
409
- for i, line in enumerate(f):
410
- if i > 3:
411
- line = line.strip(' \n')
412
- line = line.split(' ')
413
- # todo : this assumes definite outcome circuits, so fix that
414
- # by instead counting forward from the start of the line.
415
- outasdict[circuit.line_labels[int(line[-2][:-1])]] = line[-1]
416
-
417
- #print(outasdict)
418
- bitstring = ''.join([outasdict[q] for q in circuit.line_labels])
419
-
420
- if perge_chp_files:
421
- _os.system("rm " + outdir + "/circuit-{}-instance-{}.chp".format(cind, sample))
422
- _os.system("rm " + outdir + "/circuit-{}-instance-{}-out.txt".format(cind, sample))
423
-
424
- try:
425
- countdict[bitstring] += 1
426
- except:
427
- countdict[bitstring] = 1
428
-
429
- if aux_info_list is not None:
430
- aux = aux_info_list[cind]
431
- else:
432
- aux = None
433
-
434
- if returnds:
435
- ds.add_count_dict(circuit, countdict, record_zero_counts=False, aux=aux)
436
- else:
437
- ds.append(countdict)
438
-
439
- time3 = _time.time()
440
-
441
- if verbosity > 1:
442
- print("({0:.2f}, {1:.2f})".format(time2 - time1, time3 - time2), end=', ')
443
- print("Total time: {0:.2f})".format(time3 - time0))
444
-
445
- if perge_dir:
446
- _os.system("rmdir " + outdir)
447
-
448
- return ds
449
-
450
-
451
- def circuit_simulator_for_tensored_independent_pauli_errors(circuit, pspec, errormodel, counts,
452
- alloutcomes=False, idle1q_placeholder='I'):
453
- """
454
- A Clifford circuit simulator for an error model whereby each gate in the circuit induces independent Pauli
455
- errors on some or all of the qubits, with user-specified error probabilities that can vary between gate
456
- and between Pauli. State preparation and measurements errors are restricted to bit-flip errors on the output.
457
-
458
- This simulator is a stochastic-unravelling simulator that uses an efficient-in-qubit-number representation
459
- of the action of Clifford gates on Paulis. Specifically, it samples Pauli errors according to the error
460
- statistics provided, and propogates them through the layers of Clifford gates in the circuit using the
461
- conjugation action of the Cliffords on Paulis (as represented by 2n X 2n symplectic matrices for n qubits).
462
- This is repeated for the number of counts (`counts`) requested. So, this function takes a time to run that
463
- scales as (counts * n^2 * circuit depth). Therefore, this method will be slower than the pyGSTi density-matrix
464
- simulators at low qubit number and high `counts`.
465
-
466
- Parameters
467
- ----------
468
- circuit : Circuit
469
- The circuit to simulate. It should only contain gates that are also contained within the provided
470
- QubitProcessorSpec `pspec` and are Clifford gates.
471
-
472
- pspec : QubitProcessorSpec
473
- The QubitProcessorSpec that defines the device. The Clifford model in QubitProcessorSpec should contain all of
474
- the gates that are in the circuit.
475
-
476
- errormodel : dict
477
- A dictionary defining the error model. This errormodel should have keys that are Label objects (the
478
- elements of the circuit). The values for a particular Label is an (n,4) numpy array of floats, that
479
- encodes the errors caused by the gate specified by that Label. The (i,j) value in the array is the
480
- probability that this gate is followed by Pauli i where Pauli 0 = identity, Pauli 1 = X, Pauli 2 = Y
481
- and Pauli 3 = Z. So, if the arrray is [1.,0.,0.,0.] in every row then there is no errors, if it is
482
- [1-p,p/3,p/3,p/3] in row j then there is equal probability of each Pauli error on qubit j with an
483
- error probability of p.
484
-
485
- Some simple error models can be auto-constructed using `create_locally_gate_independent_pauli_error_model()`
486
- or create_iid_pauli_error_model()`.
487
-
488
- counts : The number of counts, i.e., the number of repeats of the circuit that data should be generated for.
489
-
490
- alloutcomes : bool, optional
491
- If True then a dictionary is returned where the keys are all possible outcomes (i.e., all length n
492
- bit strings) and the values are the counts for all of the outcomes. If False, then the returned
493
- dictionary only contains keys for those outcomes that happen at least once.
494
-
495
- TODO: docstring: idle1q_placeholder
496
-
497
- Returns
498
- -------
499
- dict
500
- A dictionary of simulated measurement outcome counts.
501
- """
502
- n = circuit.number_of_lines
503
-
504
- if set(circuit.line_labels) != set(pspec.qubit_labels):
505
- assert(set(circuit.line_labels).issubset(set(pspec.qubit_labels)))
506
- reduced_errormodel = errormodel.copy()
507
- mask = _np.zeros(pspec.num_qubits, bool)
508
- for i in range(pspec.num_qubits):
509
- if pspec.qubit_labels[i] in circuit.line_labels:
510
- mask[i] = True
511
- for key in list(reduced_errormodel.keys()):
512
- errormatrix = reduced_errormodel[key]
513
- assert(_np.shape(errormatrix)[0] == pspec.num_qubits), "Format of `errormodel` incorrect!"
514
- if len(_np.shape(errormatrix)) == 2:
515
- reduced_errormodel[key] = errormatrix[mask, :]
516
- elif len(_np.shape(errormatrix)) == 1:
517
- reduced_errormodel[key] = errormatrix[mask]
518
- else: raise ValueError("Format of `errormodel` incorrect!")
519
- else:
520
- reduced_errormodel = errormodel
521
-
522
- results = {}
523
-
524
- if alloutcomes:
525
- for i in range(2**n):
526
- result = tuple(_symp.int_to_bitstring(i, n))
527
- results[result] = 0
528
-
529
- for i in range(0, counts):
530
- result = oneshot_circuit_simulator_for_tensored_independent_pauli_errors(
531
- circuit, pspec, reduced_errormodel, idle1q_placeholder)
532
- try: results[result] += 1
533
- except: results[result] = 1
534
-
535
- return results
536
-
537
-
538
- def oneshot_circuit_simulator_for_tensored_independent_pauli_errors(circuit, pspec, errormodel, idle1q_placeholder='I'):
539
- """
540
- Generates a single measurement result for the `circuit_simulator_for_tensored_independent_pauli_errors()`
541
- simulator
542
-
543
- Parameters
544
- ----------
545
- circuit : Circuit
546
- The circuit to simulate. It should only contain gates that are also contained within the provided
547
- QubitProcessorSpec `pspec` and are Clifford gates.
548
-
549
- pspec : QubitProcessorSpec
550
- The QubitProcessorSpec that defines the device. The Clifford model in QubitProcessorSpec should contain all of
551
- the gates that are in the circuit.
552
-
553
- errormodel : dict
554
- A dictionary defining the error model. This errormodel should have keys that are Label objects (the
555
- elements of the circuit). The values for a particular Label is an (n,4) numpy array of floats, that
556
- encodes the errors caused by the gate specified by that Label. The (i,j) value in the array is the
557
- probability that this gate is followed by Pauli i where Pauli 0 = identity, Pauli 1 = X, Pauli 2 = Y
558
- and Pauli 3 = Z. So, if the arrray is [1.,0.,0.,0.] in every row then there is no errors, if it is
559
- [1-p,p/3,p/3,p/3] in row j then there is equal probability of each Pauli error on qubit j with an
560
- error probability of p.
561
-
562
- TODO: docstring: idle1q_placeholder
563
-
564
- Returns
565
- -------
566
- tuple
567
- A tuple of values that are 0 or 1, corresponding to the results of a z-measurement on all the qubits.
568
- The ordering of this tuple corresponds to the ordering of the wires in the circuit.
569
- """
570
- n = circuit.number_of_lines
571
- depth = circuit.depth
572
- sout, pout = _symp.prep_stabilizer_state(n, zvals=None)
573
- srep = pspec.models['clifford'].compute_clifford_symplectic_reps()
574
- I = _np.identity(2 * n, int)
575
-
576
- for l in range(depth):
577
-
578
- layer = circuit.layer_with_idles(l, idle_gate_name=idle1q_placeholder)
579
- s, p = _symp.symplectic_rep_of_clifford_layer(layer, n, q_labels=circuit.line_labels, srep_dict=srep)
580
- # Apply the perfect layer to the current state.
581
- sout, pout = _symp.apply_clifford_to_stabilizer_state(s, p, sout, pout)
582
-
583
- # Consider each gate in the layer, and apply Pauli errors with the relevant probs.
584
- for gate in layer:
585
- # Sample a pauli vector for the gate
586
- gerror_p = _np.zeros(2 * n, int)
587
- sampledvec = _np.array([list(_np.random.multinomial(1, pp)) for pp in errormodel[gate]])
588
- # Z and Y both map X - > -X under conjugation, which is encoded with the upper half of
589
- # the p vector being set to 2.
590
- gerror_p[:n] = 2 * (sampledvec[:, 3] ^ sampledvec[:, 2])
591
- # X and Y both map Z - > -Z under conjugation, which is encoded with the lower half of
592
- # the p vector being set to 2.
593
- gerror_p[n:] = 2 * (sampledvec[:, 1] ^ sampledvec[:, 2])
594
-
595
- sout, pout = _symp.apply_clifford_to_stabilizer_state(I, gerror_p, sout, pout)
596
-
597
- output = []
598
- for q in range(n):
599
- measurement_out = _symp.pauli_z_measurement(sout, pout, q)
600
- # The probability of the '1' outcome
601
- oneprob = measurement_out[1]
602
- # Sample a bit with that probability to be 1.
603
- bit = _np.random.binomial(1, oneprob)
604
- output.append(bit)
605
-
606
- # Add measurement errors, by bit-flipping with some probability
607
- try:
608
- measurement_errors = errormodel['measure']
609
- except:
610
- measurement_errors = [0 for i in range(n)]
611
-
612
- add_to_outcome = _np.array([_np.random.binomial(1, p) for p in measurement_errors])
613
- output = tuple(_np.array(output) ^ add_to_outcome)
614
- outputasstring = ''
615
- for s in output: outputasstring += str(s)
616
- return outputasstring
617
-
618
-
619
- def rb_with_pauli_errors(pspec, errormodel, lengths, k, counts, qubit_subset=None, filename=None, rbtype='DRB',
620
- rbspec=None, returndata=True, appenddata=False, verbosity=0, idle1q_placeholder='I'):
621
- """
622
- Simulates RB with Pauli errors. Can be used to simulated Clifford RB, direct RB and mirror RB. This
623
- function:
624
-
625
- 1) Samples RB circuits
626
- 2) Simulates the RB circuit with the specified Pauli-errors error model
627
- 3) Records the summary RB data to file and/or returns this RB data.
628
-
629
- Step 1 is implemented using the in-built RB samplers. For more information see rb.sample. Step 2
630
- is implemented using the `circuit_simulator_for_tensored_independent_pauli_errors()` stochastic
631
- errors circuit simulator. See that function for more details.
632
-
633
- Parameters
634
- ----------
635
- pspec : QubitProcessorSpec
636
- The QubitProcessorSpec that defines the device.
637
-
638
- errormodel : dict
639
- A dictionary defining the error model. This errormodel should have keys that are Label objects
640
- corresponding to the gates in `pspec`. The values for a particular Label is an (n,4) numpy array of
641
- floats, that encodes the errors caused by the gate specified by that Label. The (i,j) value in the
642
- array is the probability that this gate is followed by Pauli i where Pauli 0 = identity, Pauli 1 = X,
643
- Pauli 2 = Y and Pauli 3 = Z. So, if the arrray is [1.,0.,0.,0.] in every row then there is no errors,
644
- if it is [1-p,p/3,p/3,p/3] in row j then there is equal probability of each Pauli error on qubit j with an
645
- error probability of p.
646
-
647
- Some simple error models can be auto-constructed using `create_locally_gate_independent_pauli_error_model()`
648
- or create_iid_pauli_error_model()`.
649
-
650
- lengths : list
651
- A list of the RB lengths to sample and simulate circuits at. E.g., for Clifford RB this is the number
652
- of Cliffords in the uncompiled circuit - 2 (see `rb.sample.clifford_rb_circuit()`).
653
-
654
- k : int
655
- The number of circuits to sample and simulate at each RB length.
656
-
657
- counts : int
658
- The number of counts for each circuit.
659
-
660
- qubit_subset : list
661
- If not None, a list of qubit labels that the RB experiment should be over, that is a subset of the
662
- qubits in `pspec`.
663
-
664
- filename : str, optional
665
- A filename for where to save the data (if None, the data is not saved to file).
666
-
667
- rbtype : {'DRB', 'CRB', 'MRB'}
668
- The RB type to simulate. 'DRB' corresponds to direct RB, 'CRB' corresponds to Clifford RB,
669
- and 'MRB' corresponds to mirror RB.
670
-
671
- rbspec : list, optional
672
- Handed to the RB sampling function for all arguments after `pspec` and the RB lengths, which are the first
673
- two arguments handed to the relevant function. See the relevant RB circuit sampling functions for details.
674
-
675
- returndata : bool, optional
676
- Whether to return the data
677
-
678
- appenddata : bool, optional
679
- If writing to file (i.e., `filename` is not None), whether to append the data to an already existing file
680
- or to write over any existing file.
681
-
682
- verbosity : int, optional
683
- The amount of print-to-screen.
684
-
685
- Returns
686
- -------
687
- None or RBSummaryDataset
688
- If `returndata` an RBSummaryDataset containing the results. Else, None
689
-
690
- """
691
- if rbspec is None:
692
- rbspec = []
693
- assert(rbtype == 'CRB' or rbtype == 'DRB' or rbtype == 'MRB'), "RB type not valid!"
694
-
695
- if filename is not None:
696
- if not appenddata:
697
- with open(filename, 'w') as f:
698
- f.write('# Results from a {} simulation\n'.format(rbtype))
699
- f.write('# Number of qubits\n')
700
- if qubit_subset is None: f.write(str(pspec.num_qubits))
701
- else: f.write(str(len(qubit_subset)))
702
- f.write('\n# RB length // Success counts // Total counts '
703
- '// Circuit depth // Circuit two-qubit gate count\n')
704
-
705
- n = pspec.num_qubits
706
- lengthslist = []
707
- scounts = []
708
- cdepths = []
709
- c2Qgcounts = []
710
-
711
- for i in range(k):
712
-
713
- if verbosity > 0:
714
- print("- Sampling and simulating circuit {} of {} at each of {} lengths".format(i + 1, k, len(lengths)))
715
- print(" - Number of circuits complete = ", end='')
716
-
717
- for lind, l in enumerate(lengths):
718
-
719
- lengthslist.append(l)
720
-
721
- if rbtype == 'DRB':
722
- c, idealout = _samp.direct_rb_circuit(pspec, l, qubit_subset, *rbspec)
723
- elif rbtype == 'CRB':
724
- c, idealout = _samp.clifford_rb_circuit(pspec, l, qubit_subset, *rbspec)
725
- elif rbtype == 'MRB':
726
- c, idealout = _samp.mirror_rb_circuit(pspec, l, qubit_subset, *rbspec)
727
-
728
- #if verbosity > 0:
729
- # print(" complete")
730
- # print(" - Simulating circuit...",end='')
731
-
732
- outcome = circuit_simulator_for_tensored_independent_pauli_errors(
733
- c, pspec, errormodel, counts, alloutcomes=False, idle1q_placeholder=idle1q_placeholder)
734
- #EGN: Hardcoded 'I' here. Could make this into an arg, but there's really
735
- # no need for the user to modify this unless they use 'I' as a gate label.
736
- if verbosity > 0: print(lind + 1, end=',')
737
-
738
- # Add the number of success counts to the list
739
- # scounts.append(outcome.get(idealout,0))
740
- scounts.append(outcome.get(''.join(str(idealbit) for idealbit in idealout), 0))
741
- cdepths.append(c.depth)
742
- c2Qgcounts.append(c.two_q_gate_count())
743
-
744
- # Write the data to file in each round.
745
- if filename is not None:
746
- with open(filename, 'a') as f:
747
- f.write('{} {} {} {} {}\n'.format(l, scounts[-1], counts, cdepths[-1], c2Qgcounts[-1]))
748
-
749
- if verbosity > 0: print('')
750
- if returndata:
751
-
752
- from . import results as _res
753
- data = _res.RBSummaryDataset(n, lengthslist, success_counts=scounts, total_counts=counts,
754
- circuit_depths=cdepths, circuit_twoQgate_counts=c2Qgcounts)
755
- return data
756
-
757
-
758
- def create_iid_pauli_error_model(pspec, one_qubit_gate_errorrate, two_qubit_gate_errorrate, idle_errorrate,
759
- measurement_errorrate=0., ptype='uniform', idle1q_placeholder='I'):
760
- """
761
- Returns a dictionary encoding a Pauli-stochastic error model whereby the errors are the same on all the
762
- 1-qubit gates, and the same on all 2-qubit gates. The probability of the 3 different Pauli errors on each
763
- qubit is specified by `ptype` and can either be uniform, or always X, Y, or Z errors.
764
-
765
- The dictionary returned is in the appropriate format for the
766
- `circuit_simulator_for_tensored_independent_pauli_errors()` circuit simulator function.
767
-
768
- Parameters
769
- ----------
770
- pspec : QubitProcessorSpec
771
- The QubitProcessorSpec that defines the device.
772
-
773
- one_qubit_gate_errorrate : float
774
- The 1-qubit gates error rate (the probability of a Pauli error on the target qubit) not including
775
- idle gates.
776
-
777
- two_qubit_gate_errorrate : float
778
- The 2-qubit gates error rate (the total probability of a Pauli error on either qubit the gate acts
779
- on -- each qubit has independent errors with equal probabilities).
780
-
781
- idle_errorrate : float
782
- The idle gates error rate.
783
-
784
- measurement_errorrate : flip
785
- The measurement error rate for all of the qubits. This is the probability that a qubits measurement
786
- result is bit-flipped.
787
-
788
- ptype : str, optional
789
- Can be 'uniform', 'X', 'Y' or 'Z'. If 'uniform' then 3 Pauli errors are equally likely, if 'X', 'Y' or
790
- 'Z' then the errors are always Pauli X, Y or Z errors, respectively.
791
-
792
- TODO: docstring idle1q_placeholder
793
-
794
- Returns
795
- -------
796
- dict
797
- An dict that encodes the error model described above in the format required for the simulator
798
- `circuit_simulator_for_tensored_independent_pauli_errors()`.
799
-
800
- """
801
- if ptype == 'uniform':
802
- def error_row(er): return _np.array([1 - er, er / 3, er / 3, er / 3])
803
-
804
- elif ptype == 'X':
805
- def error_row(er): return _np.array([1 - er, er, 0., 0.])
806
-
807
- elif ptype == 'Y':
808
- def error_row(er): return _np.array([1 - er, 0., er, 0.])
809
-
810
- elif ptype == 'Z':
811
- def error_row(er): return _np.array([1 - er, 0., 0., er])
812
- else:
813
- raise ValueError("Error model type not understood! Set `ptype` to a valid option.")
814
-
815
- perQ_twoQ_errorrate = 1 - (1 - two_qubit_gate_errorrate)**(1 / 2)
816
- n = pspec.num_qubits
817
-
818
- errormodel = {}
819
-
820
- if idle1q_placeholder is not None:
821
- #Added by EGN: special behavior needed when Model has
822
- # an gate name used to designate a perfect 1-qubit idle op (used as placeholder).
823
- # This translates to a set of "<gatename>:X" operation labels all w/idle_errorrate
824
- idleLbl = idle1q_placeholder
825
- for q in pspec.qubit_labels:
826
- gl = _Lbl(idleLbl, q)
827
- errormodel[gl] = _np.zeros((n, 4), float)
828
- errormodel[gl][:, 0] = _np.ones(n, float)
829
- errormodel[gl][pspec.qubit_labels.index(q), :] = error_row(idle_errorrate)
830
-
831
- for gate in pspec.models['clifford'].primitive_op_labels:
832
- errormodel[gate] = _np.zeros((n, 4), float)
833
- errormodel[gate][:, 0] = _np.ones(n, float)
834
-
835
- # If not a CNOT, it is a 1-qubit gate / idle.
836
- if gate.num_qubits == 2:
837
- q1 = gate.qubits[0]
838
- q2 = gate.qubits[1]
839
- er = perQ_twoQ_errorrate
840
- errormodel[gate][pspec.qubit_labels.index(q1), :] = error_row(er)
841
- errormodel[gate][pspec.qubit_labels.index(q2), :] = error_row(er)
842
-
843
- elif gate.num_qubits == 1:
844
- q = gate.qubits[0]
845
- er = one_qubit_gate_errorrate
846
-
847
- errormodel[gate][pspec.qubit_labels.index(q), :] = error_row(er)
848
-
849
- else:
850
- raise ValueError("The QubitProcessorSpec must only contain 1- and 2- qubit gates!")
851
-
852
- errormodel['measure'] = _np.array([measurement_errorrate for q in range(n)])
853
-
854
- return errormodel
855
-
856
-
857
- def create_locally_gate_independent_pauli_error_model(pspec, gate_errorrate_dict, measurement_errorrate_dict=None,
858
- ptype='uniform', idle1q_placeholder='I'):
859
- """
860
- Returns a dictionary encoding a Pauli-stochastic error model whereby the errors are independent of the gates,
861
- with a qubit subject to an error after a circuit layer with the probabilities specified by the dict
862
- `gate_errorrate_dict`. The probability of the 3 different Pauli errors on each qubit is specified by
863
- `ptype` and can either be uniform, or always X, Y, or Z errors.
864
-
865
- The dictionary returned is in the appropriate format for the
866
- `circuit_simulator_for_tensored_independent_pauli_errors()` circuit simulator function.
867
-
868
- Parameters
869
- ----------
870
- pspec : QubitProcessorSpec
871
- The QubitProcessorSpec that defines the device.
872
-
873
- gate_errorrate_dict : dict
874
- A dict where the keys are elements of pspec.qubit_labels and the values are floats in [0,1].
875
- The element for qubit with label `q` is the error probability for that qubit.
876
-
877
- measurement_errorrate_dict : dict
878
- A dict where the keys are elements of pspec.qubit_labels and the values are floats in [0,1].
879
- The element for qubit with label `q` is the measurement bit-flip error probability for that qubit.
880
- All qubits that do not have a measurement error rate specified are assumed to have perfect measurements.
881
-
882
- ptype : str, optional
883
- Can be 'uniform', 'X', 'Y' or 'Z'. If 'uniform' then 3 Pauli errors are equally likely, if 'X', 'Y' or
884
- 'Z' then the errors are always Pauli X, Y or Z errors, respectively.
885
-
886
- TODO: docstring: idle1q_placeholder
887
-
888
- Returns
889
- -------
890
- dict
891
- An dict that encodes the error model described above in the format required for the simulator
892
- `circuit_simulator_for_tensored_independent_pauli_errors()`.
893
-
894
- """
895
- if measurement_errorrate_dict is None:
896
- measurement_errorrate_dict = {}
897
- if ptype == 'uniform':
898
- def error_row(er): return _np.array([1 - er, er / 3, er / 3, er / 3])
899
-
900
- elif ptype == 'X':
901
- def error_row(er): return _np.array([1 - er, er, 0., 0.])
902
-
903
- elif ptype == 'Y':
904
- def error_row(er): return _np.array([1 - er, 0., er, 0.])
905
-
906
- elif ptype == 'Z':
907
- def error_row(er): return _np.array([1 - er, 0., 0., er])
908
- else:
909
- raise ValueError("Error model type not understood! Set `ptype` to a valid option.")
910
-
911
- n = pspec.num_qubits
912
-
913
- errormodel = {}
914
-
915
- if idle1q_placeholder is not None:
916
- #Added by EGN: special behavior needed when Model has
917
- # an gate name used to designate a perfect 1-qubit idle op (used as placeholder).
918
- # This translates to a set of "<gatename>:X" operation labels all w/appropriate errorrate
919
- idleLbl = idle1q_placeholder
920
- for q in pspec.qubit_labels:
921
- gl = _Lbl(idleLbl, q)
922
- er = gate_errorrate_dict[q]
923
- errormodel[gl] = _np.zeros((n, 4), float)
924
- errormodel[gl][:, 0] = _np.ones(n, float)
925
- errormodel[gl][pspec.qubit_labels.index(q), :] = error_row(er)
926
-
927
- for gate in pspec.models['clifford'].primitive_op_labels:
928
- errormodel[gate] = _np.zeros((n, 4), float)
929
- errormodel[gate][:, 0] = _np.ones(n, float)
930
-
931
- for q in gate.qubits:
932
- er = gate_errorrate_dict[q]
933
- errormodel[gate][pspec.qubit_labels.index(q)] = error_row(er)
934
-
935
- errormodel['measure'] = _np.array([measurement_errorrate_dict.get(q, 0.) for q in pspec.qubit_labels])
936
-
937
- return errormodel
938
-
939
- #
940
- # TODO : DOES THIS NEED AND IDLE PLACEHOLDER?
941
- #
942
-
943
-
944
- def create_local_pauli_error_model(pspec, one_qubit_gate_errorrate_dict, two_qubit_gate_errorrate_dict,
945
- measurement_errorrate_dict=None, ptype='uniform'):
946
- """
947
- Returns a dictionary encoding a Pauli-stochastic error model whereby the errors caused by a gate act
948
- only on the "target" qubits of the gate, all the 1-qubit gates on a qubit have the same error rate,
949
- and all the 2-qubit gates on a qubit have the same error rate. The probability of the 3 different Pauli
950
- errors on each qubit is specified by `ptype` and can either be uniform, or always X, Y, or Z errors.
951
-
952
- The dictionary returned is in the appropriate format for the
953
- `circuit_simulator_for_tensored_independent_pauli_errors()` circuit simulator function.
954
-
955
- Parameters
956
- ----------
957
- pspec : QubitProcessorSpec
958
- The QubitProcessorSpec that defines the device.
959
-
960
- one_qubit_gate_errorrate_dict : dict
961
- A dict where the keys are elements of pspec.qubit_labels and the values are floats in [0,1].
962
- The element for qubit with label `q` is the error probability for all 1-qubit gates on that qubit
963
-
964
- two_qubit_gate_errorrate_dict : dict
965
- A dict where the keys are 2-qubit gates in pspec and the values are floats in [0,1]. This is the
966
- error probability for the 2-qubit gate, split evenly into independent Pauli errors on each of the
967
- qubits the gate is intended to act on.
968
-
969
- measurement_errorrate_dict : dict
970
- A dict where the keys are elements of pspec.qubit_labels and the values are floats in [0,1].
971
- The element for qubit with label `q` is the measurement bit-flip error probability for that qubit.
972
- All qubits that do not have a measurement error rate specified are assumed to have perfect measurements.
973
-
974
-
975
- ptype : str, optional
976
- Can be 'uniform', 'X', 'Y' or 'Z'. If 'uniform' then 3 Pauli errors are equally likely, if 'X', 'Y' or
977
- 'Z' then the errors are always Pauli X, Y or Z errors, respectively.
978
-
979
- Returns
980
- -------
981
- dict
982
- An dict that encodes the error model described above in the format required for the simulator
983
- `circuit_simulator_for_tensored_independent_pauli_errors()`.
984
-
985
- """
986
- if measurement_errorrate_dict is None:
987
- measurement_errorrate_dict = {}
988
- if ptype == 'uniform':
989
- def error_row(er): return _np.array([1 - er, er / 3, er / 3, er / 3])
990
-
991
- elif ptype == 'X':
992
- def error_row(er): return _np.array([1 - er, er, 0., 0.])
993
-
994
- elif ptype == 'Y':
995
- def error_row(er): return _np.array([1 - er, 0., er, 0.])
996
-
997
- elif ptype == 'Z':
998
- def error_row(er): return _np.array([1 - er, 0., 0., er])
999
- else:
1000
- raise ValueError("Error model type not understood! Set `ptype` to a valid option.")
1001
-
1002
- n = pspec.num_qubits
1003
-
1004
- errormodel = {}
1005
- for gate in list(pspec.models['clifford'].primitive_op_labels):
1006
- errormodel[gate] = _np.zeros((n, 4), float)
1007
- errormodel[gate][:, 0] = _np.ones(n, float)
1008
-
1009
- if gate.num_qubits == 1:
1010
- er = one_qubit_gate_errorrate_dict[gate.qubits[0]]
1011
- elif gate.num_qubits == 2:
1012
- er = 1 - (1 - two_qubit_gate_errorrate_dict[gate])**(0.5)
1013
- else: raise ValueError("Only 1- and 2-qubit gates supported!")
1014
-
1015
- for q in gate.qubits:
1016
- errormodel[gate][pspec.qubit_labels.index(q)] = error_row(er)
1017
-
1018
- errormodel['measure'] = _np.array([measurement_errorrate_dict.get(q, 0.) for q in pspec.qubit_labels])
1019
-
1020
- return errormodel