Exemple #1
0
    def test_processorspec(self):

        # Tests init a pspec using standard gatenames, and all standards.
        n = 3
        gate_names = ['Gh', 'Gp', 'Gxpi', 'Gypi', 'Gzpi', 'Gpdag',
                      'Gcphase']  # 'Gi',
        ps = ProcessorSpec(n, gate_names=gate_names)

        # Tests init a pspec containing 1 qubit (as special case which could break)
        n = 1
        gate_names = ['Gh', 'Gp', 'Gxpi', 'Gypi', 'Gzpi', 'Gpdag',
                      'Gcphase']  # 'Gi',
        ps = ProcessorSpec(n, gate_names=gate_names)
Exemple #2
0
    def setUpClass(cls):
        super(RBSampleTester, cls).setUpClass()
        glist = ['Gxpi2', 'Gypi2', 'Gcnot']  # 'Gi',
        cls.pspec_1 = ProcessorSpec(4, glist, verbosity=0, qubit_labels=['Q0', 'Q1', 'Q2', 'Q3'])

        # # XXX this takes nearly a minute to construct on my machine....
        # glist = ['Gxpi', 'Gypi', 'Gzpi', 'Gh', 'Gp', 'Gcphase']  # 'Gi',
        # availability = {'Gcphase': [(0, 1), (1, 2)]}
        # cls.pspec_2 = ProcessorSpec(3, glist, availability=availability, verbosity=0)

        # XXX is this an OK test fixture? see above.
        glist = ['Gxpi2', 'Gypi2', 'Gcphase']  # 'Gi',
        availability = {'Gcphase': [(0, 1), (1, 2)]}
        cls.pspec_2 = ProcessorSpec(3, glist, availability=availability, verbosity=0)

        glist = ['Gxpi2', 'Gxmpi2', 'Gypi2', 'Gympi2', 'Gcnot']  # 'Gi',
        cls.pspec_inv = ProcessorSpec(4, glist, verbosity=0, qubit_labels=['Q0', 'Q1', 'Q2', 'Q3'])
Exemple #3
0
    def test_simulate(self):
        # TODO optimize
        # Create a pspec, to test the circuit simulator.
        n = 4
        qubit_labels = ['Q' + str(i) for i in range(n)]
        gate_names = ['Gh', 'Gp', 'Gxpi', 'Gpdag', 'Gcnot']  # 'Gi',
        ps = ProcessorSpec(n, gate_names=gate_names, qubit_labels=qubit_labels)

        # Tests the circuit simulator
        c = circuit.Circuit(
            layer_labels=[Label('Gh', 'Q0'),
                          Label('Gcnot', ('Q0', 'Q1'))],
            line_labels=['Q0', 'Q1'])
        out = c.simulate(ps.models['target'])
        self.assertLess(abs(out['00'] - 0.5), 10**-10)
        self.assertLess(abs(out['11'] - 0.5), 10**-10)
Exemple #4
0
    def test_circuit(self):

        # Test initializing a circuit from an empty gatestring.
        c = pygsti.obj.Circuit(num_lines=5)
        self.assertEqual(c.depth(), 0)
        self.assertEqual(c.size(), 0)
        self.assertEqual(c.number_of_lines(), 5)
        self.assertEqual(c.line_labels, list(range(5)))

        c = pygsti.obj.Circuit(gatestring=[], num_lines=5)
        self.assertEqual(c.depth(), 0)
        self.assertEqual(c.size(), 0)
        self.assertEqual(c.number_of_lines(), 5)
        self.assertEqual(c.line_labels, list(range(5)))

        # Test initializing a circuit from a non-empty gatestring that is a list
        # containing Label objects. Also test that it can have non-integer line_labels
        # and a different identity identifier.
        gatestring = [Label('Gi', 'Q0'), Label('Gp', 'Q8')]
        c = pygsti.obj.Circuit(gatestring=gatestring,
                               line_labels=['Q0', 'Q1', 'Q8', 'Q12'],
                               identity='idle')
        # Not parallelized by default, so will be depth 2.
        self.assertEqual(c.depth(), 2)
        self.assertEqual(c.size(), 2)
        self.assertEqual(c.number_of_lines(), 4)
        self.assertEqual(c.line_labels, ['Q0', 'Q1', 'Q8', 'Q12'])

        # Do again with parallelization
        c = pygsti.obj.Circuit(gatestring=gatestring,
                               line_labels=['Q0', 'Q1', 'Q8'],
                               parallelize=True)
        self.assertEqual(c.depth(), 1)
        self.assertEqual(c.size(), 2)

        # Now repeat the read-in with no parallelize, but a list of lists of gatelabels
        gatestring = [[Label('Gi', 'Q0'), Label('Gp', 'Q8')],
                      [Label('Gh', 'Q1'),
                       Label('Gp', 'Q12')]]
        c = pygsti.obj.Circuit(gatestring=gatestring,
                               line_labels=['Q0', 'Q1', 'Q8', 'Q12'],
                               identity='id')
        self.assertLess(0, c.depth())

        # Check we can read-in a gatestring that has no qubit labels: enforces them to be on
        # all of the lines.
        gatestring = GateString(None, "Gx^2GyGxGi")
        c = pygsti.obj.Circuit(gatestring=gatestring, num_lines=1)
        self.assertEqual(c.depth(), 5)

        # Check that we can create a gatestring from a string and that we end up with
        # the correctly structured circuit.
        gatestring = GateString(None, "[Gx:Q0Gy:Q1]^2[Gy:Q0Gx:Q1]Gi:Q0Gi:Q1")
        c = pygsti.obj.Circuit(gatestring=gatestring,
                               parallelize=False,
                               line_labels=['Q0', 'Q1'])
        self.assertEqual(c.depth(), 5)
        self.assertEqual(c.size(), 8)

        # Check we can init from a line_items list of lists
        cnew = pygsti.obj.Circuit(c.line_items)
        self.assertEqual(cnew, c)

        with self.assertRaises(AssertionError):
            # Check can't give line_items and gatestring.
            c = pygsti.obj.Circuit(line_items=c.line_items,
                                   gatestring=gatestring)

        # Test copy() and clear()
        ccopy = c.copy()
        ccopy.clear()
        self.assertEqual(ccopy.size(), 0)
        self.assertEqual(c.size(), 8)

        # Test inserting a gate when the relevant qubits aren't
        # idling at that layer
        c.insert_gate(Label('Gx', 'Q0'), 2)
        self.assertEqual(c.size(), 9)
        self.assertEqual(c.depth(), 6)
        self.assertEqual(c.get_line('Q0')[2], Label('Gx', 'Q0'))

        # Test inserting a gate when the relevant qubits are
        # idling at that layer -- depth shouldn't increase
        c.insert_gate(Label('Gx', 'Q1'), 2)
        self.assertEqual(c.size(), 10)
        self.assertEqual(c.depth(), 6)
        self.assertEqual(c.get_line('Q1')[2], Label('Gx', 'Q1'))

        # Test layer insertion
        layer = [
            Label('Gx', 'Q1'),
        ]
        c.insert_layer(layer, 1)
        self.assertEqual(c.size(), 11)
        self.assertEqual(c.depth(), 7)
        self.assertEqual(c.get_layer(1), [
            Label('Gx', 'Q1'),
        ])
        c.insert_layer([], 1)
        self.assertTrue(c.lines_are_idle_at_layer(['Q0', 'Q1'], 1))
        self.assertTrue(c.lines_are_idle_at_layer(['Q0'], 2))
        self.assertFalse(c.lines_are_idle_at_layer(['Q1'], 2))
        self.assertFalse(c.is_idling_qubit('Q1'))
        c.insert_idling_wires(['Q0', 'Q1', 'Q3'])
        self.assertFalse(c.is_idling_qubit('Q0'))
        self.assertFalse(c.is_idling_qubit('Q1'))
        self.assertTrue(c.is_idling_qubit('Q3'))

        # Test replacing a layer with a layer.
        c = pygsti.obj.Circuit(gatestring=gatestring,
                               line_labels=['Q0', 'Q1'],
                               identity='id')
        newlayer = [Label('Gx', 'Q0')]
        c.replace_layer_with_layer(newlayer, 1)
        self.assertEqual(c.depth(), 5)

        # Test replacing a layer with a circuit
        c.replace_layer_with_circuit(c.copy(), 1)
        self.assertEqual(c.depth(), 2 * 5 - 1)

        # Test layer deletion
        ccopy = c.copy()
        ccopy.insert_layer(layer, 1)
        ccopy.delete_layer(1)
        self.assertEqual(c, ccopy)

        # Test inserting a circuit when they are over the same labels.
        gatestring = GateString(None, "[Gx:Q0Gy:Q1][Gy:Q0Gx:Q1]Gx:Q0Giz:Q1")
        c = pygsti.obj.Circuit(gatestring=gatestring,
                               parallelize=False,
                               line_labels=['Q0', 'Q1'])
        ccopy = c.copy()
        c.insert_circuit(ccopy, 2)
        self.assertTrue(Label('Gx', 'Q0') in c.get_layer(2))

        # Test insert a circuit that is over *more* qubits but which has the additional
        # lines idling.
        c1 = pygsti.obj.Circuit(gatestring=gatestring,
                                line_labels=['Q0', 'Q1'])
        c2 = pygsti.obj.Circuit(gatestring=gatestring,
                                line_labels=['Q0', 'Q1', 'Q2', 'Q3'])
        c1.insert_circuit(c2, 0)
        self.assertEqual(c1.line_labels, ['Q0', 'Q1'])
        self.assertEqual(c1.number_of_lines(), 2)

        # Test inserting a circuit that is on *less* qubits.
        c1 = pygsti.obj.Circuit(gatestring=gatestring,
                                line_labels=['Q0', 'Q1'],
                                identity='id')
        c2 = pygsti.obj.Circuit(gatestring=[Label('Gx', 'Q0')],
                                line_labels=[
                                    'Q0',
                                ])
        c1.insert_circuit(c2, 1)
        self.assertEqual(c1.line_labels, ['Q0', 'Q1'])
        self.assertEqual(c1.number_of_lines(), 2)

        # Test appending and prefixing a circuit
        c1 = pygsti.obj.Circuit(gatestring=gatestring,
                                line_labels=['Q0', 'Q1'],
                                identity='id')
        c2 = pygsti.obj.Circuit(gatestring=[Label('Gx', 'Q0')],
                                line_labels=[
                                    'Q0',
                                ])
        c1.append_circuit(c2)
        c1.prefix_circuit(c2)

        # Test tensoring circuits of same length
        gatestring1 = GateString(None, "[Gx:Q0Gy:Q1]^2[Gy:Q0Gx:Q1]Gi:Q0Gi:Q1")
        gatestring2 = GateString(None, "[Gx:Q2Gy:Q3]^2[Gy:Q2Gx:Q3]Gi:Q2Gi:Q3")
        c1 = pygsti.obj.Circuit(gatestring=gatestring1,
                                line_labels=['Q0', 'Q1'])
        c2 = pygsti.obj.Circuit(gatestring=gatestring2,
                                line_labels=['Q2', 'Q3'])
        c1.tensor_circuit(c2)
        self.assertEqual(c1.depth(), max(c1.depth(), c2.depth()))
        self.assertEqual(c1.line_items[2], c2.line_items[0])

        # Test tensoring circuits where the inserted circuit is shorter
        gatestring1 = GateString(None,
                                 "[Gx:Q0Gy:Q1]^2[Gy:Q0Gx:Q1]Gi:Q0Gi:Q1Gy:Q0")
        gatestring2 = GateString(None, "[Gx:Q2Gy:Q3]^2[Gy:Q2Gx:Q3]Gi:Q2Gi:Q3")
        c1 = pygsti.obj.Circuit(gatestring=gatestring1,
                                line_labels=['Q0', 'Q1'])
        c2 = pygsti.obj.Circuit(gatestring=gatestring2,
                                line_labels=['Q2', 'Q3'])
        c1.tensor_circuit(c2, line_order=['Q1', 'Q3', 'Q0', 'Q2'])
        self.assertEqual(c1.depth(), max(c1.depth(), c2.depth()))

        # Test tensoring circuits where the inserted circuit is longer
        gatestring1 = GateString(None, "[Gx:Q0Gy:Q1]^2[Gy:Q0Gx:Q1]Gi:Q0Gi:Q1")
        gatestring2 = GateString(None,
                                 "[Gx:Q2Gy:Q3]^2[Gy:Q2Gx:Q3]Gi:Q2Gi:Q3Gy:Q2")
        c1 = pygsti.obj.Circuit(gatestring=gatestring1,
                                line_labels=['Q0', 'Q1'])
        c2 = pygsti.obj.Circuit(gatestring=gatestring2,
                                line_labels=['Q2', 'Q3'])
        c1.tensor_circuit(c2)
        self.assertEqual(c1.depth(), max(c1.depth(), c2.depth()))

        # Test changing a gate name
        gatestring = GateString(None, "[Gx:Q0Gy:Q1][Gy:Q0Gx:Q1]Gx:Q0Gi:Q1")
        c = pygsti.obj.Circuit(gatestring=gatestring,
                               line_labels=['Q0', 'Q1'],
                               identity='Gi')
        c.replace_gatename('Gx', 'Gz')
        gatestring = GateString(None, "[Gz:Q0Gy:Q1][Gy:Q0Gz:Q1]Gz:Q0Gi:Q1")
        c2 = pygsti.obj.Circuit(gatestring=gatestring,
                                parallelize=False,
                                line_labels=['Q0', 'Q1'],
                                identity='Gi')
        self.assertEqual(c, c2)

        # Change gate library using an ordinary dict with every gate as a key. (we test
        # changing gate library using a CompilationLibrary elsewhere in the tests).
        comp = {}
        comp[Label('Gz',
                   'Q0')] = pygsti.obj.Circuit(gatestring=[Label('Gx', 'Q0')],
                                               line_labels=['Q0'])
        comp[Label('Gy',
                   'Q0')] = pygsti.obj.Circuit(gatestring=[Label('Gx', 'Q0')],
                                               line_labels=['Q0'])
        comp[Label('Gz',
                   'Q1')] = pygsti.obj.Circuit(gatestring=[Label('Gx', 'Q1')],
                                               line_labels=['Q1'])
        comp[Label('Gy',
                   'Q1')] = pygsti.obj.Circuit(gatestring=[Label('Gx', 'Q1')],
                                               line_labels=['Q1'])
        c.change_gate_library(comp)
        self.assertTrue(Label('Gx', 'Q0') in c.get_layer(0))

        # Change gate library using a dict with some gates missing
        comp = {}
        comp[Label('Gz',
                   'Q0')] = pygsti.obj.Circuit(gatestring=[Label('Gx', 'Q0')],
                                               line_labels=['Q0'])
        c = pygsti.obj.Circuit(gatestring=gatestring,
                               line_labels=['Q0', 'Q1'],
                               identity='Gi')
        c.change_gate_library(comp, allow_unchanged_gates=True)
        self.assertTrue(Label('Gx', 'Q0') in c.get_layer(0))
        self.assertTrue(Label('Gy', 'Q1') in c.get_layer(0))

        # Test we can change the labels of the lines.
        c.map_state_space_labels({'Q0': 0, 'Q1': 1})
        self.assertEqual(c.line_labels, [0, 1])
        self.assertEqual(c.get_line(0)[0].qubits[0], 0)

        # Check we can re-order wires
        c.reorder_wires([1, 0])
        self.assertEqual(c.line_labels, [1, 0])
        # Can't use .get_line as that takes the line label as i_nput.
        self.assertEqual(c.line_items[0][0].qubits[0], 1)

        # Test deleting and inserting idling wires.
        c = pygsti.obj.Circuit(gatestring=gatestring,
                               line_labels=['Q0', 'Q1'],
                               identity='Gi')
        c.insert_idling_wires(['Q0', 'Q1', 'Q2'])
        self.assertEqual(c.line_labels, ['Q0', 'Q1', 'Q2'])
        self.assertEqual(c.number_of_lines(), 3)
        c.delete_idling_wires()
        self.assertEqual(c.line_labels, ['Q0', 'Q1'])
        self.assertEqual(c.number_of_lines(), 2)

        # Test circuit reverse.
        gate1 = c.get_line('Q0')[0]
        c.reverse()
        gate2 = c.get_line('Q0')[-1]
        self.assertEqual(gate1, gate2)

        # Test 2-qubit and multi-qubit gate count
        self.assertEqual(c.twoQgate_count(), 0)
        gatestring = GateString(None, "[Gcnot:Q0:Q1]^2[Gy:Q0Gx:Q1]Gi:Q0Gi:Q1")
        c = pygsti.obj.Circuit(gatestring=gatestring,
                               parallelize=False,
                               line_labels=['Q0', 'Q1'])
        self.assertEqual(c.twoQgate_count(), 2)
        self.assertEqual(c.multiQgate_count(), 2)
        gatestring = GateString(None,
                                "[Gccnot:Q0:Q1:Q2]^2[Gccnot:Q0:Q1]Gi:Q0Gi:Q1")
        c = pygsti.obj.Circuit(gatestring=gatestring,
                               parallelize=False,
                               line_labels=['Q0', 'Q1', 'Q2'])
        self.assertEqual(c.twoQgate_count(), 1)
        self.assertEqual(c.multiQgate_count(), 3)

        # Test the error-probability prediction method
        gatestring = GateString(None, "[Gx:Q0][Gi:Q0Gi:Q1]")
        c = pygsti.obj.Circuit(gatestring=gatestring,
                               parallelize=False,
                               line_labels=['Q0', 'Q1'],
                               identity='Gi')
        infidelity_dict = {}
        infidelity_dict[Label('Gi', 'Q0')] = 0.7
        infidelity_dict[Label('Gi', 'Q1')] = 0.9
        infidelity_dict[Label('Gx', 'Q0')] = 0.8
        infidelity_dict[Label('Gx', 'Q2')] = 0.9
        epsilon = c.predicted_error_probability(infidelity_dict)
        self.assertLess(
            abs(epsilon - (1 - (1 - 0.7) * (1 - 0.8) * (1 - 0.9)**2)), 10**-10)

        # Check we can succesfully create a circuit string.
        s = c.__str__()

        # Check we can write to a Qcircuit file.
        c.write_Qcircuit_tex(temp_files + '/test_qcircuit.tex')

        # Test depth compression both with and without 1-qubit gate compression
        ls = [
            Label('H', 1),
            Label('P', 1),
            Label('P', 1),
            Label('I', 1),
            Label('CNOT', (2, 3))
        ]
        ls += [Label('HP', 1), Label('PH', 1), Label('CNOT', (1, 2))]
        ls += [Label('I', 1), Label('I', 2), Label('CNOT', (1, 2))]
        gatestring = GateString(ls)
        c = pygsti.obj.Circuit(gatestring=gatestring, num_lines=4)
        c.compress_depth(verbosity=0)
        self.assertEqual(c.depth(), 7)
        # Gate a dictionary that relates H, P gates etc.
        oneQrelations = pygsti.symplectic.oneQclifford_symplectic_group_relations(
        )
        c.compress_depth(oneQgate_relations=oneQrelations)
        self.assertEqual(c.depth(), 3)

        # Test the is_valid_circuit checker.
        c.is_valid_circuit()
        with self.assertRaises(AssertionError):
            c.line_items[0][2] = Label('CNOT', (2, 3))
            c.is_valid_circuit()
            fail = False

        # Check that convert_to_quil runs, doesn't check the output makes sense.
        gatestring = [
            Label(('Gi', 'Q1')),
            Label(('Gxpi', 'Q1')),
            Label('Gcnot', ('Q1', 'Q2'))
        ]
        c = Circuit(gatestring=gatestring,
                    line_labels=['Q1', 'Q2'],
                    identity='Gi')
        s = c.convert_to_quil()

        # Check done_editing makes the circuit static.
        c.done_editing()
        with self.assertRaises(AssertionError):
            c.clear()

        # Create a pspec, to test the circuit simulator.
        n = 4
        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 = ['Gi', 'Gh', 'Gp', 'Gxpi', 'Gpdag', 'Gcnot']
        ps = ProcessorSpec(n, gate_names=gate_names, qubit_labels=qubit_labels)

        # Tests the circuit simulator
        c = Circuit(
            gatestring=[Label('Gh', 'Q0'),
                        Label('Gcnot', ('Q0', 'Q1'))],
            line_labels=['Q0', 'Q1'],
            identity='Gi')
        out = c.simulate(ps.models['target'])
        self.assertLess(abs(out['00'] - 0.5), 10**-10)
        self.assertLess(abs(out['11'] - 0.5), 10**-10)
Exemple #5
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.)
Exemple #6
0
import numpy as np

from ..util import BaseCase, Namespace

from pygsti.objects import Circuit, ProcessorSpec, Label
from pygsti.tools import symplectic
from pygsti.algorithms import compilers

## Immutable test fixture data
fixture_1Q = Namespace(
    n=1,
    # arbitrary symplectic representation of a 1-qubit Clifford
    # (generated with `symplectic.random_clifford(1)`)
    clifford_sym=np.array([[1, 0], [0, 1]], dtype=np.int8),
    clifford_phase=np.array([0, 2]))
fixture_1Q.pspec = ProcessorSpec(
    nQubits=1, gate_names=['Gcnot', 'Gh', 'Gp', 'Gxpi', 'Gypi', 'Gzpi'])
fixture_2Q = Namespace(
    n=2,
    qubit_labels=['Q0', 'Q1'],
    availability={'Gcnot': [('Q0', 'Q1')]},
    gate_names=['Gh', 'Gp', 'Gxpi', 'Gpdag', 'Gcnot'],
    # generated as before:
    clifford_sym=np.array([[0, 1, 1, 1], [1, 0, 1, 1], [1, 0, 1, 0],
                           [0, 1, 0, 1]]),
    clifford_phase=np.array([2, 0, 1, 3]))
fixture_2Q.pspec = ProcessorSpec(fixture_2Q.n,
                                 gate_names=fixture_2Q.gate_names,
                                 availability=fixture_2Q.availability,
                                 qubit_labels=fixture_2Q.qubit_labels)
# Totally arbitrary CNOT circuit
fixture_2Q.cnot_circuit = Circuit(layer_labels=[