Ejemplo n.º 1
0
 def check_out_symplectic(c, pspec, s, p, n):
     s0, p0 = symplectic.prep_stabilizer_state(n)
     sc, pc = symplectic.symplectic_rep_of_clifford_circuit(c,pspec=pspec)
     scout, pcout = symplectic.apply_clifford_to_stabilizer_state(sc,pc,s0,p0)
     stargetout, ptargetout = symplectic.apply_clifford_to_stabilizer_state(s,p,s0,p0)
     for i in range(n):
         mtout = symplectic.pauli_z_measurement(stargetout,ptargetout,i)
         mcout = symplectic.pauli_z_measurement(scout,pcout,i)
         self.assertArraysAlmostEqual(mtout[0],mcout[0])
Ejemplo n.º 2
0
 def test_compile_stabilizer_state(self):
     compiled = compilers.compile_stabilizer_state(
         self.fixture.clifford_sym, self.fixture.clifford_phase,
         **self.options)
     sym_0, phase_0 = symplectic.prep_stabilizer_state(self.fixture.n)
     sym_compiled, phase_compiled = symplectic.symplectic_rep_of_clifford_circuit(
         compiled, pspec=self.options.get('pspec', None))
     sym_out, phase_out = symplectic.apply_clifford_to_stabilizer_state(
         sym_compiled, phase_compiled, sym_0, phase_0)
     sym_target, phase_target = symplectic.apply_clifford_to_stabilizer_state(
         self.fixture.clifford_sym, self.fixture.clifford_phase, sym_0,
         phase_0)
     for i in range(self.fixture.n):
         self.assertArraysAlmostEqual(
             symplectic.pauli_z_measurement(sym_target, phase_target, i)[0],
             symplectic.pauli_z_measurement(sym_out, phase_out, i)[0])
Ejemplo n.º 3
0
    def test_compile_stabilizer_measurement(self):
        compiled = compilers.compile_stabilizer_measurement(
            self.fixture.clifford_sym, self.fixture.clifford_phase,
            **self.options)
        sym_compiled, phase_compiled = symplectic.symplectic_rep_of_clifford_circuit(
            compiled, pspec=self.options.get('pspec', None))
        sym_state, phase_state = symplectic.prep_stabilizer_state(
            self.fixture.n)
        sym_state, phase_state = symplectic.apply_clifford_to_stabilizer_state(
            self.fixture.clifford_sym, self.fixture.clifford_phase, sym_state,
            phase_state)
        sym_out, phase_out = symplectic.apply_clifford_to_stabilizer_state(
            sym_compiled, phase_compiled, sym_state, phase_state)

        # This asserts that a particular stabilizer propagation yields the expected result -
        #  the all-0 state.  This test preparation, acting-on, and measurment of stabilizer states.
        for i in range(self.fixture.n):
            self.assertAlmostEqual(
                symplectic.pauli_z_measurement(sym_out, phase_out, i)[1], 0.)
Ejemplo n.º 4
0
    def test_compilers(self):

        n = 10
        # Pick a random Clifford to compile
        s, p = symplectic.random_clifford(n)
        # Directly test the core algorithm
        c = compilers.compile_symplectic_using_GGE_core(s)
        sout, pout = symplectic.symplectic_rep_of_clifford_circuit(c)
        self.assertArraysEqual(s, sout)
        # Test accessing all the allowed algorithms, without a pspec or a subsetQs
        c = compilers.compile_symplectic(s,
                                         iterations=3,
                                         algorithms=['BGGE', 'ROGGE'])

        # Tests init a pspec with limited availability, and user-specified labels.
        n = 5
        qubit_labels = ['Q' + str(i) for i in range(n)]
        availability = {
            'Gcnot':
            [('Q' + str(i), 'Q' + str(i + 1)) for i in range(0, n - 1)]
        }
        gate_names = ['Gh', 'Gp', 'Gxpi', 'Gpdag', 'Gcnot']  # 'Gi',
        pspec = ProcessorSpec(n,
                              gate_names=gate_names,
                              availability=availability,
                              qubit_labels=qubit_labels)
        s, p = symplectic.random_clifford(n)
        # Test accessing all the allowed algorithms, with a pspec but no subsetQs
        c = compilers.compile_symplectic(s,
                                         pspec=pspec,
                                         iterations=3,
                                         algorithms=['BGGE', 'ROGGE'])

        # Test accessing all the allowed algorithms, with a pspec and a subsetQs
        n = 2
        s, p = symplectic.random_clifford(n)
        c = compilers.compile_symplectic(
            s,
            pspec=pspec,
            subsetQs=['Q2', 'Q3'],
            iterations=2,
            algorithms=['BGGE', 'ROGGE', 'iAGvGE'])
        sout, pout = symplectic.symplectic_rep_of_clifford_circuit(c,
                                                                   pspec=pspec)
        self.assertArraysEqual(s, sout)

        # Test the main function that we'll access -- compile_clifford
        n = 5
        s, p = symplectic.random_clifford(n)
        c = compilers.compile_clifford(s,
                                       p,
                                       pspec=pspec,
                                       subsetQs=None,
                                       iterations=2,
                                       algorithm='ROGGE',
                                       prefixpaulis=True,
                                       paulirandomize=True)
        sout, pout = symplectic.symplectic_rep_of_clifford_circuit(c,
                                                                   pspec=pspec)
        self.assertArraysEqual(s, sout)
        c = compilers.compile_clifford(s,
                                       p,
                                       pspec=None,
                                       subsetQs=None,
                                       iterations=2,
                                       algorithm='ROGGE')
        sout, pout = symplectic.symplectic_rep_of_clifford_circuit(c,
                                                                   pspec=pspec)
        self.assertArraysEqual(s, sout)

        n = 2
        s, p = symplectic.random_clifford(n)
        c = compilers.compile_clifford(s,
                                       p,
                                       pspec=pspec,
                                       subsetQs=['Q2', 'Q3'],
                                       iterations=2,
                                       algorithm='ROGGE',
                                       prefixpaulis=True,
                                       paulirandomize=True)
        sout, pout = symplectic.symplectic_rep_of_clifford_circuit(c,
                                                                   pspec=pspec)
        self.assertArraysEqual(s, sout)
        c = compilers.compile_clifford(s,
                                       p,
                                       pspec=pspec,
                                       subsetQs=['Q2', 'Q3'],
                                       iterations=2,
                                       algorithm='BGGE',
                                       prefixpaulis=True,
                                       paulirandomize=True)
        sout, pout = symplectic.symplectic_rep_of_clifford_circuit(c,
                                                                   pspec=pspec)
        self.assertArraysEqual(s, sout)
        c = compilers.compile_clifford(s,
                                       p,
                                       pspec=pspec,
                                       subsetQs=['Q2', 'Q3'],
                                       iterations=2,
                                       algorithm='iAGvGE',
                                       prefixpaulis=True,
                                       paulirandomize=False)
        sout, pout = symplectic.symplectic_rep_of_clifford_circuit(c,
                                                                   pspec=pspec)
        self.assertArraysEqual(s, sout)

        # Check it works for the 1-qubit case.
        n = 1
        # Pick a random Clifford to compile
        s, p = symplectic.random_clifford(1)
        c = compilers.compile_clifford(s, p)
        sout, pout = symplectic.symplectic_rep_of_clifford_circuit(c)
        c = compilers.compile_clifford(s,
                                       p,
                                       pspec=pspec,
                                       subsetQs=['Q3'],
                                       iterations=2,
                                       algorithm='ROGGE',
                                       prefixpaulis=False,
                                       paulirandomize=True)
        sout, pout = symplectic.symplectic_rep_of_clifford_circuit(c,
                                                                   pspec=pspec)
        self.assertArraysEqual(s, sout)

        # Tests all CNOT compiler algorithms
        n = 8
        qubit_labels = ['Q' + str(i) for i in range(n)]
        availability = {
            'Gcnot':
            [('Q' + str(i), 'Q' + str(i + 1)) for i in range(0, n - 1)] + [
                ('Q0', 'Q2'),
            ]
        }
        gate_names = ['Gh', 'Gp', 'Gxpi', 'Gpdag', 'Gcnot']  # 'Gi',
        pspec8 = ProcessorSpec(n,
                               gate_names=gate_names,
                               availability=availability,
                               qubit_labels=qubit_labels)
        n = 6
        qubit_labels = ['Q' + str(i) for i in range(n)]
        availability = {
            'Gcphase':
            [('Q' + str(i), 'Q' + str(i + 1))
             for i in range(0, n - 1)] + [('Q' + str(n - 1), 'Q' + str(0))]
        }
        gate_names = ['Gh', 'Gxpi2', 'Gp', 'Gcphase']  # 'Gi',
        pspec6 = ProcessorSpec(n,
                               gate_names=gate_names,
                               availability=availability,
                               qubit_labels=qubit_labels)

        nsubset = 6
        circuit = []
        for i in range(100):
            a = np.random.randint(nsubset)
            b = np.random.randint(nsubset)
            if a != b:
                circuit.append(Label('CNOT', ('Q' + str(a), 'Q' + str(b))))

                subsetQs = ['Q' + str(i) for i in range(nsubset)]
        circuit = Circuit(layer_labels=circuit, line_labels=subsetQs)
        s, p = pygsti.tools.symplectic.symplectic_rep_of_clifford_circuit(
            circuit)

        aargs = {}
        aargs['COCAGE'] = []
        aargs['COiCAGE'] = []
        aargs['OCAGE'] = [
            ['Q1', 'Q0', 'Q2', 'Q5', 'Q3', 'Q4'],
        ]
        # This ordering must be a 'contraction' of the graph, with the remaining graph always connected.
        aargs['OiCAGE'] = [
            ['Q0', 'Q1', 'Q2', 'Q5', 'Q3', 'Q4'],
        ]
        aargs['ROCAGE'] = []
        for algorithm in ['COiCAGE', 'OiCAGE', 'COCAGE', 'ROCAGE']:
            c = compilers.compile_cnot_circuit(s,
                                               pspec6,
                                               algorithm=algorithm,
                                               subsetQs=None,
                                               aargs=aargs[algorithm])
            c = compilers.compile_cnot_circuit(s,
                                               pspec8,
                                               algorithm=algorithm,
                                               subsetQs=subsetQs,
                                               aargs=aargs[algorithm])

        # Tests stabilizer state and measurement functions.

        # Tests the stabilizer compilers for n = 1
        n = 1
        pspec1 = ProcessorSpec(
            nQubits=n,
            gate_names=['Gcnot', 'Gh', 'Gp', 'Gxpi', 'Gypi', 'Gzpi'])  # 'Gi',
        s, p = symplectic.random_clifford(n)
        c = compilers.compile_stabilizer_state(s,
                                               p,
                                               pspec1,
                                               algorithm='COCAGE',
                                               paulirandomize=False)
        c = compilers.compile_stabilizer_measurement(s,
                                                     p,
                                                     pspec1,
                                                     algorithm='ROCAGE',
                                                     paulirandomize=True)
        c = compilers.compile_stabilizer_measurement(s,
                                                     p,
                                                     pspec6,
                                                     subsetQs=[
                                                         'Q3',
                                                     ],
                                                     algorithm='COiCAGE',
                                                     paulirandomize=False)

        def check_out_symplectic(c, pspec, s, p, n):
            s0, p0 = symplectic.prep_stabilizer_state(n)
            sc, pc = symplectic.symplectic_rep_of_clifford_circuit(c,
                                                                   pspec=pspec)
            scout, pcout = symplectic.apply_clifford_to_stabilizer_state(
                sc, pc, s0, p0)
            stargetout, ptargetout = symplectic.apply_clifford_to_stabilizer_state(
                s, p, s0, p0)
            for i in range(n):
                mtout = symplectic.pauli_z_measurement(stargetout, ptargetout,
                                                       i)
                mcout = symplectic.pauli_z_measurement(scout, pcout, i)
                self.assertArraysAlmostEqual(mtout[0], mcout[0])

        n = 6
        s, p = symplectic.random_clifford(n)
        c = compilers.compile_stabilizer_state(s,
                                               p,
                                               pspec6,
                                               algorithm='ROCAGE',
                                               paulirandomize=False)
        check_out_symplectic(c, pspec6, s, p, n)

        s, p = symplectic.random_clifford(n)
        c = compilers.compile_stabilizer_state(s,
                                               p,
                                               pspec6,
                                               algorithm='COiCAGE',
                                               paulirandomize=True)
        check_out_symplectic(c, pspec6, s, p, n)

        s, p = symplectic.random_clifford(3)
        c = compilers.compile_stabilizer_measurement(
            s,
            p,
            pspec6,
            subsetQs=['Q3', 'Q4', 'Q5'],
            algorithm='COiCAGE',
            paulirandomize=False)
        sc, pc = symplectic.symplectic_rep_of_clifford_circuit(c, pspec=pspec6)
        # The state the c should map to |0,0,0,....>.
        sstate, pstate = symplectic.prep_stabilizer_state(3)
        sstate, pstate = symplectic.apply_clifford_to_stabilizer_state(
            s, p, sstate, pstate)
        sout, pout = symplectic.apply_clifford_to_stabilizer_state(
            sc, pc, sstate, pstate)
        for i in range(3):
            mtout = symplectic.pauli_z_measurement(sout, pout, i)
            self.assertArraysAlmostEqual(mtout[1], 0.)

        s, p = symplectic.random_clifford(n)
        c1 = compilers.compile_stabilizer_state(s,
                                                p,
                                                pspec6,
                                                algorithm='COiCAGE',
                                                paulirandomize=False)
        c2 = compilers.compile_stabilizer_measurement(s,
                                                      p,
                                                      pspec6,
                                                      algorithm='COiCAGE',
                                                      paulirandomize=True)
        c2 = c2.copy(editable=True)
        c2.prefix_circuit(c1)
        zerosstate_s, zerosstate_p = symplectic.prep_stabilizer_state(n)
        sc, pc = symplectic.symplectic_rep_of_clifford_circuit(c2,
                                                               pspec=pspec6)
        scout, pcout = symplectic.apply_clifford_to_stabilizer_state(
            sc, pc, zerosstate_s, zerosstate_p)
        for i in range(n):
            mtout = symplectic.pauli_z_measurement(scout, pcout, i)
            self.assertArraysAlmostEqual(mtout[1], 0.)
Ejemplo n.º 5
0
def oneshot_circuit_simulator_for_tensored_independent_pauli_errors(circuit, pspec, errormodel, idle1q_placeholder='I'):
    """
    Generates a single measurement result for the `circuit_simulator_for_tensored_independent_pauli_errors()`
    simulator

    Parameters
    ----------
    circuit : Circuit
        The circuit to simulate. It should only contain gates that are also contained  within the provided
        QubitProcessorSpec `pspec` and are Clifford gates.

    pspec : QubitProcessorSpec
        The QubitProcessorSpec that defines the device. The Clifford model in QubitProcessorSpec should contain all of
        the gates that are in the circuit.

    errormodel : dict
        A dictionary defining the error model. This errormodel should have keys that are Label objects (the
        elements of the circuit). The values for a particular Label is an (n,4) numpy array of floats, that
        encodes the errors caused by the gate specified by that Label. The (i,j) value in the array is the
        probability that this gate is followed by Pauli i where Pauli 0 = identity, Pauli 1 = X, Pauli 2 = Y
        and Pauli 3 = Z. So, if the arrray is [1.,0.,0.,0.] in every row then there is no errors, if it is
        [1-p,p/3,p/3,p/3] in row j then there is equal probability of each Pauli error on qubit j with an
        error probability of p.

    TODO: docstring: idle1q_placeholder

    Returns
    -------
    tuple
        A tuple of values that are 0 or 1, corresponding to the results of a z-measurement on all the qubits.
        The ordering of this tuple corresponds to the ordering of the wires in the circuit.
    """
    n = circuit.number_of_lines
    depth = circuit.depth
    sout, pout = _symp.prep_stabilizer_state(n, zvals=None)
    srep = pspec.models['clifford'].compute_clifford_symplectic_reps()
    I = _np.identity(2 * n, int)

    for l in range(depth):

        layer = circuit.layer_with_idles(l, idle_gate_name=idle1q_placeholder)
        s, p = _symp.symplectic_rep_of_clifford_layer(layer, n, q_labels=circuit.line_labels, srep_dict=srep)
        # Apply the perfect layer to the current state.
        sout, pout = _symp.apply_clifford_to_stabilizer_state(s, p, sout, pout)

        # Consider each gate in the layer, and apply Pauli errors with the relevant probs.
        for gate in layer:
            # Sample a pauli vector for the gate
            gerror_p = _np.zeros(2 * n, int)
            sampledvec = _np.array([list(_np.random.multinomial(1, pp)) for pp in errormodel[gate]])
            # Z and Y both map X - > -X under conjugation, which is encoded with the upper half of
            # the p vector being set to 2.
            gerror_p[:n] = 2 * (sampledvec[:, 3] ^ sampledvec[:, 2])
            # X and Y both map Z - > -Z under conjugation, which is encoded with the lower half of
            # the p vector being set to 2.
            gerror_p[n:] = 2 * (sampledvec[:, 1] ^ sampledvec[:, 2])

            sout, pout = _symp.apply_clifford_to_stabilizer_state(I, gerror_p, sout, pout)

    output = []
    for q in range(n):
        measurement_out = _symp.pauli_z_measurement(sout, pout, q)
        # The probability of the '1' outcome
        oneprob = measurement_out[1]
        # Sample a bit with that probability to be 1.
        bit = _np.random.binomial(1, oneprob)
        output.append(bit)

    # Add measurement errors, by bit-flipping with some probability
    try:
        measurement_errors = errormodel['measure']
    except:
        measurement_errors = [0 for i in range(n)]

    add_to_outcome = _np.array([_np.random.binomial(1, p) for p in measurement_errors])
    output = tuple(_np.array(output) ^ add_to_outcome)
    outputasstring = ''
    for s in output: outputasstring += str(s)
    return outputasstring