def test_kraus_application_dephasing():
    p = 0.372
    qam = PyQVM(
        n_qubits=1,
        quantum_simulator_type=ReferenceDensitySimulator,
        post_gate_noise_probabilities={"dephasing": p},
    )
    rho = _random_1q_density()
    qam.wf_simulator.density = rho
    qam.execute_once(Program(I(0)))
    final_density = np.array([[rho[0, 0], (1 - p) * rho[0, 1]],
                              [(1 - p) * rho[1, 0], rho[1, 1]]])
    np.testing.assert_allclose(final_density, qam.wf_simulator.density)
def test_kraus_application_bitflip():
    p = 0.372
    qam = PyQVM(
        n_qubits=1,
        quantum_simulator_type=ReferenceDensitySimulator,
        post_gate_noise_probabilities={"bit_flip": p},
    )
    initial_density = _random_1q_density()
    qam.wf_simulator.density = initial_density
    qam.execute_once(Program(I(0)))
    final_density = (1 - p) * initial_density + p * qmats.X.dot(
        initial_density).dot(qmats.X)
    np.testing.assert_allclose(final_density, qam.wf_simulator.density)
def test_kraus_application_depolarizing():
    p = 0.372
    qam = PyQVM(
        n_qubits=1,
        quantum_simulator_type=ReferenceDensitySimulator,
        post_gate_noise_probabilities={"depolarizing": p},
    )
    rho = _random_1q_density()
    qam.wf_simulator.density = rho
    qam.execute_once(Program(I(0)))

    final_density = (1 - p) * rho + (p / 3) * (qmats.X.dot(rho).dot(qmats.X) +
                                               qmats.Y.dot(rho).dot(qmats.Y) +
                                               qmats.Z.dot(rho).dot(qmats.Z))
    np.testing.assert_allclose(final_density, qam.wf_simulator.density)
def test_kraus_compound_T1T2_application():
    p1 = 0.372
    p2 = 0.45
    qam = PyQVM(
        n_qubits=1,
        quantum_simulator_type=ReferenceDensitySimulator,
        post_gate_noise_probabilities={
            "relaxation": p1,
            "dephasing": p2
        },
    )
    rho = _random_1q_density()
    qam.wf_simulator.density = rho
    qam.execute_once(Program(I(0)))

    final_density = np.array([
        [rho[0, 0] + rho[1, 1] * p1, (1 - p2) * np.sqrt(1 - p1) * rho[0, 1]],
        [(1 - p2) * np.sqrt(1 - p1) * rho[1, 0], (1 - p1) * rho[1, 1]],
    ])
    np.testing.assert_allclose(final_density, qam.wf_simulator.density)
def test_multiqubit_decay_bellstate():
    program = Program(RY(np.pi / 3, 0), CNOT(0, 1))

    # commence manually dotting the above program
    initial_density = np.zeros((4, 4), dtype=complex)
    initial_density[0, 0] = 1.0

    gate_time_1q = 50e-9
    T1 = 30e-6
    T2 = 15e-6
    p1 = 1 - np.exp(-gate_time_1q / T1)
    p2 = 1 - np.exp(-gate_time_1q / T2)

    # RY
    gate_1 = np.kron(np.eye(2), qmats.RY(np.pi / 3))
    state = gate_1.dot(initial_density).dot(np.conj(gate_1).T)

    for ii in range(2):
        new_density = np.zeros_like(state)
        for kop in qmats.relaxation_operators(p1):
            operator = lifted_gate_matrix(matrix=kop,
                                          qubit_inds=[ii],
                                          n_qubits=2)
            new_density += operator.dot(state).dot(np.conj(operator).T)
        state = new_density

    for ii in range(2):
        new_density = np.zeros_like(state)
        for kop in qmats.dephasing_operators(p2):
            operator = lifted_gate_matrix(matrix=kop,
                                          qubit_inds=[ii],
                                          n_qubits=2)
            new_density += operator.dot(state).dot(np.conj(operator).T)
        state = new_density

    # CNOT
    # TODO: different 1q, 2q noise probabilities
    cnot_01 = np.kron(qmats.I, qmats.P0) + np.kron(qmats.X, qmats.P1)
    state = cnot_01.dot(state).dot(cnot_01.T)
    gate_time_2q = 150e-9
    p1 = 1 - np.exp(-gate_time_2q / T1)
    p2 = 1 - np.exp(-gate_time_2q / T2)

    for ii in range(2):
        new_density = np.zeros_like(state)
        for kop in qmats.relaxation_operators(p1):
            operator = lifted_gate_matrix(matrix=kop,
                                          qubit_inds=[ii],
                                          n_qubits=2)
            new_density += operator.dot(state).dot(np.conj(operator).T)
        state = new_density

    for ii in range(2):
        new_density = np.zeros_like(state)
        for kop in qmats.dephasing_operators(p2):
            operator = lifted_gate_matrix(matrix=kop,
                                          qubit_inds=[ii],
                                          n_qubits=2)
            new_density += operator.dot(state).dot(np.conj(operator).T)
        state = new_density

    qam = PyQVM(
        n_qubits=2,
        quantum_simulator_type=ReferenceDensitySimulator,
        post_gate_noise_probabilities={
            "relaxation": p1,
            "dephasing": p2
        },
    )
    qam.execute_once(program)

    assert np.allclose(qam.wf_simulator.density, state)