#Import the pyGSTi module -- you probably want this at the beginning of every notebook
import pygsti
import pygsti.construction as pc
#The workhorse function is GST.create_gatestring_list, which executes its positional arguments within a nested
# loop given by iterable keyword arguments. That's a mouthful, so let's look at a few examples:
As = [('a1',),('a2',)]
Bs = [('b1','b2'), ('b3','b4')]
def rep2(x):
return x+x
list1 = pc.create_gatestring_list("a", a=As)
list2 = pc.create_gatestring_list("a+b", a=As, b=Bs, order=['a','b'])
list3 = pc.create_gatestring_list("R(a)+c", a=As, c=[('c',)], R=rep2)
print "list1 = ",map(tuple,list1)
print "list2 = ",list2
print "list3 = ",map(str,list3)
list1 = [('a1',), ('a2',)] list2 = [GateString(a1b1b2), GateString(a1b3b4), GateString(a2b1b2), GateString(a2b3b4)] list3 = ['a1a1c', 'a2a2c']
#The functions within GST.GateStringTools are useful for calling within a createGateString(...) loop.
# Here's how some of the most common ones behave:
print pc.repeat_and_truncate (('A','B','C'),5) #args (x,N): repeat x until it is exactly length N
print pc.repeat_with_max_length (('A','B','C'),5) #args (x,N): repeat x the maximum integer number of times so len(x) < N
print pc.repeat_count_with_max_length(('A','B','C'),5) #args (x,N): the maximum integer number of times so len(x) < N
('A', 'B', 'C', 'A', 'B') ('A', 'B', 'C') 1
#Now let's have a look at some more advanced examples of using create_gatestring_list along with the functions above.
fids = pc.gatestring_list( [ ('Gf0',), ('Gf1',) ] )
germs = pc.gatestring_list( [ ('G0',), ('G1a','G1b')] )
gateStrings1 = pc.create_gatestring_list("f0+germ*e+f1", f0=fids, f1=fids,
germ=germs, e=2, order=["germ","f0","f1"])
print "gateStrings1 = \n","\n".join(map(str,gateStrings1)),"\n"
gateStrings2 = pc.create_gatestring_list("f0+T(germ,N)+f1", f0=fids, f1=fids,
germ=germs, N=3, T=pc.repeat_and_truncate,
order=["germ","f0","f1"])
print "gateStrings2 = \n","\n".join(map(str,gateStrings2)),"\n"
gateStrings3 = pc.create_gatestring_list("f0+T(germ,N)+f1", f0=fids, f1=fids,
germ=germs, N=3, T=pc.repeat_with_max_length,
order=["germ","f0","f1"])
print "gateStrings3 = \n","\n".join(map(str,gateStrings3)),"\n"
gateStrings1 = Gf0(G0)^2Gf0 Gf0(G0)^2Gf1 Gf1(G0)^2Gf0 Gf1(G0)^2Gf1 Gf0(G1aG1b)^2Gf0 Gf0(G1aG1b)^2Gf1 Gf1(G1aG1b)^2Gf0 Gf1(G1aG1b)^2Gf1 gateStrings2 = Gf0G0G0G0Gf0 Gf0G0G0G0Gf1 Gf1G0G0G0Gf0 Gf1G0G0G0Gf1 Gf0G1aG1bG1aGf0 Gf0G1aG1bG1aGf1 Gf1G1aG1bG1aGf0 Gf1G1aG1bG1aGf1 gateStrings3 = Gf0(G0)^3Gf0 Gf0(G0)^3Gf1 Gf1(G0)^3Gf0 Gf1(G0)^3Gf1 Gf0(G1aG1b)Gf0 Gf0(G1aG1b)Gf1 Gf1(G1aG1b)Gf0 Gf1(G1aG1b)Gf1
#Let's suppose we have some initial lists of strings and gates
myGerms = pc.gatestring_list( [ ('G1',), ('G2',), ('G3',) ]) #list of germs
myFiducialList = pc.gatestring_list([ ('Gf1',), ('Gf2',) ]) #list of fiducials
myGates = [ 'Gx', 'Gy' ] #gate labels -- often just gateset.keys()
mySpecs = pc.build_spam_specs(fiducialGateStrings=myFiducialList) #Don't worry about this for now - it's just a conversion from fiducial strings to the more general "specs" object that GST uses
#Two special cases: LGST strings and all the gate strings within a certain length range
allStringsInLengthRange = pc.list_all_gatestrings(myGates, minlength=0, maxlength=2)
print "\nAll strings using %s up to length 2 = \n" % str(myGates), "\n".join(map(str,allStringsInLengthRange))
lgstStrings = pc.list_lgst_gatestrings(mySpecs,myGates)
print "\nLGST strings = \n","\n".join(map(str,lgstStrings))
All strings using ['Gx', 'Gy'] up to length 2 = {} Gx Gy GxGx GxGy GyGx GyGy LGST strings = Gf1 Gf2 Gf1Gf1 Gf1Gf2 Gf2Gf1 Gf2Gf2 Gf1(Gx)Gf1 Gf1(Gx)Gf2 Gf2(Gx)Gf1 Gf2(Gx)Gf2 Gf1(Gy)Gf1 Gf1(Gy)Gf2 Gf2(Gy)Gf1 Gf2(Gy)Gf2
#germ^exponent strings
germExpStrings = pc.create_gatestring_list("germ*exp", germ=myGerms, exp=[1,2], order=('germ','exp'))
print "\nGerm^Exp strings = \n", "\n".join(map(str,germExpStrings))
germExpStringsSand = pc.create_gatestring_list("f0+germ*exp+f1", f0=myFiducialList, f1=myFiducialList,
germ=myGerms, exp=[1,2], order=('germ','exp','f0','f1'))
print "\nGerm^Exp strings sandwiched by fiducials = \n", "\n".join(map(str,germExpStringsSand))
Germ^Exp strings = (G1) (G1)^2 (G2) (G2)^2 (G3) (G3)^2 Germ^Exp strings sandwiched by fiducials = Gf1(G1)Gf1 Gf1(G1)Gf2 Gf2(G1)Gf1 Gf2(G1)Gf2 Gf1(G1)^2Gf1 Gf1(G1)^2Gf2 Gf2(G1)^2Gf1 Gf2(G1)^2Gf2 Gf1(G2)Gf1 Gf1(G2)Gf2 Gf2(G2)Gf1 Gf2(G2)Gf2 Gf1(G2)^2Gf1 Gf1(G2)^2Gf2 Gf2(G2)^2Gf1 Gf2(G2)^2Gf2 Gf1(G3)Gf1 Gf1(G3)Gf2 Gf2(G3)Gf1 Gf2(G3)Gf2 Gf1(G3)^2Gf1 Gf1(G3)^2Gf2 Gf2(G3)^2Gf1 Gf2(G3)^2Gf2
# germ^exponent strings that are in some way truncated to a given length (these will be useful later on)
#for eLGST lists typically include just the gate strings you want LGST to estimate - NOT the fiducials
listOfLists_eLGST = [ myGates[:] ]
for maxLen in [1,2]:
gsList = pc.create_gatestring_list("R(germ,N)", germ=myGerms, N=maxLen,
R=pc.repeat_with_max_length,
order=('germ','f0','f1'))
listOfLists_eLGST.append( listOfLists_eLGST[-1] + gsList )
print "Typical eLGST list of lists:\n"
for i,l in enumerate(listOfLists_eLGST):
print "List %d:\n" % i,"\n".join(map(str,l)),"\n"
#In order to have LSGST use gate strings containing the fiducials on either end, you must include the
# fiducials in the gate strings.
listOfLists_LSGST = [ pc.list_lgst_gatestrings(mySpecs,myGates) ]
for maxLen in [1,2]:
gsList = pc.create_gatestring_list("f0+R(germ,N)+f1", f0=myFiducialList,
f1=myFiducialList, germ=myGerms, N=maxLen,
R=pc.repeat_with_max_length,
order=('germ','f0','f1'))
listOfLists_LSGST.append( listOfLists_LSGST[-1] + gsList )
print "\nTypical LSGST list of lists:\n"
for i,l in enumerate(listOfLists_LSGST):
print "List %d:\n" % i,"\n".join(map(str,l)),"\n"
Typical eLGST list of lists: List 0: Gx Gy List 1: Gx Gy (G1) (G2) (G3) List 2: Gx Gy (G1) (G2) (G3) (G1)^2 (G2)^2 (G3)^2 Typical LSGST list of lists: List 0: Gf1 Gf2 Gf1Gf1 Gf1Gf2 Gf2Gf1 Gf2Gf2 Gf1(Gx)Gf1 Gf1(Gx)Gf2 Gf2(Gx)Gf1 Gf2(Gx)Gf2 Gf1(Gy)Gf1 Gf1(Gy)Gf2 Gf2(Gy)Gf1 Gf2(Gy)Gf2 List 1: Gf1 Gf2 Gf1Gf1 Gf1Gf2 Gf2Gf1 Gf2Gf2 Gf1(Gx)Gf1 Gf1(Gx)Gf2 Gf2(Gx)Gf1 Gf2(Gx)Gf2 Gf1(Gy)Gf1 Gf1(Gy)Gf2 Gf2(Gy)Gf1 Gf2(Gy)Gf2 Gf1(G1)Gf1 Gf1(G1)Gf2 Gf2(G1)Gf1 Gf2(G1)Gf2 Gf1(G2)Gf1 Gf1(G2)Gf2 Gf2(G2)Gf1 Gf2(G2)Gf2 Gf1(G3)Gf1 Gf1(G3)Gf2 Gf2(G3)Gf1 Gf2(G3)Gf2 List 2: Gf1 Gf2 Gf1Gf1 Gf1Gf2 Gf2Gf1 Gf2Gf2 Gf1(Gx)Gf1 Gf1(Gx)Gf2 Gf2(Gx)Gf1 Gf2(Gx)Gf2 Gf1(Gy)Gf1 Gf1(Gy)Gf2 Gf2(Gy)Gf1 Gf2(Gy)Gf2 Gf1(G1)Gf1 Gf1(G1)Gf2 Gf2(G1)Gf1 Gf2(G1)Gf2 Gf1(G2)Gf1 Gf1(G2)Gf2 Gf2(G2)Gf1 Gf2(G2)Gf2 Gf1(G3)Gf1 Gf1(G3)Gf2 Gf2(G3)Gf1 Gf2(G3)Gf2 Gf1(G1)^2Gf1 Gf1(G1)^2Gf2 Gf2(G1)^2Gf1 Gf2(G1)^2Gf2 Gf1(G2)^2Gf1 Gf1(G2)^2Gf2 Gf2(G2)^2Gf1 Gf2(G2)^2Gf2 Gf1(G3)^2Gf1 Gf1(G3)^2Gf2 Gf2(G3)^2Gf1 Gf2(G3)^2Gf2
# As a final full-fledged example we give a function which generates gate string lists for:
# 1) running eLGST
# 2) running LSGST
# 3) creating a template dataset file
# all from some lists of gates, fiducials, germs, and maximum lengths. This example function can be copied and used
# verbatim in many circumstances and modified in others in order to fit typical gate string generation tasks.
def make_lsgst_lists(gateLabels, fiducialList, germList, maxLengthList):
singleGates = pc.gatestring_list([(g,) for g in gateLabels])
lgstStrings = pc.list_lgst_gatestrings(pc.build_spam_specs(fiducialList), gateLabels)
lsgst_list = pc.gatestring_list([ () ]) #running list of all strings so far
if maxLengthList[0] == 0:
lsgst_listOfLists = [ lgstStrings ]
maxLengthList = maxLengthList[1:]
else: lsgst_listOfLists = [ ]
for maxLen in maxLengthList:
lsgst_list += pc.create_gatestring_list("f0+R(germ,N)+f1", f0=fiducialList,
f1=fiducialList, germ=germList, N=maxLen,
R=pc.repeat_with_max_length,
order=('germ','f0','f1'))
lsgst_listOfLists.append( pygsti.remove_duplicates(lgstStrings + lsgst_list) )
print "%d LSGST sets w/lengths" % len(lsgst_listOfLists),map(len,lsgst_listOfLists)
return lsgst_listOfLists
def make_elgst_lists(gateLabels, fiducialList, germList, maxLengthList):
singleGates = pc.gatestring_list([(g,) for g in gateLabels])
lgstStrings = pc.list_lgst_gatestrings(pc.build_spam_specs(fiducialList), gateLabels)
elgst_list = pc.gatestring_list([ () ]) #running list of all strings so far
if maxLengthList[0] == 0:
elgst_listOfLists = [ singleGates ]
maxLengthList = maxLengthList[1:]
else: elgst_listOfLists = [ ]
for maxLen in maxLengthList:
elgst_list += pc.create_gatestring_list("R(germ,N)", germ=germList, N=maxLen,
R=pc.repeat_with_max_length)
elgst_listOfLists.append( pygsti.remove_duplicates(singleGates + elgst_list) )
print "%d eLGST sets w/lengths" % len(elgst_listOfLists),map(len,elgst_listOfLists)
return elgst_listOfLists
#We'll now use this function to generate some lists we'll use in other tutorials
gates = ['Gi','Gx','Gy']
fiducials = pc.gatestring_list([ (), ('Gx',), ('Gy',), ('Gx','Gx'), ('Gx','Gx','Gx'), ('Gy','Gy','Gy') ]) # fiducials for 1Q MUB
germs = pc.gatestring_list( [('Gx',), ('Gy',), ('Gi',), ('Gx', 'Gy',),
('Gx', 'Gy', 'Gi',), ('Gx', 'Gi', 'Gy',),('Gx', 'Gi', 'Gi',), ('Gy', 'Gi', 'Gi',),
('Gx', 'Gx', 'Gi', 'Gy',), ('Gx', 'Gy', 'Gy', 'Gi',),
('Gx', 'Gx', 'Gy', 'Gx', 'Gy', 'Gy',)] )
maxLengths = [0,1,2,4,8,16,32,64,128,256]
elgst_lists = make_elgst_lists(gates, fiducials, germs, maxLengths)
lsgst_lists = make_lsgst_lists(gates, fiducials, germs, maxLengths)
print "\nFirst 20 items for dataset generation in label : string format"
for gateString in lsgst_lists[-1][0:30]:
print str(gateString), ": ", tuple(gateString)
10 eLGST sets w/lengths [3, 4, 8, 18, 29, 40, 51, 62, 73, 84] 10 LSGST sets w/lengths [92, 92, 168, 441, 817, 1201, 1585, 1969, 2353, 2737] First 20 items for dataset generation in label : string format {} : () Gx : ('Gx',) Gy : ('Gy',) GxGx : ('Gx', 'Gx') GxGxGx : ('Gx', 'Gx', 'Gx') GyGyGy : ('Gy', 'Gy', 'Gy') GxGy : ('Gx', 'Gy') GxGxGxGx : ('Gx', 'Gx', 'Gx', 'Gx') GxGyGyGy : ('Gx', 'Gy', 'Gy', 'Gy') GyGx : ('Gy', 'Gx') GyGy : ('Gy', 'Gy') GyGxGx : ('Gy', 'Gx', 'Gx') GyGxGxGx : ('Gy', 'Gx', 'Gx', 'Gx') GyGyGyGy : ('Gy', 'Gy', 'Gy', 'Gy') GxGxGy : ('Gx', 'Gx', 'Gy') GxGxGxGxGx : ('Gx', 'Gx', 'Gx', 'Gx', 'Gx') GxGxGyGyGy : ('Gx', 'Gx', 'Gy', 'Gy', 'Gy') GxGxGxGy : ('Gx', 'Gx', 'Gx', 'Gy') GxGxGxGxGxGx : ('Gx', 'Gx', 'Gx', 'Gx', 'Gx', 'Gx') GxGxGxGyGyGy : ('Gx', 'Gx', 'Gx', 'Gy', 'Gy', 'Gy') GyGyGyGx : ('Gy', 'Gy', 'Gy', 'Gx') GyGyGyGxGx : ('Gy', 'Gy', 'Gy', 'Gx', 'Gx') GyGyGyGxGxGx : ('Gy', 'Gy', 'Gy', 'Gx', 'Gx', 'Gx') GyGyGyGyGyGy : ('Gy', 'Gy', 'Gy', 'Gy', 'Gy', 'Gy') (Gi) : ('Gi',) (Gi)Gx : ('Gi', 'Gx') (Gi)Gy : ('Gi', 'Gy') (Gi)GxGx : ('Gi', 'Gx', 'Gx') (Gi)GxGxGx : ('Gi', 'Gx', 'Gx', 'Gx') (Gi)GyGyGy : ('Gi', 'Gy', 'Gy', 'Gy')
#Write example gatestring list files for later use
pygsti.io.write_gatestring_list("tutorial_files/Example_FiducialList.txt", fiducials,"#My fiducial strings")
pygsti.io.write_gatestring_list("tutorial_files/Example_GermsList.txt", germs,"#My germ strings")
pygsti.io.write_gatestring_list("tutorial_files/Example_GatestringList.txt",lsgst_lists[-1],"#All the gate strings to be in my dataset")
pygsti.io.write_empty_dataset("tutorial_files/Example_DatasetTemplate.txt",lsgst_lists[-1])
for l,lst in zip(maxLengths,elgst_lists):
pygsti.io.write_gatestring_list("tutorial_files/Example_eLGSTlist%d.txt" % l,lst,
"# eLGST gate strings for max length %d" % l)
for l,lst in zip(maxLengths,lsgst_lists):
pygsti.io.write_gatestring_list("tutorial_files/Example_LSGSTlist%d.txt" % l,lst,
"# LSGST gate strings for max length %d" % l)
#Also write the max lengths we used to file
import json
json.dump(maxLengths, open("tutorial_files/Example_maxLengths.json","w"))