def make_lsgst_lists(opLabels, fiducialList, germList, maxLengthList): singleOps = pc.circuit_list([(g, ) for g in opLabels]) lgstStrings = pc.list_lgst_circuits(fiducialList, fiducialList, opLabels) lsgst_list = pc.circuit_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_circuit_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( lt.remove_duplicates(lgstStrings + lsgst_list)) print("%d LSGST sets w/lengths" % len(lsgst_listOfLists), map(len, lsgst_listOfLists)) return lsgst_listOfLists
def test_all(self): l = [1, 2, 2, 3] l2 = deepcopy(l) lt.remove_duplicates_in_place(l2) self.assertEqual(l2, [1, 2, 3]) self.assertEqual(l2, lt.remove_duplicates(l)) letters = list('ABCCA') self.assertEqual(lt.compute_occurrence_indices(letters), [0, 0, 0, 1, 1]) begin = ('A', 'B', 'C') self.assertEqual(lt.find_replace_tuple(begin, {'B': 'C'}), ('A', 'C', 'C'))
def test_remove_duplicates_in_place(self): l = [1, 2, 2, 3] l2 = deepcopy(l) lt.remove_duplicates_in_place(l2) self.assertEqual(l2, [1, 2, 3]) self.assertEqual(l2, lt.remove_duplicates(l))
def keys(self): """ The operation labels for which this object specifies noise. """ # Use remove_duplicates rather than set(.) to preserve ordering (but this is slower!) return _lt.remove_duplicates(_itertools.chain(*[modelnoise.keys() for modelnoise in self.opmodelnoises]))
def create_elgst_lists(op_label_src, germ_list, max_length_list, trunc_scheme="whole germ powers", nest=True, include_lgst=True): """ Create a set of circuit lists for eLGST based on germs and max-lengths Constructs a series (a list) of circuit lists used by the extended LGST (eLGST) algorithm. If `include_lgst == True` then the starting list is the list of length-1 operation label strings, otherwise the starting list is empty. For each nonzero element of max_length_list, call it L, a list of circuits is created with the form: Case: trunc_scheme == 'whole germ powers': pygsti.circuits.repeat_with_max_length(germ,L) Case: trunc_scheme == 'truncated germ powers': pygsti.circuits.repeat_and_truncate(germ,L) Case: trunc_scheme == 'length as exponent': germ^L If nest == True, the above list is iteratively *added* (w/duplicates removed) to the current list of circuits to form a final list for the given L. This results in successively larger lists, each of which contains all the elements of previous-L lists. If nest == False then the above list *is* the final list for the given L. Parameters ---------- op_label_src : list or Model List of operation labels to determine needed LGST strings. If a Model, then the model's gate and instrument labels are used. Only relevant when `include_lgst == True`. germ_list : list of Circuits List of the germ circuits. max_length_list : list of ints List of maximum lengths. A zero value in this list has special meaning, and corresponds to the length-1 operation label strings. trunc_scheme : str, optional Truncation scheme used to interpret what the list of maximum lengths means. If unsure, leave as default. Allowed values are: - 'whole germ powers' -- germs are repeated an integer number of times such that the length is less than or equal to the max. - 'truncated germ powers' -- repeated germ string is truncated to be exactly equal to the max (partial germ at end is ok). - 'length as exponent' -- max. length is instead interpreted as the germ exponent (the number of germ repetitions). nest : boolean, optional If True, the returned circuit lists are "nested", meaning that each successive list of circuits contains all the gate strings found in previous lists (and usually some additional new ones). If False, then the returned string list for maximum length == L contains *only* those circuits specified in the description above, and *not* those for previous values of L. include_lgst : boolean, optional If true, then the starting list (only applicable when `nest == True`) is the list of length-1 operation label strings rather than the empty list. This means that when `nest == True`, the length-1 sequences will be included in all the lists. Returns ------- list of (lists of Circuits) The i-th list corresponds to a circuit list containing repeated germs limited to length max_length_list[i]. If nest == True, then repeated germs limited to previous max-lengths are also included. Note that a "0" maximum-length corresponds to the gate label strings. """ from pygsti.processors.processorspec import QubitProcessorSpec as _QuditProcessorSpec from pygsti.models.model import OpModel as _OpModel if isinstance(op_label_src, _QuditProcessorSpec): opLabels = op_label_src.primitive_op_labels elif isinstance(op_label_src, _OpModel): opLabels = op_label_src.primitive_op_labels + op_label_src.primitive_instrument_labels else: opLabels = op_label_src singleOps = _gsc.to_circuits([(g, ) for g in opLabels]) #running list of all strings so far (length-1 strs or empty) elgst_list = singleOps[:] if include_lgst else _gsc.to_circuits([()]) elgst_listOfLists = [] # list of lists to return Rfn = _get_trunc_function(trunc_scheme) for maxLen in max_length_list: if maxLen == 0: #Special length-1 string case lst = singleOps[:] else: #Typical case of germs repeated to maxLen using Rfn lst = _gsc.create_circuits("R(germ,N)", germ=germ_list, N=maxLen, R=Rfn) if nest: elgst_list += lst # add new strings to running list elgst_listOfLists.append( _lt.remove_duplicates(singleOps + elgst_list)) else: elgst_listOfLists.append(_lt.remove_duplicates(lst)) #print "%d eLGST sets w/lengths" % len(elgst_listOfLists),map(len,elgst_listOfLists) return elgst_listOfLists
def _create_raw_lsgst_lists(op_label_src, prep_strs, effect_strs, germ_list, max_length_list, fid_pairs=None, trunc_scheme="whole germ powers", nest=True, keep_fraction=1, keep_seed=None, include_lgst=True, germ_length_limits=None): """ Create a set of circuit lists for LSGST based on germs and max-lengths. Constructs a series (a list) of circuit lists used by long-sequence GST (LSGST) algorithms. If `include_lgst == True` then the starting list is the list of LGST strings, otherwise the starting list is empty. For each nonzero element of max_length_list, call it L, a list of circuits is created with the form: Case: trunc_scheme == 'whole germ powers': prepStr + pygsti.circuits.repeat_with_max_length(germ,L) + effectStr Case: trunc_scheme == 'truncated germ powers': prepStr + pygsti.circuits.repeat_and_truncate(germ,L) + effectStr Case: trunc_scheme == 'length as exponent': prepStr + germ^L + effectStr If nest == True, the above list is iteratively *added* (w/duplicates removed) to the current list of circuits to form a final list for the given L. This results in successively larger lists, each of which contains all the elements of previous-L lists. If nest == False then the above list *is* the final list for the given L. Parameters ---------- op_label_src : list or Model List of operation labels to determine needed LGST strings. If a Model, then the model's gate and instrument labels are used. Only relevant when `include_lgst == True`. prep_strs : list of Circuits List of the preparation fiducial circuits, which follow state preparation. effect_strs : list of Circuits List of the measurement fiducial circuits, which precede measurement. germ_list : list of Circuits List of the germ circuits. max_length_list : list of ints List of maximum lengths. A zero value in this list has special meaning, and corresponds to the LGST sequences. fid_pairs : list of 2-tuples or dict, optional Specifies a subset of all fiducial string pairs (prepStr, effectStr) to be used in the circuit lists. If a list, each element of fid_pairs is a (iPrepStr, iEffectStr) 2-tuple of integers, each indexing a string within prep_strs and effect_strs, respectively, so that prepStr = prep_strs[iPrepStr] and effectStr = effect_strs[iEffectStr]. If a dictionary, keys are germs (elements of germ_list) and values are lists of 2-tuples specifying the pairs to use for that germ. trunc_scheme : str, optional Truncation scheme used to interpret what the list of maximum lengths means. If unsure, leave as default. Allowed values are: - 'whole germ powers' -- germs are repeated an integer number of times such that the length is less than or equal to the max. - 'truncated germ powers' -- repeated germ string is truncated to be exactly equal to the max (partial germ at end is ok). - 'length as exponent' -- max. length is instead interpreted as the germ exponent (the number of germ repetitions). nest : boolean, optional If True, the returned circuits lists are "nested", meaning that each successive list of circuits contains all the gate strings found in previous lists (and usually some additional new ones). If False, then the returned circuit list for maximum length == L contains *only* those circuits specified in the description above, and *not* those for previous values of L. keep_fraction : float, optional The fraction of fiducial pairs selected for each germ-power base string. The default includes all fiducial pairs. Note that for each germ-power the selected pairs are *different* random sets of all possible pairs (unlike fid_pairs, which specifies the *same* fiducial pairs for *all* same-germ base strings). If fid_pairs is used in conjuction with keep_fraction, the pairs specified by fid_pairs are always selected, and any additional pairs are randomly selected. keep_seed : int, optional The seed used for random fiducial pair selection (only relevant when keep_fraction < 1). include_lgst : boolean, optional If true, then the starting list (only applicable when `nest == True`) is the list of LGST strings rather than the empty list. This means that when `nest == True`, the LGST sequences will be included in all the lists. germ_length_limits : dict, optional A dictionary limiting the max-length values used for specific germs. Keys are germ sequences and values are integers. For example, if this argument is `{('Gx',): 4}` and `max_length_list = [1,2,4,8,16]`, then the germ `('Gx',)` is only repeated using max-lengths of 1, 2, and 4 (whereas other germs use all the values in `max_length_list`). Returns ------- list of (lists of Circuits) The i-th list corresponds to a circuit list containing repeated germs limited to length max_length_list[i]. If nest == True, then repeated germs limited to previous max-lengths are also included. Note that a "0" maximum-length corresponds to the LGST strings. """ if germ_length_limits is None: germ_length_limits = {} if nest and include_lgst and len( max_length_list) > 0 and max_length_list[0] == 0: _warnings.warn( "Setting the first element of a max-length list to zero" + " to ensure the inclusion of LGST sequences has been" + " replaced by the `include_lgst` parameter which" + " defaults to `True`. Thus, in most cases, you can" + " simply remove the leading 0 and start your" + " max-length list at 1 now." + "") # ensure circuit lists have computed their string reps so addition produces "nice" strings for printing [germ.str for germ in germ_list] [c.str for c in prep_strs] [c.str for c in effect_strs] from pygsti.processors.processorspec import QubitProcessorSpec as _QuditProcessorSpec from pygsti.models.model import OpModel as _OpModel if isinstance(op_label_src, _QuditProcessorSpec): opLabels = op_label_src.primitive_op_labels elif isinstance(op_label_src, _OpModel): opLabels = op_label_src.primitive_op_labels + op_label_src.primitive_instrument_labels else: opLabels = op_label_src lgst_list = _gsc.create_lgst_circuits(prep_strs, effect_strs, opLabels) if keep_fraction < 1.0: rndm = _rndm.RandomState(keep_seed) # ok if seed is None nPairs = len(prep_strs) * len(effect_strs) nPairsToKeep = int(round(float(keep_fraction) * nPairs)) else: rndm = None if isinstance(fid_pairs, dict) or hasattr(fid_pairs, "keys"): fiducialPairs = _collections.OrderedDict([(germ, [ (prep_strs[i], effect_strs[j]) for (i, j) in fid_pairs[germ] ]) for germ in germ_list]) fidPairDict = fid_pairs else: if fid_pairs is not None: # assume fid_pairs is a list fidPairDict = {germ: fid_pairs for germ in germ_list} lst = [(prep_strs[i], effect_strs[j]) for (i, j) in fid_pairs] else: fidPairDict = None lst = list(_itertools.product(prep_strs, effect_strs)) fiducialPairs = {germ: lst for germ in germ_list} #running list of all strings so far (LGST strings or empty) lsgst_list = lgst_list[:] if include_lgst else _gsc.to_circuits([()]) lsgst_listOfLists = [] # list of lists to return Rfn = _get_trunc_function(trunc_scheme) for maxLen in max_length_list: lst = [] if maxLen == 0: #Special LGST case lst += lgst_list[:] else: #Typical case of germs repeated to maxLen using Rfn for germ in germ_list: if maxLen > germ_length_limits.get(germ, 1e100): continue if rndm is None: fiducialPairsThisIter = fiducialPairs[germ] elif fidPairDict is not None: pair_indx_tups = fidPairDict[germ] remainingPairs = [(prep_strs[i], effect_strs[j]) for i in range(len(prep_strs)) for j in range(len(effect_strs)) if (i, j) not in pair_indx_tups] nPairsRemaining = len(remainingPairs) nPairsToChoose = nPairsToKeep - len(pair_indx_tups) nPairsToChoose = max(0, min(nPairsToChoose, nPairsRemaining)) assert (0 <= nPairsToChoose <= nPairsRemaining) # FUTURE: issue warnings when clipping nPairsToChoose? fiducialPairsThisIter = fiducialPairs[germ] + \ [remainingPairs[k] for k in sorted(rndm.choice(nPairsRemaining, nPairsToChoose, replace=False))] else: # rndm is not None and fidPairDict is None assert (nPairsToKeep <= nPairs ) # keep_fraction must be <= 1.0 fiducialPairsThisIter = \ [fiducialPairs[germ][k] for k in sorted(rndm.choice(nPairs, nPairsToKeep, replace=False))] lst += _gsc.create_circuits("f[0]+R(germ,N)+f[1]", f=fiducialPairsThisIter, germ=germ, N=maxLen, R=Rfn, order=('f', )) if nest: lsgst_list += lst # add new strings to running list lsgst_listOfLists.append(_lt.remove_duplicates(lsgst_list)) else: lsgst_listOfLists.append(_lt.remove_duplicates(lst)) #print "%d LSGST sets w/lengths" % len(lsgst_listOfLists),map(len,lsgst_listOfLists) return lsgst_listOfLists