#!/usr/bin/env python # coding: utf-8 # # Leakage characterization using GST # This tutorial demonstrates how to perform GST on a "leaky-qubit" described by a 3-level (instead of the desired 2-level) system. # In[1]: import pygsti import pygsti.construction as pc import pygsti.construction.std1Q_XYI as std1Q import numpy as np import scipy.linalg as sla #import pickle # In[2]: def to_3level_unitary(U_2level): U_3level = np.zeros((3,3),complex) U_3level[0:2,0:2] = U_2level U_3level[2,2] = 1.0 return U_3level def unitary_to_gmgate(U): return pygsti.tools.change_basis( pygsti.tools.unitary_to_process_mx(U), 'std','gm') def state_to_gmvec(state): pygsti.tools.stdmx_to_gmvec Us = pygsti.tools.internalgates.get_standard_gatename_unitaries() # In[3]: mdl_2level_ideal = std1Q.target_model() # In[4]: rho0 = np.array( [[1,0,0], [0,0,0], [0,0,0]], complex) E0 = rho0 E1 = np.array( [[0,0,0], [0,1,0], [0,0,1]], complex) sslbls = pygsti.obj.StateSpaceLabels(['Qubit+Leakage'],[3]) mdl_3level_ideal = pygsti.obj.ExplicitOpModel(sslbls, 'gm') mdl_3level_ideal['rho0'] = pygsti.tools.stdmx_to_gmvec(rho0) mdl_3level_ideal['Mdefault'] = pygsti.obj.TPPOVM([('0',pygsti.tools.stdmx_to_gmvec(E0)), ('1',pygsti.tools.stdmx_to_gmvec(E1))]) mdl_3level_ideal['Gi'] = unitary_to_gmgate( to_3level_unitary(Us['Gi'])) mdl_3level_ideal['Gx'] = unitary_to_gmgate( to_3level_unitary(Us['Gxpi2'])) mdl_3level_ideal['Gy'] = unitary_to_gmgate( to_3level_unitary(Us['Gypi2'])) # In[5]: sigmaX = np.array([[0,1],[1,0]],complex) rot = sla.expm(1j * 0.1 * sigmaX) Uleakage = np.identity(3,complex) Uleakage[1:3,1:3] = rot leakageOp = unitary_to_gmgate(Uleakage) #print(Uleakage) #Guess of a model w/just unitary leakage mdl_3level_guess = mdl_3level_ideal.copy() mdl_3level_guess['Gi'] = np.dot(leakageOp, mdl_3level_guess['Gi']) #mdl_3level_guess['Gx'] = np.dot(leakageOp, mdl_3level_guess['Gx']) #mdl_3level_guess['Gy'] = np.dot(leakageOp, mdl_3level_guess['Gy']) #Actual model used for data generation (some depolarization too) mdl_3level_noisy = mdl_3level_ideal.depolarize(op_noise=0.005, spam_noise=0.01) mdl_3level_noisy['Gi'] = np.dot(leakageOp, mdl_3level_noisy['Gi']) #mdl_3level_noisy['Gx'] = np.dot(leakageOp, mdl_3level_noisy['Gx']) #mdl_3level_noisy['Gy'] = np.dot(leakageOp, mdl_3level_noisy['Gy']) # In[6]: #print(mdl_3level_guess) # In[7]: # get sequences using expected model generate_fiducials = False if generate_fiducials: prepfids, measfids = pygsti.algorithms.generate_fiducials( mdl_3level_guess, omitIdentity=False, maxFidLength=4, verbosity=4) pygsti.io.write_circuit_list("example_files/leakage_prepfids.txt", prepfids) pygsti.io.write_circuit_list("example_files/leakage_measfids.txt", measfids) # In[8]: prepfids = pygsti.io.load_circuit_list("example_files/leakage_prepfids.txt") measfids = pygsti.io.load_circuit_list("example_files/leakage_measfids.txt") germs = std1Q.germs maxLengths = [1,] expList = pc.make_lsgst_experiment_list(mdl_3level_noisy, prepfids, measfids, germs, maxLengths) ds = pc.generate_fake_data(mdl_3level_noisy, expList, 1000, 'binomial', seed=1234) # In[9]: results_2level = pygsti.do_stdpractice_gst(ds, mdl_2level_ideal, prepfids, measfids, germs, maxLengths, modes="CPTP", verbosity=3) results_3level = pygsti.do_stdpractice_gst(ds, mdl_3level_ideal, prepfids, measfids, germs, maxLengths, modes="CPTP,True", modelsToTest={'True': mdl_3level_noisy}, verbosity=4, advancedOptions={'all': {'tolerance': 1e-2}}) # In[ ]: # In[10]: pygsti.report.create_standard_report({'two-level': results_2level, 'three-level': results_3level}, "example_files/leakage_report", "Leakage Example Report") # In[11]: #try a different basis: gm_basis = pygsti.obj.Basis('gm',3) leakage_basis_mxs = [ np.sqrt(2)/3*(np.sqrt(3)*gm_basis[0] + 0.5*np.sqrt(6)*gm_basis[8]), gm_basis[1], gm_basis[4], gm_basis[7], gm_basis[2], gm_basis[3], gm_basis[5], gm_basis[6], 1/3*(np.sqrt(3)*gm_basis[0] - np.sqrt(6)*gm_basis[8]) ] #for mx in leakage_basis_mxs: # pygsti.tools.print_mx(mx) check = np.zeros( (9,9), complex) for i,m1 in enumerate(leakage_basis_mxs): for j,m2 in enumerate(leakage_basis_mxs): check[i,j] = np.trace(np.dot(m1,m2)) assert(np.allclose(check, np.identity(9,complex))) leakage_basis = pygsti.obj.Basis(name="LeakageBasis", matrices=leakage_basis_mxs, longname="2+1 level leakage basis", real=True, labels=['I','X','Y','Z','LX0','LX1','LY0','LY1','L']) def changebasis_3level_model(mdl): new_mdl = mdl.copy() new_mdl.preps['rho0'] = pygsti.obj.FullSPAMVec( pygsti.tools.change_basis(mdl.preps['rho0'].todense(), gm_basis, leakage_basis)) new_mdl.povms['Mdefault'] = pygsti.obj.UnconstrainedPOVM( [('0', pygsti.tools.change_basis(mdl.povms['Mdefault']['0'].todense(), gm_basis, leakage_basis)), ('1', pygsti.tools.change_basis(mdl.povms['Mdefault']['1'].todense(), gm_basis, leakage_basis))]) for lbl,op in mdl.operations.items(): new_mdl.operations[lbl] = pygsti.obj.FullDenseOp( pygsti.tools.change_basis(op.todense(), gm_basis, leakage_basis)) new_mdl.basis = leakage_basis return new_mdl def changebasis_3level_results(results): new_results = results.copy() for estlbl,est in results.estimates.items(): for mlbl,mdl in est.models.items(): if isinstance(mdl,(list,tuple)): #assume a list/tuple of models new_results.estimates[estlbl].models[mlbl] = \ [ changebasis_3level_model(m) for m in mdl ] else: new_results.estimates[estlbl].models[mlbl] = changebasis_3level_model(mdl) return new_results # In[12]: results_3level_leakage_basis = changebasis_3level_results( results_3level ) # In[13]: pygsti.report.create_standard_report({'two-level': results_2level, 'three-level': results_3level_leakage_basis}, "example_files/leakage_report", "Leakage Example Report") #advancedOptions={'autosize': 'none'}) # Open the report [here](example_files/leakage_report/main.html) # In[14]: # use "kite" density-matrix structure def to_2plus1_superop(superop_2level): ret = np.zeros((5,5),'d') ret[0:4,0:4] = superop_2level ret[4,4] = 1.0 #leave leakage population where it is return ret #Tack on a single extra "0" for the 5-th dimension corresponding # to the classical leakage level population. rho0 = np.concatenate( (mdl_2level_ideal.preps['rho0'],[[0]]), axis=0) E0 = np.concatenate( (mdl_2level_ideal.povms['Mdefault']['0'],[[0]]), axis=0) E1 = np.concatenate( (mdl_2level_ideal.povms['Mdefault']['1'],[[0]]), axis=0) sslbls = pygsti.obj.StateSpaceLabels([('Qubit',),('Leakage',)],[(2,),(1,)]) mdl_2plus1_ideal = pygsti.obj.ExplicitOpModel(sslbls, 'gm') mdl_2plus1_ideal['rho0'] = rho0 mdl_2plus1_ideal['Mdefault'] = pygsti.obj.UnconstrainedPOVM([('0',E0),('1',E1)]) mdl_2plus1_ideal['Gi'] = to_2plus1_superop(mdl_2level_ideal['Gi']) mdl_2plus1_ideal['Gx'] = to_2plus1_superop(mdl_2level_ideal['Gi']) mdl_2plus1_ideal['Gy'] = to_2plus1_superop(mdl_2level_ideal['Gi']) # In[15]: results_2plus1 = pygsti.do_long_sequence_gst(ds, mdl_2plus1_ideal, prepfids, measfids, germs, maxLengths, verbosity=3, advancedOptions={"starting point": "target"}) # In[16]: pygsti.report.create_standard_report({'two-level': results_2level, 'three-level': results_3level_leakage_basis, 'two+one level': results_2plus1}, "example_files/leakage_report", "Leakage Example Report", advancedOptions={'autosize': 'none'}) # Open the report [here](example_files/leakage_report/main.html)