Skip to content

Commit

Permalink
Merge pull request #421 from sandialabs/bugfix-0.9.12.2
Browse files Browse the repository at this point in the history
Bugfix 0.9.12.2
  • Loading branch information
sserita authored Apr 16, 2024
2 parents 89b2d21 + 9b9e5c2 commit 70a3ce5
Show file tree
Hide file tree
Showing 10 changed files with 438 additions and 56 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ jupyter_notebooks/Tutorials/tutorial_files/modeltest_report
jupyter_notebooks/Tutorials/tutorial_files/gettingStartedReport
jupyter_notebooks/Examples/example_files/*.pkl
jupyter_notebooks/Examples/example_files/*.json
jupyter_notebooks/Examples/example_files/leakage_*
jupyter_notebooks/Tutorials/tutorial_files/exampleReport
jupyter_notebooks/Tutorials/tutorial_files/exampleStdReport
jupyter_notebooks/Tutorials/tutorial_files/exampleMultiEstimateReport
Expand Down
134 changes: 86 additions & 48 deletions jupyter_notebooks/Examples/Leakage.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"outputs": [],
"source": [
"import pygsti\n",
"import pygsti.modelpacks.legacy.std1Q_XYI as std1Q\n",
"import pygsti.modelpacks.smq1Q_XYI as smq1Q\n",
"from pygsti.baseobjs import Label\n",
"from pygsti.circuits import Circuit\n",
"import numpy as np\n",
"import scipy.linalg as sla\n",
"#import pickle"
Expand Down Expand Up @@ -49,8 +51,7 @@
"metadata": {},
"outputs": [],
"source": [
"mdl_2level_ideal = std1Q.target_model()\n",
"mdl_2level_ideal.sim = \"matrix\" # so we can create reports later on"
"mdl_2level_ideal = smq1Q.target_model(qubit_labels=[\"Qubit\"])"
]
},
{
Expand All @@ -67,17 +68,16 @@
" [0,1,0],\n",
" [0,0,1]], complex)\n",
"\n",
"sslbls = pygsti.baseobjs.ExplicitStateSpace(['Qubit+Leakage'],[3])\n",
"mdl_3level_ideal = pygsti.models.ExplicitOpModel(sslbls, 'gm')\n",
"sslbls = pygsti.baseobjs.ExplicitStateSpace(['Qubit_leakage'],[3])\n",
"mdl_3level_ideal = pygsti.models.ExplicitOpModel(sslbls, 'gm', simulator='matrix')\n",
"mdl_3level_ideal['rho0'] = pygsti.tools.stdmx_to_gmvec(rho0)\n",
"mdl_3level_ideal['Mdefault'] = pygsti.modelmembers.povms.TPPOVM([('0',pygsti.tools.stdmx_to_gmvec(E0)),\n",
" ('1',pygsti.tools.stdmx_to_gmvec(E1))],\n",
" evotype='default')\n",
"\n",
"mdl_3level_ideal['Gi'] = unitary_to_gmgate( to_3level_unitary(Us['Gi']))\n",
"mdl_3level_ideal['Gx'] = unitary_to_gmgate( to_3level_unitary(Us['Gxpi2']))\n",
"mdl_3level_ideal['Gy'] = unitary_to_gmgate( to_3level_unitary(Us['Gypi2']))\n",
"mdl_3level_ideal.sim = \"matrix\" # so we can create reports later on"
"mdl_3level_ideal[tuple()] = unitary_to_gmgate( to_3level_unitary(Us['Gi']))\n",
"mdl_3level_ideal['Gxpi2', 'Qubit_leakage'] = unitary_to_gmgate( to_3level_unitary(Us['Gxpi2']))\n",
"mdl_3level_ideal['Gypi2', 'Qubit_leakage'] = unitary_to_gmgate( to_3level_unitary(Us['Gypi2']))"
]
},
{
Expand All @@ -95,15 +95,15 @@
"\n",
"#Guess of a model w/just unitary leakage\n",
"mdl_3level_guess = mdl_3level_ideal.copy()\n",
"mdl_3level_guess['Gi'] = np.dot(leakageOp, mdl_3level_guess['Gi'])\n",
"#mdl_3level_guess['Gx'] = np.dot(leakageOp, mdl_3level_guess['Gx'])\n",
"#mdl_3level_guess['Gy'] = np.dot(leakageOp, mdl_3level_guess['Gy'])\n",
"mdl_3level_guess[tuple()] = np.dot(leakageOp, mdl_3level_guess[tuple()])\n",
"#mdl_3level_guess['Gxpi2', 'Qubit_leakage'] = np.dot(leakageOp, mdl_3level_guess['Gxpi2', 'Qubit_leakage'])\n",
"#mdl_3level_guess['Gypi2', 'Qubit_leakage'] = np.dot(leakageOp, mdl_3level_guess['Gypi2', 'Qubit_leakage'])\n",
"\n",
"#Actual model used for data generation (some depolarization too)\n",
"mdl_3level_noisy = mdl_3level_ideal.depolarize(op_noise=0.005, spam_noise=0.01)\n",
"mdl_3level_noisy['Gi'] = np.dot(leakageOp, mdl_3level_noisy['Gi'])\n",
"#mdl_3level_noisy['Gx'] = np.dot(leakageOp, mdl_3level_noisy['Gx'])\n",
"#mdl_3level_noisy['Gy'] = np.dot(leakageOp, mdl_3level_noisy['Gy'])"
"mdl_3level_noisy[tuple()] = np.dot(leakageOp, mdl_3level_noisy[tuple()])\n",
"#mdl_3level_noisy['Gxpi2', 'Qubit_leakage'] = np.dot(leakageOp, mdl_3level_noisy['Gxpi2', 'Qubit_leakage'])\n",
"#mdl_3level_noisy['Gypi2', 'Qubit_leakage'] = np.dot(leakageOp, mdl_3level_noisy['Gypi2', 'Qubit_leakage'])"
]
},
{
Expand All @@ -126,7 +126,7 @@
"\n",
"if find_fiducials:\n",
" prepfids, measfids = pygsti.algorithms.find_fiducials(\n",
" mdl_3level_guess, omit_identity=False, max_fid_length=4, verbosity=4)\n",
" mdl_3level_guess, omit_identity=False, candidate_fid_counts={4: \"all upto\"}, verbosity=4)\n",
" pygsti.io.write_circuit_list(\"example_files/leakage_prepfids.txt\", prepfids)\n",
" pygsti.io.write_circuit_list(\"example_files/leakage_measfids.txt\", measfids)"
]
Expand All @@ -140,10 +140,7 @@
"# If files missing, run previous cell at least once with find_fiducials = True\n",
"prepfids = pygsti.io.read_circuit_list(\"example_files/leakage_prepfids.txt\")\n",
"measfids = pygsti.io.read_circuit_list(\"example_files/leakage_measfids.txt\")\n",
"# HACK: Fix broken force empty labels\n",
"prepfids[-1] = pygsti.circuits.Circuit([])\n",
"measfids[-1] = pygsti.circuits.Circuit([])\n",
"germs = std1Q.germs\n",
"germs = smq1Q.germs(qubit_labels=[\"Qubit_leakage\"])\n",
"maxLengths = [1,]\n",
"expList = pygsti.circuits.create_lsgst_circuits(mdl_3level_noisy, prepfids, measfids, germs, maxLengths)\n",
"ds = pygsti.data.simulate_data(mdl_3level_noisy, expList, 1000, 'binomial', seed=1234)"
Expand All @@ -155,8 +152,37 @@
"metadata": {},
"outputs": [],
"source": [
"results_2level = pygsti.run_stdpractice_gst(ds, mdl_2level_ideal, prepfids, measfids,\n",
" germs, maxLengths, modes=\"CPTPLND\", verbosity=3)"
"\n",
"# We have found out prep fids, meas fids, and germs, as well as simulated noisy data, for the 3 level model\n",
"# If we want to run GST on another model, we need to get versions of the circuits will the correct state space labels\n",
"\n",
"def map_2level_sslbls(circuit):\n",
" sslbl_map = {'Qubit_leakage': 'Qubit'}\n",
" return circuit.map_state_space_labels(sslbl_map)\n",
"\n",
"prepfids_2level = [map_2level_sslbls(c) for c in prepfids]\n",
"measfids_2level = [map_2level_sslbls(c) for c in measfids]\n",
"germs_2level = [map_2level_sslbls(c) for c in germs]\n",
"ds_2level = ds.process_circuits(map_2level_sslbls)\n",
"\n",
"results_2level = pygsti.run_stdpractice_gst(ds_2level, mdl_2level_ideal, prepfids_2level, measfids_2level,\n",
" germs_2level, maxLengths, modes=\"CPTPLND\", verbosity=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pygsti.report.construct_standard_report(results_2level, \"2-level Leakage Example Report\").write_html('example_files/leakage_report_2level')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Open the report [here](example_files/leakage_report_2level/main.html)"
]
},
{
Expand All @@ -168,7 +194,7 @@
"outputs": [],
"source": [
"results_3level = pygsti.run_stdpractice_gst(ds, mdl_3level_ideal, prepfids, measfids,\n",
" germs, maxLengths, modes=[\"CPTP\",\"True\"],\n",
" germs, maxLengths, modes=[\"CPTPLND\",\"True\"],\n",
" models_to_test={'True': mdl_3level_noisy}, \n",
" verbosity=4, advanced_options={'all': {'tolerance': 1e-2}})"
]
Expand All @@ -179,10 +205,14 @@
"metadata": {},
"outputs": [],
"source": [
"pygsti.report.construct_standard_report(\n",
" {'two-level': results_2level, 'three-level': results_3level},\n",
" \"Leakage Example Report\"\n",
").write_html('example_files/leakage_report')"
"pygsti.report.construct_standard_report(results_3level, \"3-level Leakage Example Report\").write_html('example_files/leakage_report')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Open the report [here](example_files/leakage_report/main.html)"
]
},
{
Expand Down Expand Up @@ -254,17 +284,15 @@
"metadata": {},
"outputs": [],
"source": [
"pygsti.report.construct_standard_report(\n",
" {'two-level': results_2level, 'three-level': results_3level_leakage_basis},\n",
" \"Leakage Example Report\"\n",
").write_html('example_files/leakage_report')"
"pygsti.report.construct_standard_report(results_3level_leakage_basis, \"3-level with Basis Change Leakage Example Report\"\n",
" ).write_html('example_files/leakage_report_basis')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Open the report [here](example_files/leakage_report/main.html)"
"Open the report [here](example_files/leakage_report_basis/main.html)"
]
},
{
Expand All @@ -288,15 +316,15 @@
"E1 = np.concatenate( (mdl_2level_ideal.povms['Mdefault']['1'].to_dense(),[eps]), axis=0)\n",
"\n",
"\n",
"statespace = pygsti.baseobjs.ExplicitStateSpace([('Qubit',),('Leakage',)],[(2,),(1,)])\n",
"mdl_2plus1_ideal = pygsti.models.ExplicitOpModel(statespace, 'gm')\n",
"statespace = pygsti.baseobjs.ExplicitStateSpace([('Qubit',),('Leakage',)], [(2,), (1,)])\n",
"mdl_2plus1_ideal = pygsti.models.ExplicitOpModel(statespace, 'gm', simulator='matrix')\n",
"mdl_2plus1_ideal['rho0'] = rho0\n",
"mdl_2plus1_ideal['Mdefault'] = pygsti.modelmembers.povms.UnconstrainedPOVM([('0',E0),('1',E1)],\n",
" evotype='default', state_space=statespace)\n",
"\n",
"mdl_2plus1_ideal['Gi'] = to_2plus1_superop(mdl_2level_ideal['Gi'])\n",
"mdl_2plus1_ideal['Gx'] = to_2plus1_superop(mdl_2level_ideal['Gx'])\n",
"mdl_2plus1_ideal['Gy'] = to_2plus1_superop(mdl_2level_ideal['Gy'])"
"mdl_2plus1_ideal[tuple()] = to_2plus1_superop(mdl_2level_ideal[tuple()])\n",
"mdl_2plus1_ideal['Gxpi2'] = to_2plus1_superop(mdl_2level_ideal['Gxpi2', 'Qubit'])\n",
"mdl_2plus1_ideal['Gypi2'] = to_2plus1_superop(mdl_2level_ideal['Gypi2', 'Qubit'])"
]
},
{
Expand All @@ -305,9 +333,22 @@
"metadata": {},
"outputs": [],
"source": [
"mdl_2plus1_ideal.sim = \"matrix\" # so we can construct report below\n",
"results_2plus1 = pygsti.run_long_sequence_gst(ds, mdl_2plus1_ideal, prepfids, measfids,\n",
" germs, maxLengths, verbosity=2,\n",
"# We have found out prep fids, meas fids, and germs, as well as simulated noisy data, for the 3 level model\n",
"# If we want to run GST on another model, we need to get versions of the circuits will the correct state space labels\n",
"\n",
"# We do this in a slightly different/awkward way here for this case since our state space labels are not a single entry\n",
"# 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",
"def map_2plus1_circuit_linelabels(circuit):\n",
" return Circuit([Label(l.name) if l.name != \"COMPOUND\" else tuple() for l in circuit.layertup],\n",
" \"*\", None, not circuit._static)\n",
"\n",
"prepfids_2plus1 = [map_2plus1_circuit_linelabels(c) for c in prepfids]\n",
"measfids_2plus1 = [map_2plus1_circuit_linelabels(c) for c in measfids]\n",
"germs_2plus1 = [map_2plus1_circuit_linelabels(c) for c in germs]\n",
"ds_2plus1 = ds.process_circuits(map_2plus1_circuit_linelabels)\n",
"\n",
"results_2plus1 = pygsti.run_long_sequence_gst(ds_2plus1, mdl_2plus1_ideal, prepfids_2plus1, measfids_2plus1,\n",
" germs_2plus1, maxLengths, verbosity=2,\n",
" advanced_options={\"starting_point\": \"target\",\n",
" \"tolerance\": 1e-8, # (lowering tolerance from 1e-6 gave a better fit)\n",
" \"estimate_label\": \"kite\"})"
Expand All @@ -324,11 +365,8 @@
"outputs": [],
"source": [
"# TODO: This is currently broken\n",
"pygsti.report.construct_standard_report(\n",
" {'two-level': results_2level, 'three-level': results_3level_leakage_basis,\n",
" 'two+one level': results_2plus1},\n",
" \"Leakage Example Report\"\n",
").write_html('example_files/leakage_report', autosize='none')"
"pygsti.report.construct_standard_report(results_2plus1,\"2+1 Leakage Example Report\"\n",
").write_html('example_files/leakage_report_2plus1', autosize='none')"
]
},
{
Expand All @@ -341,9 +379,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "leakage_models",
"display_name": "pygsti",
"language": "python",
"name": "leakage_models"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
Expand All @@ -355,7 +393,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.13"
"version": "3.11.5"
}
},
"nbformat": 4,
Expand Down
95 changes: 92 additions & 3 deletions jupyter_notebooks/Tutorials/algorithms/GST-Protocols.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,95 @@
"custom_gauge_opt_model = results_TP2.estimates['GSTwithMyGO'].models['my_gauge_opt']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Wildcard parameters\n",
"\n",
"TODO"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"proto = pygsti.protocols.GateSetTomography(\n",
" target_model_TP, name=\"GSTwithPerGateWildcard\",\n",
" badfit_options={'actions': ['wildcard']}\n",
" )\n",
"\n",
"# Artifically unset threshold so that wildcard runs. YOU WOULD NOT DO THIS IN PRODUCTION RUNS\n",
"proto.badfit_options.threshold = None\n",
"\n",
"results_pergate_wildcard = proto.run(data, disable_checkpointing=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# The wildcard can be retrieved by looking at unmodeled_error in the estimates\n",
"results_pergate_wildcard.estimates['GSTwithPerGateWildcard'].parameters['unmodeled_error']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Another common form of wildcard is to have one parameter for SPAM and one for all the other gates."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"op_label_dict = {k:0 for k in target_model_TP.operations} # Assign all gates to value 0\n",
"op_label_dict['SPAM'] = 1 # Assign SPAM to value 1\n",
"\n",
"proto = pygsti.protocols.GateSetTomography(\n",
" target_model_TP, name=\"GSTwithPerGateWildcard\",\n",
" badfit_options={'actions': ['wildcard'], 'wildcard_primitive_op_labels': op_label_dict}\n",
" )\n",
"\n",
"# Artifically unset threshold so that wildcard runs. YOU WOULD NOT DO THIS IN PRODUCTION RUNS\n",
"proto.badfit_options.threshold = None\n",
"\n",
"results_globalgate_wildcard = proto.run(data, disable_checkpointing=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"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",
"\n",
"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."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"proto = pygsti.protocols.GateSetTomography(\n",
" target_model_TP, name=\"GSTwithPerGateWildcard\",\n",
" badfit_options={'actions': ['wildcard1d'], 'wildcard1d_reference': 'diamond distance'}\n",
" )\n",
"\n",
"# Artifically unset threshold so that wildcard runs. YOU WOULD NOT DO THIS IN PRODUCTION RUNS\n",
"proto.badfit_options.threshold = None\n",
"\n",
"results_1d_wildcard = proto.run(data, disable_checkpointing=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down Expand Up @@ -487,9 +576,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "gst_checkpointing",
"display_name": "pygsti",
"language": "python",
"name": "gst_checkpointing"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
Expand All @@ -501,7 +590,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.13"
"version": "3.11.5"
}
},
"nbformat": 4,
Expand Down
Loading

0 comments on commit 70a3ce5

Please sign in to comment.