Skip to content

Commit 70a3ce5

Browse files
authored
Merge pull request #421 from sandialabs/bugfix-0.9.12.2
Bugfix 0.9.12.2
2 parents 89b2d21 + 9b9e5c2 commit 70a3ce5

File tree

10 files changed

+438
-56
lines changed

10 files changed

+438
-56
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ jupyter_notebooks/Tutorials/tutorial_files/modeltest_report
4646
jupyter_notebooks/Tutorials/tutorial_files/gettingStartedReport
4747
jupyter_notebooks/Examples/example_files/*.pkl
4848
jupyter_notebooks/Examples/example_files/*.json
49+
jupyter_notebooks/Examples/example_files/leakage_*
4950
jupyter_notebooks/Tutorials/tutorial_files/exampleReport
5051
jupyter_notebooks/Tutorials/tutorial_files/exampleStdReport
5152
jupyter_notebooks/Tutorials/tutorial_files/exampleMultiEstimateReport

jupyter_notebooks/Examples/Leakage.ipynb

Lines changed: 86 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
"outputs": [],
1616
"source": [
1717
"import pygsti\n",
18-
"import pygsti.modelpacks.legacy.std1Q_XYI as std1Q\n",
18+
"import pygsti.modelpacks.smq1Q_XYI as smq1Q\n",
19+
"from pygsti.baseobjs import Label\n",
20+
"from pygsti.circuits import Circuit\n",
1921
"import numpy as np\n",
2022
"import scipy.linalg as sla\n",
2123
"#import pickle"
@@ -49,8 +51,7 @@
4951
"metadata": {},
5052
"outputs": [],
5153
"source": [
52-
"mdl_2level_ideal = std1Q.target_model()\n",
53-
"mdl_2level_ideal.sim = \"matrix\" # so we can create reports later on"
54+
"mdl_2level_ideal = smq1Q.target_model(qubit_labels=[\"Qubit\"])"
5455
]
5556
},
5657
{
@@ -67,17 +68,16 @@
6768
" [0,1,0],\n",
6869
" [0,0,1]], complex)\n",
6970
"\n",
70-
"sslbls = pygsti.baseobjs.ExplicitStateSpace(['Qubit+Leakage'],[3])\n",
71-
"mdl_3level_ideal = pygsti.models.ExplicitOpModel(sslbls, 'gm')\n",
71+
"sslbls = pygsti.baseobjs.ExplicitStateSpace(['Qubit_leakage'],[3])\n",
72+
"mdl_3level_ideal = pygsti.models.ExplicitOpModel(sslbls, 'gm', simulator='matrix')\n",
7273
"mdl_3level_ideal['rho0'] = pygsti.tools.stdmx_to_gmvec(rho0)\n",
7374
"mdl_3level_ideal['Mdefault'] = pygsti.modelmembers.povms.TPPOVM([('0',pygsti.tools.stdmx_to_gmvec(E0)),\n",
7475
" ('1',pygsti.tools.stdmx_to_gmvec(E1))],\n",
7576
" evotype='default')\n",
7677
"\n",
77-
"mdl_3level_ideal['Gi'] = unitary_to_gmgate( to_3level_unitary(Us['Gi']))\n",
78-
"mdl_3level_ideal['Gx'] = unitary_to_gmgate( to_3level_unitary(Us['Gxpi2']))\n",
79-
"mdl_3level_ideal['Gy'] = unitary_to_gmgate( to_3level_unitary(Us['Gypi2']))\n",
80-
"mdl_3level_ideal.sim = \"matrix\" # so we can create reports later on"
78+
"mdl_3level_ideal[tuple()] = unitary_to_gmgate( to_3level_unitary(Us['Gi']))\n",
79+
"mdl_3level_ideal['Gxpi2', 'Qubit_leakage'] = unitary_to_gmgate( to_3level_unitary(Us['Gxpi2']))\n",
80+
"mdl_3level_ideal['Gypi2', 'Qubit_leakage'] = unitary_to_gmgate( to_3level_unitary(Us['Gypi2']))"
8181
]
8282
},
8383
{
@@ -95,15 +95,15 @@
9595
"\n",
9696
"#Guess of a model w/just unitary leakage\n",
9797
"mdl_3level_guess = mdl_3level_ideal.copy()\n",
98-
"mdl_3level_guess['Gi'] = np.dot(leakageOp, mdl_3level_guess['Gi'])\n",
99-
"#mdl_3level_guess['Gx'] = np.dot(leakageOp, mdl_3level_guess['Gx'])\n",
100-
"#mdl_3level_guess['Gy'] = np.dot(leakageOp, mdl_3level_guess['Gy'])\n",
98+
"mdl_3level_guess[tuple()] = np.dot(leakageOp, mdl_3level_guess[tuple()])\n",
99+
"#mdl_3level_guess['Gxpi2', 'Qubit_leakage'] = np.dot(leakageOp, mdl_3level_guess['Gxpi2', 'Qubit_leakage'])\n",
100+
"#mdl_3level_guess['Gypi2', 'Qubit_leakage'] = np.dot(leakageOp, mdl_3level_guess['Gypi2', 'Qubit_leakage'])\n",
101101
"\n",
102102
"#Actual model used for data generation (some depolarization too)\n",
103103
"mdl_3level_noisy = mdl_3level_ideal.depolarize(op_noise=0.005, spam_noise=0.01)\n",
104-
"mdl_3level_noisy['Gi'] = np.dot(leakageOp, mdl_3level_noisy['Gi'])\n",
105-
"#mdl_3level_noisy['Gx'] = np.dot(leakageOp, mdl_3level_noisy['Gx'])\n",
106-
"#mdl_3level_noisy['Gy'] = np.dot(leakageOp, mdl_3level_noisy['Gy'])"
104+
"mdl_3level_noisy[tuple()] = np.dot(leakageOp, mdl_3level_noisy[tuple()])\n",
105+
"#mdl_3level_noisy['Gxpi2', 'Qubit_leakage'] = np.dot(leakageOp, mdl_3level_noisy['Gxpi2', 'Qubit_leakage'])\n",
106+
"#mdl_3level_noisy['Gypi2', 'Qubit_leakage'] = np.dot(leakageOp, mdl_3level_noisy['Gypi2', 'Qubit_leakage'])"
107107
]
108108
},
109109
{
@@ -126,7 +126,7 @@
126126
"\n",
127127
"if find_fiducials:\n",
128128
" prepfids, measfids = pygsti.algorithms.find_fiducials(\n",
129-
" mdl_3level_guess, omit_identity=False, max_fid_length=4, verbosity=4)\n",
129+
" mdl_3level_guess, omit_identity=False, candidate_fid_counts={4: \"all upto\"}, verbosity=4)\n",
130130
" pygsti.io.write_circuit_list(\"example_files/leakage_prepfids.txt\", prepfids)\n",
131131
" pygsti.io.write_circuit_list(\"example_files/leakage_measfids.txt\", measfids)"
132132
]
@@ -140,10 +140,7 @@
140140
"# If files missing, run previous cell at least once with find_fiducials = True\n",
141141
"prepfids = pygsti.io.read_circuit_list(\"example_files/leakage_prepfids.txt\")\n",
142142
"measfids = pygsti.io.read_circuit_list(\"example_files/leakage_measfids.txt\")\n",
143-
"# HACK: Fix broken force empty labels\n",
144-
"prepfids[-1] = pygsti.circuits.Circuit([])\n",
145-
"measfids[-1] = pygsti.circuits.Circuit([])\n",
146-
"germs = std1Q.germs\n",
143+
"germs = smq1Q.germs(qubit_labels=[\"Qubit_leakage\"])\n",
147144
"maxLengths = [1,]\n",
148145
"expList = pygsti.circuits.create_lsgst_circuits(mdl_3level_noisy, prepfids, measfids, germs, maxLengths)\n",
149146
"ds = pygsti.data.simulate_data(mdl_3level_noisy, expList, 1000, 'binomial', seed=1234)"
@@ -155,8 +152,37 @@
155152
"metadata": {},
156153
"outputs": [],
157154
"source": [
158-
"results_2level = pygsti.run_stdpractice_gst(ds, mdl_2level_ideal, prepfids, measfids,\n",
159-
" germs, maxLengths, modes=\"CPTPLND\", verbosity=3)"
155+
"\n",
156+
"# We have found out prep fids, meas fids, and germs, as well as simulated noisy data, for the 3 level model\n",
157+
"# If we want to run GST on another model, we need to get versions of the circuits will the correct state space labels\n",
158+
"\n",
159+
"def map_2level_sslbls(circuit):\n",
160+
" sslbl_map = {'Qubit_leakage': 'Qubit'}\n",
161+
" return circuit.map_state_space_labels(sslbl_map)\n",
162+
"\n",
163+
"prepfids_2level = [map_2level_sslbls(c) for c in prepfids]\n",
164+
"measfids_2level = [map_2level_sslbls(c) for c in measfids]\n",
165+
"germs_2level = [map_2level_sslbls(c) for c in germs]\n",
166+
"ds_2level = ds.process_circuits(map_2level_sslbls)\n",
167+
"\n",
168+
"results_2level = pygsti.run_stdpractice_gst(ds_2level, mdl_2level_ideal, prepfids_2level, measfids_2level,\n",
169+
" germs_2level, maxLengths, modes=\"CPTPLND\", verbosity=3)"
170+
]
171+
},
172+
{
173+
"cell_type": "code",
174+
"execution_count": null,
175+
"metadata": {},
176+
"outputs": [],
177+
"source": [
178+
"pygsti.report.construct_standard_report(results_2level, \"2-level Leakage Example Report\").write_html('example_files/leakage_report_2level')"
179+
]
180+
},
181+
{
182+
"cell_type": "markdown",
183+
"metadata": {},
184+
"source": [
185+
"Open the report [here](example_files/leakage_report_2level/main.html)"
160186
]
161187
},
162188
{
@@ -168,7 +194,7 @@
168194
"outputs": [],
169195
"source": [
170196
"results_3level = pygsti.run_stdpractice_gst(ds, mdl_3level_ideal, prepfids, measfids,\n",
171-
" germs, maxLengths, modes=[\"CPTP\",\"True\"],\n",
197+
" germs, maxLengths, modes=[\"CPTPLND\",\"True\"],\n",
172198
" models_to_test={'True': mdl_3level_noisy}, \n",
173199
" verbosity=4, advanced_options={'all': {'tolerance': 1e-2}})"
174200
]
@@ -179,10 +205,14 @@
179205
"metadata": {},
180206
"outputs": [],
181207
"source": [
182-
"pygsti.report.construct_standard_report(\n",
183-
" {'two-level': results_2level, 'three-level': results_3level},\n",
184-
" \"Leakage Example Report\"\n",
185-
").write_html('example_files/leakage_report')"
208+
"pygsti.report.construct_standard_report(results_3level, \"3-level Leakage Example Report\").write_html('example_files/leakage_report')"
209+
]
210+
},
211+
{
212+
"cell_type": "markdown",
213+
"metadata": {},
214+
"source": [
215+
"Open the report [here](example_files/leakage_report/main.html)"
186216
]
187217
},
188218
{
@@ -254,17 +284,15 @@
254284
"metadata": {},
255285
"outputs": [],
256286
"source": [
257-
"pygsti.report.construct_standard_report(\n",
258-
" {'two-level': results_2level, 'three-level': results_3level_leakage_basis},\n",
259-
" \"Leakage Example Report\"\n",
260-
").write_html('example_files/leakage_report')"
287+
"pygsti.report.construct_standard_report(results_3level_leakage_basis, \"3-level with Basis Change Leakage Example Report\"\n",
288+
" ).write_html('example_files/leakage_report_basis')"
261289
]
262290
},
263291
{
264292
"cell_type": "markdown",
265293
"metadata": {},
266294
"source": [
267-
"Open the report [here](example_files/leakage_report/main.html)"
295+
"Open the report [here](example_files/leakage_report_basis/main.html)"
268296
]
269297
},
270298
{
@@ -288,15 +316,15 @@
288316
"E1 = np.concatenate( (mdl_2level_ideal.povms['Mdefault']['1'].to_dense(),[eps]), axis=0)\n",
289317
"\n",
290318
"\n",
291-
"statespace = pygsti.baseobjs.ExplicitStateSpace([('Qubit',),('Leakage',)],[(2,),(1,)])\n",
292-
"mdl_2plus1_ideal = pygsti.models.ExplicitOpModel(statespace, 'gm')\n",
319+
"statespace = pygsti.baseobjs.ExplicitStateSpace([('Qubit',),('Leakage',)], [(2,), (1,)])\n",
320+
"mdl_2plus1_ideal = pygsti.models.ExplicitOpModel(statespace, 'gm', simulator='matrix')\n",
293321
"mdl_2plus1_ideal['rho0'] = rho0\n",
294322
"mdl_2plus1_ideal['Mdefault'] = pygsti.modelmembers.povms.UnconstrainedPOVM([('0',E0),('1',E1)],\n",
295323
" evotype='default', state_space=statespace)\n",
296324
"\n",
297-
"mdl_2plus1_ideal['Gi'] = to_2plus1_superop(mdl_2level_ideal['Gi'])\n",
298-
"mdl_2plus1_ideal['Gx'] = to_2plus1_superop(mdl_2level_ideal['Gx'])\n",
299-
"mdl_2plus1_ideal['Gy'] = to_2plus1_superop(mdl_2level_ideal['Gy'])"
325+
"mdl_2plus1_ideal[tuple()] = to_2plus1_superop(mdl_2level_ideal[tuple()])\n",
326+
"mdl_2plus1_ideal['Gxpi2'] = to_2plus1_superop(mdl_2level_ideal['Gxpi2', 'Qubit'])\n",
327+
"mdl_2plus1_ideal['Gypi2'] = to_2plus1_superop(mdl_2level_ideal['Gypi2', 'Qubit'])"
300328
]
301329
},
302330
{
@@ -305,9 +333,22 @@
305333
"metadata": {},
306334
"outputs": [],
307335
"source": [
308-
"mdl_2plus1_ideal.sim = \"matrix\" # so we can construct report below\n",
309-
"results_2plus1 = pygsti.run_long_sequence_gst(ds, mdl_2plus1_ideal, prepfids, measfids,\n",
310-
" germs, maxLengths, verbosity=2,\n",
336+
"# We have found out prep fids, meas fids, and germs, as well as simulated noisy data, for the 3 level model\n",
337+
"# If we want to run GST on another model, we need to get versions of the circuits will the correct state space labels\n",
338+
"\n",
339+
"# We do this in a slightly different/awkward way here for this case since our state space labels are not a single entry\n",
340+
"# This would not be necessary if we were rebuilding the circuits/dataset from scratch, only hacky since we are reusing the 3-level information\n",
341+
"def map_2plus1_circuit_linelabels(circuit):\n",
342+
" return Circuit([Label(l.name) if l.name != \"COMPOUND\" else tuple() for l in circuit.layertup],\n",
343+
" \"*\", None, not circuit._static)\n",
344+
"\n",
345+
"prepfids_2plus1 = [map_2plus1_circuit_linelabels(c) for c in prepfids]\n",
346+
"measfids_2plus1 = [map_2plus1_circuit_linelabels(c) for c in measfids]\n",
347+
"germs_2plus1 = [map_2plus1_circuit_linelabels(c) for c in germs]\n",
348+
"ds_2plus1 = ds.process_circuits(map_2plus1_circuit_linelabels)\n",
349+
"\n",
350+
"results_2plus1 = pygsti.run_long_sequence_gst(ds_2plus1, mdl_2plus1_ideal, prepfids_2plus1, measfids_2plus1,\n",
351+
" germs_2plus1, maxLengths, verbosity=2,\n",
311352
" advanced_options={\"starting_point\": \"target\",\n",
312353
" \"tolerance\": 1e-8, # (lowering tolerance from 1e-6 gave a better fit)\n",
313354
" \"estimate_label\": \"kite\"})"
@@ -324,11 +365,8 @@
324365
"outputs": [],
325366
"source": [
326367
"# TODO: This is currently broken\n",
327-
"pygsti.report.construct_standard_report(\n",
328-
" {'two-level': results_2level, 'three-level': results_3level_leakage_basis,\n",
329-
" 'two+one level': results_2plus1},\n",
330-
" \"Leakage Example Report\"\n",
331-
").write_html('example_files/leakage_report', autosize='none')"
368+
"pygsti.report.construct_standard_report(results_2plus1,\"2+1 Leakage Example Report\"\n",
369+
").write_html('example_files/leakage_report_2plus1', autosize='none')"
332370
]
333371
},
334372
{
@@ -341,9 +379,9 @@
341379
],
342380
"metadata": {
343381
"kernelspec": {
344-
"display_name": "leakage_models",
382+
"display_name": "pygsti",
345383
"language": "python",
346-
"name": "leakage_models"
384+
"name": "python3"
347385
},
348386
"language_info": {
349387
"codemirror_mode": {
@@ -355,7 +393,7 @@
355393
"name": "python",
356394
"nbconvert_exporter": "python",
357395
"pygments_lexer": "ipython3",
358-
"version": "3.9.13"
396+
"version": "3.11.5"
359397
}
360398
},
361399
"nbformat": 4,

jupyter_notebooks/Tutorials/algorithms/GST-Protocols.ipynb

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,95 @@
138138
"custom_gauge_opt_model = results_TP2.estimates['GSTwithMyGO'].models['my_gauge_opt']"
139139
]
140140
},
141+
{
142+
"cell_type": "markdown",
143+
"metadata": {},
144+
"source": [
145+
"### Wildcard parameters\n",
146+
"\n",
147+
"TODO"
148+
]
149+
},
150+
{
151+
"cell_type": "code",
152+
"execution_count": null,
153+
"metadata": {},
154+
"outputs": [],
155+
"source": [
156+
"proto = pygsti.protocols.GateSetTomography(\n",
157+
" target_model_TP, name=\"GSTwithPerGateWildcard\",\n",
158+
" badfit_options={'actions': ['wildcard']}\n",
159+
" )\n",
160+
"\n",
161+
"# Artifically unset threshold so that wildcard runs. YOU WOULD NOT DO THIS IN PRODUCTION RUNS\n",
162+
"proto.badfit_options.threshold = None\n",
163+
"\n",
164+
"results_pergate_wildcard = proto.run(data, disable_checkpointing=True)"
165+
]
166+
},
167+
{
168+
"cell_type": "code",
169+
"execution_count": null,
170+
"metadata": {},
171+
"outputs": [],
172+
"source": [
173+
"# The wildcard can be retrieved by looking at unmodeled_error in the estimates\n",
174+
"results_pergate_wildcard.estimates['GSTwithPerGateWildcard'].parameters['unmodeled_error']"
175+
]
176+
},
177+
{
178+
"cell_type": "markdown",
179+
"metadata": {},
180+
"source": [
181+
"Another common form of wildcard is to have one parameter for SPAM and one for all the other gates."
182+
]
183+
},
184+
{
185+
"cell_type": "code",
186+
"execution_count": null,
187+
"metadata": {},
188+
"outputs": [],
189+
"source": [
190+
"op_label_dict = {k:0 for k in target_model_TP.operations} # Assign all gates to value 0\n",
191+
"op_label_dict['SPAM'] = 1 # Assign SPAM to value 1\n",
192+
"\n",
193+
"proto = pygsti.protocols.GateSetTomography(\n",
194+
" target_model_TP, name=\"GSTwithPerGateWildcard\",\n",
195+
" badfit_options={'actions': ['wildcard'], 'wildcard_primitive_op_labels': op_label_dict}\n",
196+
" )\n",
197+
"\n",
198+
"# Artifically unset threshold so that wildcard runs. YOU WOULD NOT DO THIS IN PRODUCTION RUNS\n",
199+
"proto.badfit_options.threshold = None\n",
200+
"\n",
201+
"results_globalgate_wildcard = proto.run(data, disable_checkpointing=True)"
202+
]
203+
},
204+
{
205+
"cell_type": "markdown",
206+
"metadata": {},
207+
"source": [
208+
"Unfortunately both of these wildcard strategies have the same problem. They are not unique, i.e. it is possible to \"slosh\" wildcard strength from one parameter to another to get another valid wildcard solution. This makes it difficult to make any quantitative statements about relative wildcard strengths.\n",
209+
"\n",
210+
"In order to avoid this, we have also introduced a 1D wildcard solution. This takes some reference weighting for the model operations and scales a single wildcard parameter ($\\alpha$) up until the model fits the data. Since there is only one parameter, this does not have any of the ambiguity of the above wildcard strategies. Currently, the reference weighting used is the diamond distance from the noisy model to the target model, with the intuition that \"noisier\" operations are more likely to contribute to model violation."
211+
]
212+
},
213+
{
214+
"cell_type": "code",
215+
"execution_count": null,
216+
"metadata": {},
217+
"outputs": [],
218+
"source": [
219+
"proto = pygsti.protocols.GateSetTomography(\n",
220+
" target_model_TP, name=\"GSTwithPerGateWildcard\",\n",
221+
" badfit_options={'actions': ['wildcard1d'], 'wildcard1d_reference': 'diamond distance'}\n",
222+
" )\n",
223+
"\n",
224+
"# Artifically unset threshold so that wildcard runs. YOU WOULD NOT DO THIS IN PRODUCTION RUNS\n",
225+
"proto.badfit_options.threshold = None\n",
226+
"\n",
227+
"results_1d_wildcard = proto.run(data, disable_checkpointing=True)"
228+
]
229+
},
141230
{
142231
"cell_type": "markdown",
143232
"metadata": {},
@@ -487,9 +576,9 @@
487576
],
488577
"metadata": {
489578
"kernelspec": {
490-
"display_name": "gst_checkpointing",
579+
"display_name": "pygsti",
491580
"language": "python",
492-
"name": "gst_checkpointing"
581+
"name": "python3"
493582
},
494583
"language_info": {
495584
"codemirror_mode": {
@@ -501,7 +590,7 @@
501590
"name": "python",
502591
"nbconvert_exporter": "python",
503592
"pygments_lexer": "ipython3",
504-
"version": "3.9.13"
593+
"version": "3.11.5"
505594
}
506595
},
507596
"nbformat": 4,

0 commit comments

Comments
 (0)