Example #1
0
def test_create_untimed_model():
    basis = (bases.general(2), )

    class SampleModel(Model):
        dim = 2

        @Model.gate()
        def rotate_y(self, qubit):
            return (ParametrizedOperation(lib.rotate_y, basis), )

        @Model.gate()
        def cphase(self, qubit_static, qubit_fluxed):
            return (lib.cphase(pi).at(qubit_static, qubit_fluxed), )

    sample_setup = Setup("""
    setup: []
    """)

    m = SampleModel(sample_setup)
    cnot = m.rotate_y('D0', angle=0.5*pi) + m.cphase('D0', 'D1') + \
           m.rotate_y('D0', angle=-0.5*pi)

    assert cnot.finalize().operation.ptm(basis * 2, basis * 2) == approx(
        Operation.from_sequence(
            lib.rotate_y(0.5 * pi).at(0),
            lib.cphase(pi).at(0, 1),
            lib.rotate_y(-0.5 * pi).at(0),
        ).ptm(basis * 2, basis * 2))
Example #2
0
def test_create_timed_model():
    basis = (bases.general(2), )

    class SampleModel(Model):
        dim = 2

        @Model.gate(duration=20)
        def rotate_y(self, qubit):
            return (
                self.wait(qubit, 10),
                ParametrizedOperation(lib.rotate_y, basis),
                self.wait(qubit, 10),
            )

        @Model.gate(duration='t_twoqubit')
        def cphase(self, qubit_static, qubit_fluxed):
            return (
                self.wait(qubit_static, 0.5 * self.p('t_twoqubit')),
                self.wait(qubit_fluxed, 0.5 * self.p('t_twoqubit')),
                lib.cphase(pi).at(qubit_static, qubit_fluxed),
                self.wait(qubit_static, 0.5 * self.p('t_twoqubit')),
                self.wait(qubit_fluxed, 0.5 * self.p('t_twoqubit')),
            )

        @Model.gate(duration=lambda qubit, setup: 600
                    if qubit == 'D0' else 400)
        def strange_duration_gate(self, qubit):
            return lib.rotate_y(pi)

        @staticmethod
        def _filter_wait_placeholders(operation):
            return Operation.from_sequence([
                unit for unit in operation.units()
                if not isinstance(unit.operation, WaitPlaceholder)
            ])

        def finalize(self, circuit, bases_in=None):
            return circuit.finalize([self._filter_wait_placeholders], bases_in)

    sample_setup = Setup("""
    setup:
    - t_twoqubit: 40
    """)

    m = SampleModel(sample_setup)
    cnot = m.rotate_y('D0', angle=0.5*pi) + m.cphase('D0', 'D1') + \
           m.rotate_y('D0', angle=-0.5*pi)
    cnot = m.finalize(cnot)

    assert cnot.operation.ptm(basis * 2, basis * 2) == approx(
        Operation.from_sequence(
            lib.rotate_y(0.5 * pi).at(0),
            lib.cphase(pi).at(0, 1),
            lib.rotate_y(-0.5 * pi).at(0),
        ).ptm(basis * 2, basis * 2))

    gate1 = m.strange_duration_gate('D0')
    assert gate1.duration == 600
    gate2 = m.strange_duration_gate('D1')
    assert gate2.duration == 400
Example #3
0
    def test_circuits_add(self):
        dim = 2
        orplus = lib.rotate_y(0.5 * pi)
        ocphase = lib.cphase(pi)
        orminus = lib.rotate_y(-0.5 * pi)
        grplus = Gate('Q0', dim, orplus)
        gcphase = Gate(('Q0', 'Q1'), dim, ocphase)
        grminus = Gate('Q0', dim, orminus)
        basis = (bases.general(2), ) * 2

        circuit = grplus + gcphase
        assert circuit.qubits == ['Q0', 'Q1']
        assert len(circuit.gates) == 2
        assert c_op(circuit).ptm(basis, basis) == approx(
            Operation.from_sequence(orplus.at(0),
                                    ocphase.at(0, 1)).ptm(basis, basis))

        circuit = circuit + grminus
        assert circuit.qubits == ['Q0', 'Q1']
        assert len(circuit.gates) == 3
        assert c_op(circuit).ptm(basis, basis) == approx(
            Operation.from_sequence(orplus.at(0), ocphase.at(0, 1),
                                    orminus.at(0)).ptm(basis, basis))

        circuit = grplus + (gcphase + grminus)
        assert circuit.qubits == ['Q0', 'Q1']
        assert len(circuit.gates) == 3
        assert c_op(circuit).ptm(basis, basis) == approx(
            Operation.from_sequence(orplus.at(0), ocphase.at(0, 1),
                                    orminus.at(0)).ptm(basis, basis))

        grplus = Gate('Q1', dim, orplus)
        grminus = Gate('Q1', dim, orminus)
        circuit = grplus + gcphase + grminus
        assert circuit.qubits == ['Q1', 'Q0']
        assert len(circuit.gates) == 3
        assert c_op(circuit).ptm(basis, basis) == approx(
            Operation.from_sequence(orplus.at(0), ocphase.at(0, 1),
                                    orminus.at(0)).ptm(basis, basis))

        basis = (basis[0], ) * 3

        grplus = Gate('Q2', dim, orplus)
        grminus = Gate('Q0', dim, orminus)
        circuit = grplus + gcphase + grminus
        assert circuit.qubits == ['Q2', 'Q0', 'Q1']
        assert len(circuit.gates) == 3
        assert c_op(circuit).ptm(basis, basis) == approx(
            Operation.from_sequence(orplus.at(0), ocphase.at(1, 2),
                                    orminus.at(1)).ptm(basis, basis))

        grplus = Gate('Q0', dim, orplus)
        grminus = Gate('Q2', dim, orminus)
        circuit = grplus + gcphase + grminus
        assert circuit.qubits == ['Q0', 'Q1', 'Q2']
        assert len(circuit.gates) == 3
        assert c_op(circuit).ptm(basis, basis) == approx(
            Operation.from_sequence(orplus.at(0), ocphase.at(0, 1),
                                    orminus.at(2)).ptm(basis, basis))
Example #4
0
    def test_opt_basis_single_qubit_2d(self):
        b = bases.general(2)
        b0 = b.subbasis([0])
        b1 = b.subbasis([1])
        b01 = b.computational_subbasis()

        # Identity up to floating point error
        rot = lib2.rotate_x(2 * np.pi).compile(bases_in=(b0, ))
        assert rot.bases_in == (b0, )
        assert rot.bases_out == (b0, )
        rot = lib2.rotate_x(2 * np.pi).compile(bases_in=(b1, ))
        assert rot.bases_in == (b1, )
        assert rot.bases_out == (b1, )

        # RX(pi)
        rot = lib2.rotate_x(np.pi).compile(bases_in=(b0, ))
        assert rot.bases_in == (b0, )
        assert rot.bases_out == (b1, )
        rot = lib2.rotate_x(np.pi).compile(bases_in=(b1, ))
        assert rot.bases_in == (b1, )
        assert rot.bases_out == (b0, )

        # RY(pi/2)
        rot = lib2.rotate_y(np.pi / 2).compile(bases_in=(b01, ))
        assert rot.bases_in[0] == b01
        assert rot.bases_out[0].dim_pauli == 3
        assert '0' in rot.bases_out[0].labels
        assert '1' in rot.bases_out[0].labels
        assert 'X10' in rot.bases_out[0].labels
Example #5
0
    def test_gate_create(self):
        dim = 2
        gate = Gate('Q0', dim, lib.rotate_y(0.5 * pi), 20.)
        assert gate.time_start == 0
        assert gate.time_end == 20.
        assert gate.duration == 20.

        gate = Gate(['Q0', 'Q1'], dim, lib.cphase(0.5 * pi), 40., 125.)
        assert gate.time_start == 125.
        assert gate.time_end == approx(165.)
        assert gate.duration == 40.

        gate.time_end = 90.
        assert gate.time_start == approx(50.)
        assert gate.time_end == 90.
        assert gate.duration == 40.

        gate1 = gate.shift(time_start=0.)
        assert gate.time_start == approx(50.)
        assert gate.time_end == 90.
        assert gate.duration == 40.
        assert gate1.time_start == 0.
        assert gate1.time_end == 40.
        assert gate1.duration == 40.

        gate1 = gate.shift(time_end=123.)
        assert gate.time_start == approx(50.)
        assert gate.time_end == 90.
        assert gate.duration == 40.
        assert gate1.time_start == approx(83.)
        assert gate1.time_end == 123.
        assert gate1.duration == 40.
Example #6
0
    def test_time_aware_add_gate_no_init_time(self):
        dim = 2
        orplus = lib.rotate_y(0.5 * pi)
        ocphase = lib.cphase(pi)
        orminus = lib.rotate_y(-0.5 * pi)
        gate_q0 = Gate('Q0', dim, orplus, 20.)
        gate_2q = Gate(['Q0', 'Q1'], dim, ocphase, 40.)
        gate_q1 = Gate('Q1', dim, orminus, 30.)

        circuit = gate_q0 + gate_2q
        assert circuit.time_start == 0.
        assert circuit.time_end == approx(60.)
        assert circuit.duration == approx(60.)
        assert [gate.time_start for gate in circuit.gates] == approx([0., 20.])

        circuit = circuit + gate_q1
        assert circuit.time_start == 0.
        assert circuit.time_end == approx(90.)
        assert circuit.duration == approx(90.)
        assert [gate.time_start for gate in circuit.gates] == \
               approx([0., 20., 60.])

        circuit = circuit + gate_q0
        assert circuit.time_start == 0.
        assert circuit.time_end == approx(90.)
        assert circuit.duration == approx(90.)
        assert [gate.time_start for gate in circuit.gates] == \
               approx([0., 20., 60., 60.])

        circuit = gate_q1 + circuit
        assert circuit.time_start == 0.
        assert circuit.time_end == approx(100.)
        assert circuit.duration == approx(100.)
        assert [gate.time_start for gate in circuit.gates] == \
               approx([0., 10., 30., 70., 70.])

        circuit = circuit + (gate_q0 + gate_q1)
        assert circuit.time_start == 0.
        assert circuit.time_end == approx(130.)
        assert circuit.duration == approx(130.)
        assert [gate.time_start for gate in circuit.gates] == \
               approx([0., 10., 30., 70., 70., 100., 100.])
Example #7
0
    def test_chain_create(self):
        op1 = lib2.rotate_x()
        op2 = lib2.rotate_y()
        op3 = lib2.cnot()
        op_qutrit = lib3.rotate_x()

        circuit = Operation.from_sequence(op1.at(0), op2.at(0))
        assert circuit.num_qubits == 1
        assert len(circuit._units) == 2

        circuit = Operation.from_sequence(op1.at(1), op2.at(0))
        assert circuit.num_qubits == 2
        assert len(circuit._units) == 2

        with pytest.raises(ValueError, match=".* must form an ordered set .*"):
            Operation.from_sequence(op1.at(2), op2.at(0))

        with pytest.raises(ValueError, match=".* must form an ordered set .*"):
            Operation.from_sequence(op1.at(1), op2.at(2))

        with pytest.raises(ValueError, match="Hilbert dimensionality of op.*"):
            Operation.from_sequence(op1.at(0), op_qutrit.at(0))

        circuit3q = Operation.from_sequence(op1.at(0), op2.at(1), op3.at(0, 1),
                                            op1.at(1), op2.at(0), op3.at(0, 2))
        assert circuit3q.num_qubits == 3
        assert len(circuit3q._units) == 6

        with pytest.raises(ValueError, match="Number of indices is not .*"):
            Operation.from_sequence(op1.at(0), op3.at(0))

        with pytest.raises(ValueError, match="Number of indices is not .*"):
            circuit3q.at(0, 1)

        circuit4q = Operation.from_sequence(op3.at(0, 2),
                                            circuit3q.at(1, 2, 3))
        assert len(circuit4q._units) == 7
        assert circuit4q._units[0].indices == (0, 2)
        for o1, o2 in zip(circuit4q._units[1:], circuit3q._units):
            assert np.all(np.array(o1.indices) == np.array(o2.indices) + 1)

        circuit4q = Operation.from_sequence(circuit3q.at(2, 0, 3),
                                            op3.at(0, 1), op2.at(1))
        assert len(circuit4q._units) == 8
        assert circuit4q._units[0].indices == (2, )
        assert circuit4q._units[1].indices == (0, )
        assert circuit4q._units[2].indices == (2, 0)

        Operation.from_sequence(circuit3q.at(0, 1, 2),
                                Operation.from_sequence(op1, op2).at(1))
Example #8
0
    def test_compile_single_qubit_2d(self):
        b = bases.general(2)
        b0 = b.subbasis([0])
        b01 = b.computational_subbasis()

        op = lib2.rotate_y(np.pi)
        assert op.shape == (4, 4)
        op_full = op.compile(bases_in=(b, ))
        assert op_full.shape == (4, 4)
        op_cl = op.compile(bases_in=(b01, ))
        assert op_cl.shape == (2, 2)

        op = lib2.rotate_x(np.pi / 3)
        assert op.shape == (4, 4)
        op_full = op.compile(bases_in=(b, ), bases_out=(b01, ))
        # X component of a state is irrelevant for the output.
        assert op_full.shape == (2, 3)
        op_cl = op.compile(bases_in=(b0, ))
        assert op_cl.shape == (3, 1)
Example #9
0
    def test_chain_apply(self):
        b = (bases.general(2), ) * 3
        dm = random_hermitian_matrix(8, seed=93)
        pv1 = PauliVector.from_dm(dm, b)
        pv2 = PauliVector.from_dm(dm, b)

        # Some random gate sequence
        op_indices = [(lib2.rotate_x(np.pi / 2), (0, )),
                      (lib2.rotate_y(0.3333), (1, )), (lib2.cphase(), (0, 2)),
                      (lib2.cphase(), (1, 2)),
                      (lib2.rotate_x(-np.pi / 2), (0, ))]

        for op, indices in op_indices:
            op(pv1, *indices),

        circuit = Operation.from_sequence(*(op.at(*ix)
                                            for op, ix in op_indices))
        circuit(pv2, 0, 1, 2)
        assert np.all(pv1.to_pv() == pv2.to_pv())
Example #10
0
    def test_ptm(self):
        # Some random gate sequence
        op_indices = [(lib2.rotate_x(np.pi / 2), (0, )),
                      (lib2.rotate_y(0.3333), (1, )), (lib2.cphase(), (0, 2)),
                      (lib2.cphase(), (1, 2)),
                      (lib2.rotate_x(-np.pi / 2), (0, ))]
        circuit = Operation.from_sequence(*(op.at(*ix)
                                            for op, ix in op_indices))

        b = (bases.general(2), ) * 3
        ptm = circuit.ptm(b, b)
        assert isinstance(ptm, np.ndarray)

        op_3q = Operation.from_ptm(ptm, b)
        dm = random_hermitian_matrix(8, seed=93)
        state1 = PauliVector.from_dm(dm, b)
        state2 = PauliVector.from_dm(dm, b)

        circuit(state1, 0, 1, 2)
        op_3q(state2, 0, 1, 2)
        assert np.allclose(state1.to_pv(), state2.to_pv())
Example #11
0
 def strange_duration_gate(self, qubit):
     return lib.rotate_y(pi)
Example #12
0
 def cnot_like(angle_cphase, angle_rotate):
     return Operation.from_sequence(
         lib.rotate_y(angle_rotate).at(1),
         lib.cphase(angle_cphase).at(0, 1),
         lib.rotate_y(-angle_rotate).at(1))