示例#1
0
    def test_opt_basis_two_qubit_2d(self):
        op = lib2.cnot()

        # Classical input basis -> classical output basis
        # Possible flip in control bit
        b = bases.general(2)
        b0 = b.subbasis([0])
        b01 = b.subbasis([0, 1])
        b_in = (b01, b0)
        op_c = op.compile(bases_in=b_in)
        assert op_c.bases_in[0] == b01
        assert op_c.bases_in[1] == b0
        assert op_c.bases_out[0] == b01
        assert op_c.bases_out[1] == b01

        # Classical control bit is not violated
        b = bases.general(2)
        b0 = b.subbasis([0])
        b_in = (b0, b)
        op_c = op.compile(bases_in=b_in)
        assert op_c.bases_in[0] == b0
        assert op_c.bases_in[1] == b
        assert op_c.bases_out[0] == b0
        assert op_c.bases_out[1] == b

        # Classical target bit will become quantum for quantum control bit,
        # input should not be violated
        b = bases.general(2)
        b0 = b.subbasis([0])
        b_in = (b, b0)
        op_c = op.compile(bases_in=b_in)
        assert op_c.bases_in[0] == b
        assert op_c.bases_in[1] == b0
        assert op_c.bases_out[0] == b
        assert op_c.bases_out[1] == b
示例#2
0
    def test_opt_basis_two_qubit_2d(self):
        op = lib2.cnot()

        # Classical input basis -> classical output basis
        # Possible flip in control bit
        b = bases.general(2)
        b0 = b.subbasis([0])
        b01 = b.subbasis([0, 1])
        b_in = (b01, b0)
        op_c = op.compile(bases_in=b_in)
        assert op_c.bases_in[0] == b01
        assert op_c.bases_in[1] == b0
        assert op_c.bases_out[0] == b01
        assert op_c.bases_out[1] == b01

        # Classical control bit is not violated
        b = bases.general(2)
        b0 = b.subbasis([0])
        b_in = (b0, b)
        op_c = op.compile(bases_in=b_in)
        assert op_c.bases_in[0] == b0
        assert op_c.bases_in[1] == b
        assert op_c.bases_out[0] == b0
        assert op_c.bases_out[1] == b

        # Classical target bit will become quantum for quantum control bit,
        # input should not be violated
        b = bases.general(2)
        b0 = b.subbasis([0])
        b_in = (b, b0)
        op_c = op.compile(bases_in=b_in)
        assert op_c.bases_in[0] == b
        assert op_c.bases_in[1] == b0
        assert op_c.bases_out[0] == b
        assert op_c.bases_out[1] == b
示例#3
0
    def test_chain_merge_prev(self, d, lib):
        b = bases.general(d)

        rng = np.random.RandomState(4242)
        dm = rng.randn(d*d, d*d) + 1j * rng.randn(d*d, d*d)
        dm += dm.conjugate().transpose()
        dm /= dm.trace()

        chain = Operation.from_sequence(
            (lib.cphase(angle=np.pi/7, leakage=0.25)
             if d == 3 else lib.cphase(3*np.pi / 7)).at(0, 1),
            lib.rotate_x(4 * np.pi / 7).at(0),
        )

        bases_full = (b, b)
        chain_c = chain.compile(bases_full, bases_full)
        assert len(chain.operations) == 2
        assert isinstance(chain_c, _PTMOperation)

        state1 = State.from_dm(dm, bases_full)
        state2 = State.from_dm(dm, bases_full)
        chain(state1, 0, 1)
        chain_c(state2, 0, 1)

        assert np.allclose(state1.meas_prob(0), state2.meas_prob(0))
        assert np.allclose(state1.meas_prob(1), state2.meas_prob(1))
示例#4
0
    def test_rotate_z(self):
        sqrt2 = np.sqrt(2)
        qubit_basis = (bases.general(2),)
        dm = State(qubit_basis)

        rotate90 = lib.rotate_z(0.5*np.pi)
        rotate180 = lib.rotate_z(np.pi)
        rotate360 = lib.rotate_z(2*np.pi)

        rotate90(dm, 0)
        assert np.allclose(dm.to_pv(), [1, 0, 0, 0])
        rotate180(dm, 0)
        assert np.allclose(dm.to_pv(), [1, 0, 0, 0])

        # manually apply a Hadamard gate
        had_expansion = np.array([0.5, 0.5, sqrt2, 0])
        superpos_dm = State(qubit_basis,
                            had_expansion)

        rotate180(superpos_dm, 0)
        assert np.allclose(superpos_dm.to_pv(),
                           [0.5, 0.5, -sqrt2, 0])

        rotate90(superpos_dm, 0)
        assert np.allclose(superpos_dm.to_pv(),
                           [0.5, 0.5, 0, -sqrt2])

        rotate180(superpos_dm, 0)
        assert np.allclose(superpos_dm.to_pv(),
                           [0.5, 0.5, 0, sqrt2])

        rotate360(superpos_dm, 0)
        assert np.allclose(superpos_dm.to_pv(),
                           [0.5, 0.5, 0, sqrt2])
示例#5
0
    def test_chain_merge_prev(self, d, lib):
        b = bases.general(d)

        rng = np.random.RandomState(4242)
        dm = rng.randn(d * d, d * d) + 1j * rng.randn(d * d, d * d)
        dm += dm.conjugate().transpose()
        dm /= dm.trace()

        chain = Operation.from_sequence(
            (lib.cphase(angle=np.pi / 7, leakage_rate=0.25)
             if d == 3 else lib.cphase(3 * np.pi / 7)).at(0, 1),
            lib.rotate_x(4 * np.pi / 7).at(0),
        )

        bases_full = (b, b)
        chain_c = chain.compile(bases_full, bases_full)
        assert len(chain._units) == 2
        assert isinstance(chain_c, PTMOperation)

        pv1 = PauliVector.from_dm(dm, bases_full)
        pv2 = PauliVector.from_dm(dm, bases_full)
        chain(pv1, 0, 1)
        chain_c(pv2, 0, 1)

        assert np.allclose(pv1.meas_prob(0), pv2.meas_prob(0))
        assert np.allclose(pv1.meas_prob(1), pv2.meas_prob(1))
示例#6
0
def meas_butterfly(p0_up, p1_up, p1_down, p2_down):
    """
    Returns a gate, that corresponds to measurement-induced excitations.
    Each measurement should be sandwiched by two of these gates (before
    and after projection. This operation dephases the qubit immediately.

    Note: if measurement-induced leakage is reported by RB, p1_up should
    be twice larger, since RB would report average probabllity for both 0
    and 1 state.

    Parameters
    ----------
    p0_up : float
        Probability to excite to state 1, being in the state 0
    p1_up : float
        Probability to excite to state 2, being in the state 1
    p1_down : float
        Probability to relax to state 0, being in the state 1
    p2_down : float
        Probability to relax to state 1, being in the state 2

    Returns
    -------
        quantumsim.operation._PTMOperation
    """
    basis = (bases.general(3).computational_subbasis(), )
    return amp_damping(0.5 * p0_up, 0.5 * p1_up, 0.5 * p1_down,
                       0.5 * p2_down).set_bases(bases_in=basis,
                                                bases_out=basis)
示例#7
0
def amp_damping(p0_up, p1_up, p1_down, p2_down):
    """
    A gate, that excites or relaxes a qubit with a certain probability.

    Parameters
    ----------
    p0_up : float
        Probability to excite to state 1, being in the state 0
    p1_up : float
        Probability to excite to state 2, being in the state 1
    p1_down : float
        Probability to relax to state 0, being in the state 1
    p2_down : float
        Probability to relax to state 1, being in the state 2

    Returns
    -------
        quantumsim.operation._PTMOperation
    """
    ptm = np.identity(9, dtype=float)
    ptm[:3, :3] = [[1. - p0_up, p1_down, 0.],
                   [p0_up, 1. - p1_down - p1_up, p2_down],
                   [0., p1_up, 1 - p2_down]]
    basis = (bases.general(3), )
    return Operation.from_ptm(ptm, basis, basis)
示例#8
0
def idle(duration, t1, t2, anharmonicity=0.):
    if np.isfinite(t1) and np.isfinite(t2):
        t_phi = 1. / (1. / t2 - 0.5 / t1)
        if t_phi < 0:
            raise ValueError('t2 must be less than 2*t1')
        elif np.allclose(t_phi, 0):
            ops_t2 = []
        else:
            ops_t2 = [(8. / (9 * t_phi))**0.5 *
                      np.array([[1, 0, 0], [0, 0, 0], [0, 0, -1]]),
                      (2. / (9 * t_phi))**0.5 *
                      np.array([[1, 0, 0], [0, -1, 0], [0, 0, 0]]),
                      (2. / (9 * t_phi))**0.5 *
                      np.array([[0, 0, 0], [0, 1, 0], [0, 0, -1]])]
    else:
        ops_t2 = []

    op_t1 = t1**-0.5 * np.array([[0, 1, 0], [0, 0, np.sqrt(2)], [0, 0, 0]])
    if not np.allclose(anharmonicity, 0.):
        ham = np.array([
            [0., 0., 0.],
            [0., 0., 0.],
            [0., 0., anharmonicity],
        ])
    else:
        ham = None
    return Operation.from_lindblad_form(duration, (bases.general(3), ),
                                        hamiltonian=ham,
                                        lindblad_ops=[op_t1, *ops_t2])
示例#9
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
示例#10
0
    def test_kraus_to_ptm_errors(self):
        qubit_basis = (bases.general(2), )
        qutrit_basis = (bases.general(3), )
        cz_kraus_mat = np.diag([1, 1, 1, -1])
        kraus_op = Operation.from_kraus(cz_kraus_mat, qubit_basis * 2)

        wrong_dim_kraus = np.random.random((4, 4, 2, 2))
        with pytest.raises(ValueError):
            _ = Operation.from_kraus(wrong_dim_kraus, qubit_basis)
        not_sqr_kraus = np.random.random((4, 2, 3))
        with pytest.raises(ValueError):
            _ = Operation.from_kraus(not_sqr_kraus, qubit_basis)
        with pytest.raises(ValueError):
            _ = Operation.from_kraus(cz_kraus_mat, qutrit_basis)
        with pytest.raises(ValueError):
            _ = kraus_op.set_bases(qutrit_basis * 2)
示例#11
0
    def test_lindblad_singlequbit(self):
        ham = random_hermitian_matrix(2, seed=56)
        lindblad_ops = np.array([
            [[0, 0.1], [0, 0]],
            [[0, 0], [0, 0.33]],
        ])
        t1 = 10
        t2 = 25
        b1 = (bases.general(2), )
        b2 = (bases.gell_mann(2), )
        op1 = Operation.from_lindblad_form(t1,
                                           b1,
                                           b2,
                                           hamiltonian=ham,
                                           lindblad_ops=lindblad_ops)
        op2 = Operation.from_lindblad_form(t2,
                                           b2,
                                           b1,
                                           hamiltonian=ham,
                                           lindblad_ops=lindblad_ops)
        op = Operation.from_lindblad_form(t1 + t2,
                                          b1,
                                          hamiltonian=ham,
                                          lindblad_ops=lindblad_ops)
        dm = random_hermitian_matrix(2, seed=3)
        state1 = PauliVector.from_dm(dm, b1)
        state2 = PauliVector.from_dm(dm, b1)

        op1(state1, 0)
        op2(state1, 0)
        op(state2, 0)
        assert np.allclose(state1.to_pv(), state2.to_pv())
示例#12
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
示例#13
0
    def test_chain_compile_leaking(self):
        b = bases.general(3)
        chain0 = Operation.from_sequence(
            lib3.rotate_x(0.5 * np.pi).at(2),
            lib3.cphase(leakage_rate=0.1).at(0, 2),
            lib3.cphase(leakage_rate=0.1).at(1, 2),
            lib3.rotate_x(-0.75 * np.pi).at(2),
            lib3.rotate_x(0.25 * np.pi).at(2),
        )
        b0 = b.subbasis([0])
        b01 = b.subbasis([0, 1])
        b0134 = b.subbasis([0, 1, 3, 4])
        chain1 = chain0.compile((b0, b0, b0134), (b, b, b))
        assert isinstance(chain1, _Chain)
        # Ancilla is not leaking here
        anc_basis = chain1._units[1].operation.bases_out[1]
        for label in anc_basis.labels:
            assert '2' not in label

        chain2 = chain0.compile((b01, b01, b0134), (b, b, b))
        # Ancilla is leaking here
        assert isinstance(chain2, _Chain)
        anc_basis = chain2._units[1].operation.bases_out[1]
        for label in '2', 'X20', 'Y20', 'X21', 'Y21':
            assert label in anc_basis.labels
示例#14
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))
示例#15
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
示例#16
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))
示例#17
0
    def test_cnot(self):
        cnot = lib.cnot()
        qubit_bases = (bases.general(2), bases.general(2), bases.general(2))

        dm = np.diag([0.25, 0, 0.75, 0, 0, 0, 0, 0])
        s = PauliVector.from_dm(dm, qubit_bases)
        assert np.allclose(s.meas_prob(0), (1, 0))
        assert np.allclose(s.meas_prob(1), (0.25, 0.75))
        assert np.allclose(s.meas_prob(2), (1, 0))
        cnot(s, 0, 1)
        assert np.allclose(s.meas_prob(0), (1, 0))
        assert np.allclose(s.meas_prob(1), (0.25, 0.75))
        assert np.allclose(s.meas_prob(2), (1, 0))
        cnot(s, 1, 2)
        assert np.allclose(s.meas_prob(0), (1, 0))
        assert np.allclose(s.meas_prob(1), (0.25, 0.75))
        assert np.allclose(s.meas_prob(2), (0.25, 0.75))
示例#18
0
    def test_lindblad_two_qubit(self):
        b = (bases.general(2), )
        id = np.array([[1, 0], [0, 1]])
        ham1 = random_hermitian_matrix(2, seed=6)
        ham2 = random_hermitian_matrix(2, seed=7)
        ham = np.kron(ham1, id).reshape(2, 2, 2, 2) + \
              np.kron(id, ham2).reshape(2, 2, 2, 2)
        dm = random_hermitian_matrix(4, seed=3)
        op1 = Operation.from_lindblad_form(25, b, hamiltonian=ham1)
        op2 = Operation.from_lindblad_form(25, b, hamiltonian=ham2)
        op = Operation.from_lindblad_form(25, b * 2, hamiltonian=ham)
        state1 = PauliVector.from_dm(dm, b * 2)
        state2 = PauliVector.from_dm(dm, b * 2)
        op1(state1, 0)
        op2(state1, 1)
        op(state2, 0, 1)
        assert np.allclose(state1.to_pv(), state2.to_pv())

        ops1 = np.array([
            [[0, 0.1], [0, 0]],
            [[0, 0], [0, 0.33]],
        ])
        ops2 = np.array([
            [[0, 0.15], [0, 0]],
            [[0, 0], [0, 0.17]],
        ])
        ops = [np.kron(op, id).reshape(2, 2, 2, 2) for op in ops1] +\
              [np.kron(id, op).reshape(2, 2, 2, 2) for op in ops2]
        op1 = Operation.from_lindblad_form(25, b, lindblad_ops=ops1)
        op2 = Operation.from_lindblad_form(25, b, lindblad_ops=ops2)
        op = Operation.from_lindblad_form(25, b * 2, lindblad_ops=ops)
        state1 = PauliVector.from_dm(dm, b * 2)
        state2 = PauliVector.from_dm(dm, b * 2)
        op1(state1, 0)
        op2(state1, 1)
        op(state2, 0, 1)
        assert np.allclose(state1.to_pv(), state2.to_pv())

        op1 = Operation.from_lindblad_form(25,
                                           b,
                                           hamiltonian=ham1,
                                           lindblad_ops=ops1)
        op2 = Operation.from_lindblad_form(25,
                                           b,
                                           hamiltonian=ham2,
                                           lindblad_ops=ops2)
        op = Operation.from_lindblad_form(25,
                                          b * 2,
                                          hamiltonian=ham,
                                          lindblad_ops=ops)
        state1 = PauliVector.from_dm(dm, b * 2)
        state2 = PauliVector.from_dm(dm, b * 2)
        op1(state1, 0)
        op2(state1, 1)
        op(state2, 0, 1)
        assert np.allclose(state1.to_pv(), state2.to_pv())
示例#19
0
 def test_lindblad_time_inverse(self):
     ham = random_hermitian_matrix(2, seed=4)
     b = (bases.general(2), )
     op_plus = Operation.from_lindblad_form(20, b, hamiltonian=ham)
     op_minus = Operation.from_lindblad_form(20, b, hamiltonian=-ham)
     dm = random_hermitian_matrix(2, seed=5)
     state = PauliVector.from_dm(dm, b)
     op_plus(state, 0)
     op_minus(state, 0)
     assert np.allclose(state.to_dm(), dm)
示例#20
0
    def test_cnot(self):
        cnot = lib.cnot()
        qubit_bases = (bases.general(2),
                       bases.general(2),
                       bases.general(2))

        dm = np.diag([0.25, 0, 0.75, 0, 0, 0, 0, 0])
        s = State.from_dm(dm, qubit_bases)
        assert np.allclose(s.meas_prob(0), (1, 0))
        assert np.allclose(s.meas_prob(1), (0.25, 0.75))
        assert np.allclose(s.meas_prob(2), (1, 0))
        cnot(s, 0, 1)
        assert np.allclose(s.meas_prob(0), (1, 0))
        assert np.allclose(s.meas_prob(1), (0.25, 0.75))
        assert np.allclose(s.meas_prob(2), (1, 0))
        cnot(s, 1, 2)
        assert np.allclose(s.meas_prob(0), (1, 0))
        assert np.allclose(s.meas_prob(1), (0.25, 0.75))
        assert np.allclose(s.meas_prob(2), (0.25, 0.75))
示例#21
0
    def test_compilation_with_placeholders(self):
        b_full = bases.general(3)
        b0 = b_full.subbasis([0])
        b01 = b_full.subbasis([0, 1])
        b012 = b_full.subbasis([0, 1, 2])

        bases_in = (b01, b01, b0)
        bases_out = (b_full, b_full, b012)
        zz = Operation.from_sequence(
            lib3.rotate_x(-np.pi / 2).at(2),
            lib3.cphase(leakage_rate=0.1).at(0, 2),
            lib3.cphase(leakage_rate=0.25).at(2, 1),
            lib3.rotate_x(np.pi / 2).at(2),
            lib3.rotate_x(np.pi).at(0),
            lib3.rotate_x(np.pi).at(1)).compile(bases_in, bases_out)
        ptm_ref = zz.ptm(bases_in, bases_out)

        zz_parametrized = Operation.from_sequence(
            Operation.from_sequence(
                ParametrizedOperation(lambda angle1: lib3.rotate_x(angle1),
                                      (b_full, )).at(2),
                ParametrizedOperation(
                    lambda lr02: lib3.cphase(leakage_rate=lr02),
                    (b_full, ) * 2).at(0, 2),
                ParametrizedOperation(
                    lambda lr21: lib3.cphase(leakage_rate=lr21),
                    (b_full, ) * 2).at(2, 1),
                ParametrizedOperation(lambda angle2: lib3.rotate_x(angle2),
                                      (b_full, )).at(2),
                lib3.rotate_x(np.pi).at(0),
                lib3.rotate_x(np.pi).at(1)))
        zzpc = zz_parametrized.compile(bases_in, bases_out)
        assert isinstance(zzpc, _Chain)
        assert len(list(zzpc.units())) == 6

        zz_parametrized = Operation.from_sequence(
            Operation.from_sequence(
                ParametrizedOperation(lambda angle1: lib3.rotate_x(angle1),
                                      (b_full, )).at(2),
                ParametrizedOperation(
                    lambda lr02: lib3.cphase(leakage_rate=lr02),
                    (b_full, ) * 2).at(0, 2),
                lib3.cphase(leakage_rate=0.25).at(2, 1),
                lib3.rotate_x(np.pi / 2).at(2),
                lib3.rotate_x(np.pi).at(0),
                lib3.rotate_x(np.pi).at(1)))
        zzpc = zz_parametrized.compile(bases_in, bases_out)
        assert len(list(zzpc.units())) == 4
        params = dict(angle1=-np.pi / 2, lr02=0.1, foo='bar')
        new_units = [(op.substitute(
            **params) if isinstance(op, ParametrizedOperation) else op).at(*ix)
                     for op, ix in zzpc.units()]
        zzpc = Operation.from_sequence(new_units).compile(bases_in, bases_out)
        assert len(zzpc._units) == 2
        assert zzpc.ptm(bases_in, bases_out) == approx(ptm_ref)
示例#22
0
    def test_rotate_euler(self):
        qubit_basis = (bases.general(2),)
        dm = State(qubit_basis + qubit_basis)

        rotate90x = lib.rotate_euler(0, 0.5*np.pi, 0)
        rotate90y = lib.rotate_euler(0, 0.5*np.pi, 0)

        rotate90x(dm, 0)
        assert np.allclose(dm.meas_prob(0), (0.5, 0.5))

        rotate90y(dm, 1)
        assert np.allclose(dm.meas_prob(1), (0.5, 0.5))
示例#23
0
    def test_compile_two_qubit_2d(self):
        b = bases.general(2)
        b0 = b.subbasis([0])
        b01 = b.computational_subbasis()

        op = lib2.cnot()
        assert op.shape == (4, 4, 4, 4)
        op_full = op.compile(bases_in=(b, b))
        assert op_full.shape == (4, 4, 4, 4)
        op_cl = op.compile(bases_in=(b01, b01))
        assert op_cl.shape == (2, 2, 2, 2)
        op_cl = op.compile(bases_in=(b0, b))
        assert op_cl.shape == (1, 4, 1, 4)
示例#24
0
    def test_hadamard(self):
        qubit_basis = (bases.general(2),)
        sys_bases = qubit_basis+qubit_basis
        dm = State(sys_bases)

        hadamard = lib.hadamard()

        hadamard(dm, 1)
        assert np.allclose(dm.meas_prob(0), (1, 0))
        assert np.allclose(dm.meas_prob(1), (0.5, 0.5))

        hadamard(dm, 1)
        assert np.allclose(dm.meas_prob(1), (1, 0))
示例#25
0
    def test_compile_two_qubit_2d(self):
        b = bases.general(2)
        b0 = b.subbasis([0])
        b01 = b.computational_subbasis()

        op = lib2.cnot()
        assert op.shape == (4, 4, 4, 4)
        op_full = op.compile(bases_in=(b, b))
        assert op_full.shape == (4, 4, 4, 4)
        op_cl = op.compile(bases_in=(b01, b01))
        assert op_cl.shape == (2, 2, 2, 2)
        op_cl = op.compile(bases_in=(b0, b))
        assert op_cl.shape == (1, 4, 1, 4)
示例#26
0
    def test_convert_ptm_basis(self):
        p_damp = 0.5
        damp_kraus_mat = np.array([[[1, 0], [0, np.sqrt(1 - p_damp)]],
                                   [[0, np.sqrt(p_damp)], [0, 0]]])
        gell_mann_basis = (bases.gell_mann(2), )
        general_basis = (bases.general(2), )

        op1 = Operation.from_kraus(damp_kraus_mat, gell_mann_basis)
        op2 = op1.set_bases(general_basis, general_basis) \
            .set_bases(gell_mann_basis, gell_mann_basis)
        assert np.allclose(op1.ptm(gell_mann_basis), op2.ptm(gell_mann_basis))
        assert op1.bases_in == op2.bases_in
        assert op1.bases_out == op2.bases_out
示例#27
0
    def test_convert_ptm_basis(self):
        p_damp = 0.5
        damp_kraus_mat = np.array(
            [[[1, 0], [0, np.sqrt(1-p_damp)]],
             [[0, np.sqrt(p_damp)], [0, 0]]])
        gell_mann_basis = (bases.gell_mann(2),)
        general_basis = (bases.general(2),)

        damp_op_kraus = Operation.from_kraus(damp_kraus_mat, 2)
        op1 = damp_op_kraus.set_bases(gell_mann_basis, gell_mann_basis)
        op2 = damp_op_kraus.set_bases(general_basis, general_basis) \
            .set_bases(gell_mann_basis, gell_mann_basis)
        assert np.allclose(op1.ptm, op2.ptm)
        assert op1.bases_in == op2.bases_in
        assert op1.bases_out == op2.bases_out
示例#28
0
    def test_kraus_to_ptm_errors(self):
        qutrit_basis = (bases.general(3),)
        cz_kraus_mat = np.diag([1, 1, 1, -1])
        kraus_op = Operation.from_kraus(cz_kraus_mat, 2)

        wrong_dim_kraus = np.random.random((4, 4, 2, 2))
        with pytest.raises(ValueError):
            _ = Operation.from_kraus(wrong_dim_kraus, 2)
        not_sqr_kraus = np.random.random((4, 2, 3))
        with pytest.raises(ValueError):
            _ = Operation.from_kraus(not_sqr_kraus, 2)
        with pytest.raises(ValueError):
            _ = Operation.from_kraus(cz_kraus_mat, 3)
        with pytest.raises(ValueError):
            _ = kraus_op.set_bases(qutrit_basis + qutrit_basis)
示例#29
0
    def test_create(self):
        op_1q = lib2.rotate_x(0.5 * pi)
        basis = (bases.general(2), )

        with pytest.raises(ValueError,
                           match=".*can't accept free arguments.*"):
            ParametrizedOperation(lambda *args: op_1q, basis, basis)
        with pytest.raises(ValueError,
                           match=".*can't accept free keyword arguments.*"):
            ParametrizedOperation(lambda **kwargs: op_1q, basis, basis)
        with pytest.raises(OperationNotDefinedError,
                           match="Operation placeholder does not have a PTM"):
            ParametrizedOperation(lambda: op_1q, basis).ptm(basis)
        with pytest.raises(OperationNotDefinedError,
                           match="Operation placeholder can not be called"):
            ParametrizedOperation(lambda: op_1q, basis)(PauliVector(basis))
示例#30
0
    def test_zz_parity_compilation(self):
        b_full = bases.general(3)
        b0 = b_full.subbasis([0])
        b01 = b_full.subbasis([0, 1])
        b012 = b_full.subbasis([0, 1, 2])

        bases_in = (b01, b01, b0)
        bases_out = (b_full, b_full, b012)
        zz = Operation.from_sequence(
            lib3.rotate_x(-np.pi / 2).at(2),
            lib3.cphase(leakage_rate=0.1).at(0, 2),
            lib3.cphase(leakage_rate=0.25).at(2, 1),
            lib3.rotate_x(np.pi / 2).at(2),
            lib3.rotate_x(np.pi).at(0),
            lib3.rotate_x(np.pi).at(1))
        zz_ptm = zz.ptm(bases_in, bases_out)
        zzc = zz.compile(bases_in=bases_in, bases_out=bases_out)
        zzc_ptm = zzc.ptm(bases_in, bases_out)
        assert zz_ptm == approx(zzc_ptm)

        units = list(zzc.units())
        assert len(units) == 2
        op1, ix1 = units[0]
        op2, ix2 = units[1]
        assert ix1 == (0, 2)
        assert ix2 == (1, 2)
        assert op1.bases_in[0] == bases_in[0]
        assert op2.bases_in[0] == bases_in[1]
        assert op1.bases_in[1] == bases_in[2]
        # Qubit 0 did not leak
        assert op1.bases_out[0] == bases_out[0].subbasis([0, 1])
        # Qubit 1 leaked
        assert op2.bases_out[0] == bases_out[1].subbasis([0, 1, 2, 6])
        # Qubit 2 is measured
        assert op2.bases_out[1] == bases_out[2]

        dm = random_hermitian_matrix(3**3, seed=85)
        pv1 = PauliVector.from_dm(dm, (b01, b01, b0))
        pv2 = PauliVector.from_dm(dm, (b01, b01, b0))

        zz(pv1, 0, 1, 2)
        zzc(pv2, 0, 1, 2)

        # Compiled version still needs to be projected, so we can't compare
        # Pauli vectors, so we can to check only DM diagonals.
        assert np.allclose(pv1.diagonal(), pv2.diagonal())
示例#31
0
    def test_circuits_params(self):
        dim = 2
        basis = (bases.general(dim), ) * 2
        orotate = lib.rotate_y
        ocphase = lib.cphase
        grotate = Gate('Q0', dim, ParametrizedOperation(orotate, basis[:1]))
        gcphase = Gate(('Q0', 'Q1'), dim,
                       ParametrizedOperation(ocphase, basis))

        with pytest.raises(RuntimeError,
                           match=r".*free parameters.*\n"
                           r".*angle.*\n"
                           r".*allow_param_repeat.*"):
            _ = gcphase + grotate

        with allow_param_repeat():
            circuit = grotate + gcphase + grotate

        assert circuit.free_parameters == {sympy.symbols('angle')}
        assert len(circuit.gates) == 3
        angle = 0.736
        assert c_op(circuit(angle=angle)).ptm(basis, basis) == \
               approx(Operation.from_sequence(
                   orotate(angle).at(0), ocphase(angle).at(0, 1),
                   orotate(angle).at(0)
               ).ptm(basis, basis))

        angle1 = 0.4 * pi
        angle2 = 1.01 * pi
        angle3 = -0.6 * pi
        ptm_ref = Operation.from_sequence(
            orotate(angle1).at(0),
            ocphase(angle2).at(0, 1),
            orotate(angle3).at(0)).ptm(basis, basis)

        circuit = grotate(angle=angle1) + gcphase(angle=angle2) + \
                  grotate(angle=angle3)
        assert circuit.finalize().operation.ptm(basis, basis) == \
               approx(ptm_ref)

        circuit = grotate(angle='angle1') + gcphase(angle='angle2') + \
                  grotate(angle='angle3')
        assert c_op(circuit(angle1=angle1, angle2=angle2,
                            angle3=angle3)).ptm(basis,
                                                basis) == approx(ptm_ref)
示例#32
0
    def test_zz_parity_compilation(self):
        b_full = bases.general(3)
        b0 = b_full.subbasis([0])
        b01 = b_full.subbasis([0, 1])
        b012 = b_full.subbasis([0, 1, 2])

        bases_in = (b01, b01, b0)
        bases_out = (b_full, b_full, b012)
        zz = Operation.from_sequence(
            lib3.rotate_x(-np.pi/2).at(2),
            lib3.cphase(leakage=0.1).at(0, 2),
            lib3.cphase(leakage=0.25).at(2, 1),
            lib3.rotate_x(np.pi/2).at(2),
            lib3.rotate_x(np.pi).at(0),
            lib3.rotate_x(np.pi).at(1)
        )
        zzc = zz.compile(bases_in=bases_in, bases_out=bases_out)

        assert len(zzc.operations) == 2
        op1, ix1 = zzc.operations[0]
        op2, ix2 = zzc.operations[1]
        assert ix1 == (0, 2)
        assert ix2 == (1, 2)
        assert op1.bases_in[0] == bases_in[0]
        assert op2.bases_in[0] == bases_in[1]
        assert op1.bases_in[1] == bases_in[2]
        # Qubit 0 did not leak
        assert op1.bases_out[0] == bases_out[0].subbasis([0, 1, 3, 4])
        # Qubit 1 leaked
        assert op2.bases_out[0] == bases_out[1].subbasis([0, 1, 2, 6])
        # Qubit 2 is measured
        assert op2.bases_out[1] == bases_out[2]

        dm = random_density_matrix(3**3, seed=85)
        state1 = State.from_dm(dm, (b01, b01, b0))
        state2 = State.from_dm(dm, (b01, b01, b0))

        zz(state1, 0, 1, 2)
        zzc(state2, 0, 1, 2)

        # Compiled version still needs to be projected, so we can't compare
        # Pauli vectors, so we can to check only DM diagonals.
        assert np.allclose(state1.diagonal(), state2.diagonal())
示例#33
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())
示例#34
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)
示例#35
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)
示例#36
0
    def test_chain_compile_single_qubit(self, d, lib):
        b = bases.general(d)
        dm = random_hermitian_matrix(d, seed=487)

        bases_full = (b, )
        subbases = (b.subbasis([0, 1]), )
        angle = np.pi / 5
        rx_angle = lib.rotate_x(angle)
        rx_2angle = lib.rotate_x(2 * angle)
        chain0 = Operation.from_sequence(rx_angle.at(0), rx_angle.at(0))
        pv0 = PauliVector.from_dm(dm, bases_full)
        chain0(pv0, 0)
        assert chain0.num_qubits == 1
        assert len(chain0._units) == 2

        chain0_c = chain0.compile(bases_full, bases_full)
        assert isinstance(chain0_c, PTMOperation)
        pv1 = PauliVector.from_dm(dm, bases_full)
        chain0_c(pv1, 0)
        assert chain0_c.num_qubits == 1
        assert isinstance(chain0_c, PTMOperation)
        op_angle = chain0_c
        op_2angle = rx_2angle.compile(bases_full, bases_full)
        assert isinstance(op_2angle, PTMOperation)
        assert op_angle.shape == op_2angle.shape
        assert op_angle.bases_in == op_2angle.bases_in
        assert op_angle.bases_out == op_2angle.bases_out
        assert op_angle.ptm(op_angle.bases_in, op_angle.bases_out) == \
            approx(op_2angle.ptm(op_2angle.bases_in, op_2angle.bases_out))
        assert pv1.to_pv() == approx(pv0.to_pv())

        rx_pi = lib.rotate_x(np.pi)
        chain_2pi = Operation.from_sequence(rx_pi.at(0), rx_pi.at(0))
        chain_2pi_c1 = chain_2pi.compile(subbases, bases_full)
        assert isinstance(chain_2pi_c1, PTMOperation)
        assert chain_2pi_c1.bases_in == subbases
        assert chain_2pi_c1.bases_out == subbases

        chain_2pi_c2 = chain_2pi.compile(bases_full, subbases)
        assert isinstance(chain_2pi_c2, PTMOperation)
        assert chain_2pi_c2.bases_in == subbases
        assert chain_2pi_c2.bases_out == subbases
示例#37
0
    def test_chain_compile_three_qubit(self, d, lib):
        b = bases.general(d)
        b0 = b.subbasis([0])

        chain0 = Operation.from_sequence(
            lib.rotate_x(0.5*np.pi).at(2),
            lib.cphase().at(0, 2),
            lib.cphase().at(1, 2),
            lib.rotate_x(-0.75*np.pi).at(2),
            lib.rotate_x(0.25*np.pi).at(2),
        )
        chain1 = chain0.compile((b, b, b0), (b, b, b))
        assert chain1.operations[0].indices == (0, 2)
        assert chain1.operations[0].operation.bases_in == (b, b0)
        assert chain1.operations[0].operation.bases_out[0] == b
        assert chain1.operations[1].indices == (1, 2)
        assert chain1.operations[1].operation.bases_in[0] == b
        assert chain1.operations[1].operation.bases_out[0] == b
        for label in '0', '1', 'X10', 'Y10':
            assert label in chain1.operations[1].operation.bases_out[1].labels
示例#38
0
    def test_chain_apply(self):
        b = (bases.general(2), ) * 3
        dm = random_density_matrix(8, seed=93)
        state1 = State.from_dm(dm, b)
        state2 = State.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(state1, *indices),

        circuit = Operation.from_sequence(*(op.at(*ix)
                                            for op, ix in op_indices))
        circuit(state2, 0, 1, 2)

        assert np.all(state1.to_pv() == state2.to_pv())
示例#39
0
    def test_chain_apply(self):
        b = (bases.general(2),) * 3
        dm = random_density_matrix(8, seed=93)
        state1 = State.from_dm(dm, b)
        state2 = State.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(state1, *indices),

        circuit = Operation.from_sequence(
            *(op.at(*ix) for op, ix in op_indices))
        circuit(state2, 0, 1, 2)

        assert np.all(state1.to_pv() == state2.to_pv())
示例#40
0
    def test_chain_compile_single_qubit(self, d, lib):
        b = bases.general(d)
        dm = random_density_matrix(d, seed=487)

        bases_full = (b,)
        subbases = (b.subbasis([0, 1]),)
        angle = np.pi/5
        rx_angle = lib.rotate_x(angle)
        rx_2angle = lib.rotate_x(2*angle)
        chain0 = Operation.from_sequence(rx_angle.at(0), rx_angle.at(0))
        state0 = State.from_dm(dm, bases_full)
        chain0(state0, 0)
        assert chain0.num_qubits == 1
        assert len(chain0.operations) == 2

        chain0_c = chain0.compile(bases_full, bases_full)
        state1 = State.from_dm(dm, bases_full)
        chain0_c(state1, 0)
        assert chain0_c.num_qubits == 1
        assert isinstance(chain0_c, _PTMOperation)
        op_angle = chain0_c
        op_2angle = rx_2angle.compile(bases_full, bases_full)
        assert op_angle.shape == op_2angle.shape
        assert op_angle.bases_in == op_2angle.bases_in
        assert op_angle.bases_out == op_2angle.bases_out
        assert op_angle.ptm == approx(op_2angle.ptm)
        assert state1.to_pv() == approx(state0.to_pv())

        rx_pi = lib.rotate_x(np.pi)
        chain_2pi = Operation.from_sequence(rx_pi.at(0), rx_pi.at(0))
        chain_2pi_c1 = chain_2pi.compile(subbases, bases_full)
        assert isinstance(chain_2pi_c1, _PTMOperation)
        assert chain_2pi_c1.bases_in == subbases
        assert chain_2pi_c1.bases_out == subbases

        chain_2pi_c2 = chain_2pi.compile(bases_full, subbases)
        assert isinstance(chain_2pi_c2, _PTMOperation)
        assert chain_2pi_c2.bases_in == subbases
        assert chain_2pi_c2.bases_out == subbases
示例#41
0
    def test_rotate_x(self):
        basis = (bases.general(3),)
        sys_bases = basis * 3
        dm = State(sys_bases)

        rotate90 = lib.rotate_x(0.5*np.pi)
        rotate180 = lib.rotate_x(np.pi)
        rotate360 = lib.rotate_x(2*np.pi)

        rotate90(dm, 1)
        rotate180(dm, 2)
        assert np.allclose(dm.meas_prob(0), (1, 0, 0))
        assert np.allclose(dm.meas_prob(1), (0.5, 0.5, 0))
        assert np.allclose(dm.meas_prob(2), (0, 1, 0))

        rotate180(dm, 1)
        assert np.allclose(dm.meas_prob(1), (0.5, 0.5, 0))

        rotate90(dm, 1)
        assert np.allclose(dm.meas_prob(1), (1, 0, 0))

        rotate360(dm, 0)
        assert np.allclose(dm.meas_prob(0), (1, 0, 0))
示例#42
0
    def test_rotate_y(self):
        qubit_basis = (bases.general(2),)
        sys_bases = qubit_basis+qubit_basis+qubit_basis
        dm = State(sys_bases)

        rotate90 = lib.rotate_y(0.5*np.pi)
        rotate180 = lib.rotate_y(np.pi)
        rotate360 = lib.rotate_y(2*np.pi)

        rotate90(dm, 1)
        rotate180(dm, 2)
        assert np.allclose(dm.meas_prob(0), (1, 0))
        assert np.allclose(dm.meas_prob(1), (0.5, 0.5))
        assert np.allclose(dm.meas_prob(2), (0, 1))

        rotate180(dm, 1)
        assert np.allclose(dm.meas_prob(1), (0.5, 0.5))

        rotate90(dm, 1)
        assert np.allclose(dm.meas_prob(1), (1, 0))

        rotate360(dm, 0)
        assert np.allclose(dm.meas_prob(0), (1, 0))
示例#43
0
    def test_chain_merge_next(self, d, lib):
        b = bases.general(d)

        dm = random_density_matrix(d**2, seed=574)

        chain = Operation.from_sequence(
            lib.rotate_x(np.pi / 5).at(0),
            (lib.cphase(angle=3*np.pi/7, leakage=0.1)
             if d == 3 else lib.cphase(3*np.pi / 7)).at(0, 1),
        )

        bases_full = (b, b)
        chain_c = chain.compile(bases_full, bases_full)
        assert len(chain.operations) == 2
        assert isinstance(chain_c, _PTMOperation)

        state1 = State.from_dm(dm, bases_full)
        state2 = State.from_dm(dm, bases_full)
        chain(state1, 0, 1)
        chain_c(state2, 0, 1)

        assert state1.meas_prob(0) == approx(state2.meas_prob(0))
        assert state1.meas_prob(1) == approx(state2.meas_prob(1))
示例#44
0
    def test_chain_compile_leaking(self):
        b = bases.general(3)
        chain0 = Operation.from_sequence(
            lib3.rotate_x(0.5*np.pi).at(2),
            lib3.cphase(leakage=0.1).at(0, 2),
            lib3.cphase(leakage=0.1).at(1, 2),
            lib3.rotate_x(-0.75*np.pi).at(2),
            lib3.rotate_x(0.25*np.pi).at(2),
        )
        b0 = b.subbasis([0])
        b01 = b.subbasis([0, 1])
        b0134 = b.subbasis([0, 1, 3, 4])
        chain1 = chain0.compile((b0, b0, b0134), (b, b, b))
        # Ancilla is not leaking here
        anc_basis = chain1.operations[1].operation.bases_out[1]
        for label in anc_basis.labels:
            assert '2' not in label

        chain2 = chain0.compile((b01, b01, b0134), (b, b, b))
        # Ancilla is leaking here
        anc_basis = chain2.operations[1].operation.bases_out[1]
        for label in '2', 'X20', 'Y20', 'X21', 'Y21':
            assert label in anc_basis.labels
示例#45
0
def idle(duration, t1, t2, anharmonicity=0.):
    t_phi = 1./(1./t2 - 0.5/t1)
    op_t1 = t1**-0.5 * np.array([
        [0, 1, 0],
        [0, 0, np.sqrt(2)],
        [0, 0, 0]
    ])
    ops_t2 = [
        (8. / (9*t_phi))**0.5 * np.array([
            [1, 0, 0],
            [0, 0, 0],
            [0, 0, -1]
        ]),
        (2. / (9*t_phi))**0.5 * np.array([
            [1, 0, 0],
            [0, -1, 0],
            [0, 0, 0]
        ]),
        (2. / (9*t_phi))**0.5 * np.array([
            [0, 0, 0],
            [0, 1, 0],
            [0, 0, -1]
        ])
    ]
    if not np.allclose(anharmonicity, 0.):
        ham = np.array([
            [0., 0., 0.],
            [0., 0., 0.],
            [0., 0., anharmonicity],
        ])
    else:
        ham = None
    return Operation.from_lindblad_form(
        duration, bases.general(3),
        hamiltonian=ham,
        lindblad_ops=[op_t1, *ops_t2])