Example #1
0
        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
Example #2
0
    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'))
Example #3
0
 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))
Example #4
0
 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]))
Example #5
0
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
Example #6
0
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