def unitary_channel(dimension,desired_fidelity,error):
    noise_operator = qt.to_super(qt.rand_unitary(dimension))
    count=0
    while np.abs(qt.average_gate_fidelity(noise_operator)-desired_fidelity)>error and count<400:
        noise_operator = qt.to_super(qt.rand_unitary(dimension))
        count=count+1
    if count>=400: 
        print("Could not achieve desired fidelity within margin of error")
    return noise_operator 
def two_qubit_cliffords():
    '''returns the two qubit clifford group as a list of qutip superoperators'''
    rot_cliffords = [qt.identity(2), qt.rotation((2/(np.sqrt(3))),(qt.sigmax()+qt.sigmay()+qt.sigmaz())/3),qt.rotation((4/(np.sqrt(3))),(qt.sigmax()+qt.sigmay()+qt.sigmaz())/3)]
    rot_class_cliffords  = [qt.to_super(qt.tensor(x,y)) for x in rot_cliffords for y in rot_cliffords]
    class_one_cliffords = [qt.to_super(qt.tensor(x,y)) for x in qt.qubit_clifford_group() for y in qt.qubit_clifford_group()]
    class_two_cliffords = [x*qt.to_super(qt.cnot())*y for x in class_one_cliffords for y in rot_class_cliffords]
    class_three_cliffords = [x*qt.to_super(qt.iswap())*y for x in class_one_cliffords for y in rot_class_cliffords]
    class_four_cliffords = [x*qt.to_super(qt.swap()) for x in class_one_cliffords]
    return class_one_cliffords+class_two_cliffords+ class_three_cliffords+ class_four_cliffords
def rotating_frame_transformation_new(U, t: float, H):
    """
    Transforms the frame of the unitary according to
        U' = U_{RF}*U*U_{RF}^dag
        NOTE: remember that this is how the time evolution operator changes from one picture to another

    Args:
        U (QObj): Unitary to be transformed
        t (float): time at which to transform
        H (QObj): hamiltonian to be rotated away

    """

    U_RF = (
        1j * H *
        t).expm()  #wrong: it shouldn't affect avgatefid_compsubspace though
    if U.type == 'super':
        U_RF = qtp.to_super(U_RF)

    U_prime = U_RF * U
    """ U_RF only on one side because that's the operator that
    satisfies the Schroedinger equation in the interaction picture.
    """

    return U_prime
def correct_reference(U, w_q1, w_q0, t):
    # w_qi should be a frequency (not including the 2*pi factor). Moreover they and t should be in the same scale.
    # this functions should be used just to make sanity checks.
    phase_to_correct_q1 = w_q1 * (2 * np.pi) * t
    phase_to_correct_q0 = w_q0 * (2 * np.pi) * t

    Ucorrection = qtp.Qobj(
        [[1, 0, 0, 0, 0, 0, 0, 0, 0],
         [0, np.exp(1j * phase_to_correct_q0), 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 1, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, np.exp(1j * phase_to_correct_q1), 0, 0, 0, 0, 0],
         [
             0, 0, 0, 0,
             np.exp(1j *
                    (phase_to_correct_q0 + phase_to_correct_q1)), 0, 0, 0, 0
         ], [0, 0, 0, 0, 0,
             np.exp(1j * phase_to_correct_q1), 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 1, 0, 0],
         [0, 0, 0, 0, 0, 0, 0,
          np.exp(1j * phase_to_correct_q0), 0], [0, 0, 0, 0, 0, 0, 0, 0, 1]],
        type='oper',
        dims=[[3, 3], [3, 3]])

    if U.type == 'oper':
        return Ucorrection * U
    elif U.type == 'super':
        return qtp.to_super(Ucorrection) * U
def rotating_frame_transformation(U,
                                  t: float,
                                  w_q0: float = 0,
                                  w_q1: float = 0):
    """
    Transforms the frame of the unitary according to
        U' = U_{RF}*U
        NOTE: remember that this is how the time evolution operator changes from one picture to another
    with
        U_{RF} = e^{-i w_q0 a^dag a t } otimes e^{-i w_q1 b^dag b t }
        (method for the case where we are simply rotating away the two qubit frequencies)

    Args:
        U (QObj): Unitary to be transformed
        t (float): time at which to transform
        w_q0 (float): freq of frame for q0
        w_q1 (float): freq of frame for q1

    """
    logging.warning(
        'Recommended to use rotating_frame_transformation_new passing the hamiltonian as an argument.'
    )

    U_RF = (1j * w_q0 * n_q0 * t).expm() * (1j * w_q1 * n_q1 * t).expm()
    if U.type == 'super':
        U_RF = qtp.to_super(U_RF)

    U_prime = U_RF * U
    """ U_RF only on one side because that's the operator that
    satisfies the Schroedinger equation in the interaction picture.
    """

    return U_prime
예제 #6
0
class TestTypeFromDims:
    @pytest.mark.parametrize(["base", "expected", "enforce_square"], [
        pytest.param([[2], [2]], 'oper', True),
        pytest.param([[2, 3], [2, 3]], 'oper', True),
        pytest.param([[2], [3]], 'other', True),
        pytest.param([[2], [3]], 'oper', False),
        pytest.param([[2], [1]], 'ket', True),
        pytest.param([[1], [2]], 'bra', True),
        pytest.param([[[2, 3], [2, 3]], [1]], 'operator-ket', True),
        pytest.param([[1], [[2, 3], [2, 3]]], 'operator-bra', True),
        pytest.param([[[3], [3]], [[2, 3], [2, 3]]], 'other', True),
        pytest.param([[[3], [3]], [[2, 3], [2, 3]]], 'super', False),
        pytest.param([[[2], [3, 3]], [[3], [2, 3]]], 'other', True),
    ])
    def test_type_from_dims(self, base, expected, enforce_square):
        assert type_from_dims(base, enforce_square=enforce_square) == expected

    @pytest.mark.parametrize("qobj", [
        pytest.param(qutip.rand_ket(10), id='ket'),
        pytest.param(qutip.rand_ket(10).dag(), id='bra'),
        pytest.param(qutip.rand_dm(10), id='oper'),
        pytest.param(qutip.to_super(qutip.rand_dm(10)), id='super'),
    ])
    def test_qobj_dims_match_qobj(self, qobj):
        assert type_from_dims(qobj.dims) == qobj.type
예제 #7
0
class Test_unitarity:
    @pytest.mark.parametrize(['operator', 'expected'], [
        pytest.param(to_super(sigmax()), 1, id="sigmax"),
        pytest.param(0.25 * sum(to_super(x) for x in paulis), 0, id="paulis"),
        pytest.param(0.5 * (to_super(qeye(2)) + to_super(sigmax())),
                     1 / 3,
                     id="id+sigmax"),
    ])
    def test_known_cases(self, operator, expected):
        assert unitarity(operator) == pytest.approx(expected, abs=1e-7)

    @pytest.mark.parametrize('n_qubits', [1, 2, 3, 4, 5])
    def test_bounded(self, n_qubits):
        tol = 1e-7
        operator = rand_super_bcsz(2**n_qubits)
        assert -tol <= unitarity(operator) <= 1 + tol
def pro_avfid_superoperator_phasecorrected(U,phases):
    """
    Average process (gate) fidelity in the whole space for a qubit and qutrit
    Qubit Z rotation and qutrit "Z" rotations are applied, taking into account the anharmonicity as well
    """
    Ucorrection = qtp.Qobj([[np.exp(-1j*np.deg2rad(phases[0])), 0, 0, 0, 0, 0, 0, 0, 0],
                     [0, np.exp(-1j*np.deg2rad(phases[1])), 0, 0, 0, 0, 0, 0, 0],
                     [0, 0, np.exp(-1j*np.deg2rad(phases[4]-phases[-1])), 0, 0, 0, 0, 0, 0],
                     [0, 0, 0, np.exp(-1j*np.deg2rad(phases[2])), 0, 0, 0, 0, 0],
                     [0, 0, 0, 0, np.exp(-1j*np.deg2rad(phases[3]-phases[-1])), 0, 0, 0, 0],
                     [0, 0, 0, 0, 0, np.exp(-1j*np.deg2rad(phases[4]-phases[-1]+phases[2]-phases[0])), 0, 0, 0],
                     [0, 0, 0, 0, 0, 0, np.exp(-1j*np.deg2rad(phases[5])), 0, 0],
                     [0, 0, 0, 0, 0, 0, 0, np.exp(-1j*np.deg2rad(phases[5]+phases[1]-phases[0])), 0],
                     [0, 0, 0, 0, 0, 0, 0, 0, np.exp(-1j*np.deg2rad(phases[4]-phases[-1]+phases[5]-phases[0]))]],
                    type='oper',
                    dims=[[3, 3], [3, 3]])

    if U.type=='oper':
        U=Ucorrection*U
        ptrace = np.abs((U.dag()*U_target).tr())**2
        dim = 9  # dimension of the whole space
        return np.real((ptrace+dim)/(dim*(dim+1)))

    elif U.type=='super':
        U=qtp.to_super(Ucorrection)*U
        return np.real(qtp.average_gate_fidelity(U,target=U_target_diffdims))
def transform_basis(C, S):
    # C (operator or superoperator)
    # S: matrix change of basis
    if C.type == 'oper':
        return S.dag() * C * S
    elif C.type == 'super':
        S = qtp.to_super(S)
        return S.dag() * C * S
def pro_avfid_superoperator_compsubspace_phasecorrected(U, L1, phases):
    """
    Average process (gate) fidelity in the qubit computational subspace for two qutrits
    Leakage has to be taken into account, see Woods & Gambetta
    The phase is corrected with Z rotations considering both transmons as qubits. The correction is done perfectly.
    The function assumes that the computational subspace (:= the 4 energy levels chosen as the two qubits) is given by 
            the standard basis |0> /otimes |0>, |0> /otimes |1>, |1> /otimes |0>, |1> /otimes |1>.
            If this is not the case, one need to change the basis to that one, before calling this function.
    """

    Ucorrection = qtp.Qobj(
        [[np.exp(-1j * np.deg2rad(phases[0])), 0, 0, 0, 0, 0, 0, 0, 0],
         [0, np.exp(-1j * np.deg2rad(phases[1])), 0, 0, 0, 0, 0, 0, 0],
         [0, 0, np.exp(-1j * np.deg2rad(phases[0])), 0, 0, 0, 0, 0, 0],
         [0, 0, 0, np.exp(-1j * np.deg2rad(phases[2])), 0, 0, 0, 0, 0],
         [
             0, 0, 0, 0,
             np.exp(-1j * np.deg2rad(phases[3] - phases[-1])), 0, 0, 0, 0
         ], [0, 0, 0, 0, 0,
             np.exp(-1j * np.deg2rad(phases[2])), 0, 0, 0],
         [0, 0, 0, 0, 0, 0,
          np.exp(-1j * np.deg2rad(phases[0])), 0, 0],
         [0, 0, 0, 0, 0, 0, 0,
          np.exp(-1j * np.deg2rad(phases[1])), 0],
         [0, 0, 0, 0, 0, 0, 0, 0,
          np.exp(-1j * np.deg2rad(phases[0]))]],
        type='oper',
        dims=[[3, 3], [3, 3]])

    if U.type == 'oper':
        U = Ucorrection * U
        inner = U.dag() * U_target
        part_idx = [0, 1, 3, 4]  # only computational subspace
        ptrace = 0
        for i in part_idx:
            ptrace += inner[i, i]
        dim = 4  # 2 qubits comp subspace

        return np.real(
            ((np.abs(ptrace))**2 + dim * (1 - L1)) / (dim * (dim + 1)))

    elif U.type == 'super':
        U = qtp.to_super(Ucorrection) * U
        kraus_form = qtp.to_kraus(U)
        dim = 4  # 2 qubits in the computational subspace
        part_idx = [0, 1, 3, 4]  # only computational subspace
        psum = 0
        for A_k in kraus_form:
            ptrace = 0
            inner = U_target_diffdims.dag(
            ) * A_k  # otherwise dimension mismatch
            for i in part_idx:
                ptrace += inner[i, i]
            psum += (np.abs(ptrace))**2

        return np.real((dim * (1 - L1) + psum) / (dim * (dim + 1)))
예제 #11
0
def time_series(U_final_vec_timeseries, S, weights, repetitions,
                samplingpoints_gaussian_q0, axis_overrotation):

    trace_PTM_vec = []
    trace_GTM_vec = []

    for n_rep in range(repetitions):
        print(n_rep)

        U_final_vec = np.copy(U_final_vec_timeseries)

        for i in range(len(U_final_vec)):
            if U_final_vec[i].type == 'oper':
                U_final_vec[i] = qtp.to_super(
                    U_final_vec[i]
                )  # weighted averaging needs to be done for superoperators

                over_rot = czf.qubit_to_2qutrit_unitary(
                    czf.bloch_sphere_rotation(samplingpoints_gaussian_q0[i],
                                              axis_overrotation), 'right')
                U_final_vec[i] = qtp.to_super(over_rot) * U_final_vec[i]

                U_final_vec[i] = U_final_vec[i]**n_rep
            U_final_vec[i] = U_final_vec[i] * weights[i]
        U_superop_average = np.sum(
            np.array(U_final_vec))  # computing resulting average propagator
        #print(czf.verify_CPTP(U_superop_average))

        U_superop_average = czf.correct_phases(U_superop_average)
        U_superop_average = transform_basis(U_superop_average, S.dag())

        GTM = get_PTM_or_GTM(U_superop_average, 'GTM')
        PTM = get_PTM_or_GTM(U_superop_average, 'PTM')
        T_GTM = extract_T_matrix(GTM)
        T_PTM = extract_T_matrix(PTM)

        trace_PTM = np.trace(T_PTM)
        trace_GTM = np.trace(T_GTM)

        trace_GTM_vec.append(trace_GTM)
        trace_PTM_vec.append(trace_PTM)

    return trace_GTM_vec, trace_PTM_vec
예제 #12
0
    def test_reshuffle(self):
        U1 = rand_unitary(2)
        U2 = rand_unitary(3)
        U3 = rand_unitary(4)

        U = tensor(U1, U2, U3)
        S = to_super(U)
        S_col = reshuffle(S)

        assert_equal(S_col.dims[0], [[2, 2], [3, 3], [4, 4]])

        assert_(reshuffle(S_col) == S)
예제 #13
0
def calc_populations(U):

    hadamard_singleq = qtp.Qobj([[1, 1, 0], [1, -1, 0], [0, 0, 0]
                                 ]) / np.sqrt(2)
    hadamard_q0 = qtp.tensor(qtp.qeye(3), hadamard_singleq)

    if U.type == 'oper':
        U_pi2_pulsed = hadamard_q0 * U * hadamard_q0
        populations = {
            'population_in_0': np.abs(U_pi2_pulsed[0, 0])**2,
            'population_in_1': np.abs(U_pi2_pulsed[0, 1])**2
        }
    elif U.type == 'super':
        U_pi2_pulsed = qtp.to_super(hadamard_q0) * U * qtp.to_super(
            hadamard_q0)
        populations = {
            'population_in_0': np.real(U_pi2_pulsed[0, 0]),
            'population_in_1': np.real(U_pi2_pulsed[0, 10])
        }

    return populations
예제 #14
0
    def test_reshuffle(self):
        U1 = rand_unitary(2)
        U2 = rand_unitary(3)
        U3 = rand_unitary(4)

        U = tensor(U1, U2, U3)
        S = to_super(U)
        S_col = reshuffle(S)

        assert_equal(S_col.dims[0], [[2, 2], [3, 3], [4, 4]])

        assert_(reshuffle(S_col) == S)
예제 #15
0
def pro_avfid_superoperator_compsubspace_phasecorrected(U, L1, phases):
    """
    Average process (gate) fidelity in the qubit computational subspace for two qutrits
    Leakage has to be taken into account, see Woods & Gambetta
    The phase is corrected with Z rotations considering both transmons as qubits
    """

    Ucorrection = qtp.Qobj(
        [[np.exp(-1j * np.deg2rad(phases[0])), 0, 0, 0, 0, 0, 0, 0, 0],
         [0, np.exp(-1j * np.deg2rad(phases[1])), 0, 0, 0, 0, 0, 0, 0],
         [0, 0, np.exp(-1j * np.deg2rad(phases[0])), 0, 0, 0, 0, 0, 0],
         [0, 0, 0, np.exp(-1j * np.deg2rad(phases[2])), 0, 0, 0, 0, 0],
         [
             0, 0, 0, 0,
             np.exp(-1j * np.deg2rad(phases[3] - phases[-1])), 0, 0, 0, 0
         ], [0, 0, 0, 0, 0,
             np.exp(-1j * np.deg2rad(phases[2])), 0, 0, 0],
         [0, 0, 0, 0, 0, 0,
          np.exp(-1j * np.deg2rad(phases[0])), 0, 0],
         [0, 0, 0, 0, 0, 0, 0,
          np.exp(-1j * np.deg2rad(phases[1])), 0],
         [0, 0, 0, 0, 0, 0, 0, 0,
          np.exp(-1j * np.deg2rad(phases[0]))]],
        type='oper',
        dims=[[3, 3], [3, 3]])

    if U.type == 'oper':
        U = Ucorrection * U
        inner = U.dag() * U_target
        part_idx = [0, 1, 3, 4]  # only computational subspace
        ptrace = 0
        for i in part_idx:
            ptrace += inner[i, i]
        dim = 4  # 2 qubits comp subspace

        return np.real(
            ((np.abs(ptrace))**2 + dim * (1 - L1)) / (dim * (dim + 1)))

    elif U.type == 'super':
        U = qtp.to_super(Ucorrection) * U
        kraus_form = qtp.to_kraus(U)
        dim = 4  # 2 qubits in the computational subspace
        part_idx = [0, 1, 3, 4]  # only computational subspace
        psum = 0
        for A_k in kraus_form:
            ptrace = 0
            inner = U_target_diffdims.dag(
            ) * A_k  # otherwise dimension mismatch
            for i in part_idx:
                ptrace += inner[i, i]
            psum += (np.abs(ptrace))**2

        return np.real((dim * (1 - L1) + psum) / (dim * (dim + 1)))
def pro_avfid_superoperator_phasecorrected(U, phases):
    """
    Average process (gate) fidelity in the whole space for two qutrits
    Qubit Z rotation and qutrit "Z" rotations are applied, taking into account the anharmonicity as well.
    The function assumes that the computational subspace (:= the 4 energy levels chosen as the two qubits) is given by 
            the standard basis |0> /otimes |0>, |0> /otimes |1>, |1> /otimes |0>, |1> /otimes |1>.
            If this is not the case, one need to change the basis to that one, before calling this function.
    This function is quite useless because we are always interested in the computational subspace only.
    """
    Ucorrection = qtp.Qobj(
        [[np.exp(-1j * np.deg2rad(phases[0])), 0, 0, 0, 0, 0, 0, 0, 0],
         [0, np.exp(-1j * np.deg2rad(phases[1])), 0, 0, 0, 0, 0, 0, 0],
         [
             0, 0,
             np.exp(-1j * np.deg2rad(phases[4] - phases[-1])), 0, 0, 0, 0, 0, 0
         ], [0, 0, 0,
             np.exp(-1j * np.deg2rad(phases[2])), 0, 0, 0, 0, 0],
         [
             0, 0, 0, 0,
             np.exp(-1j * np.deg2rad(phases[3] - phases[-1])), 0, 0, 0, 0
         ],
         [
             0, 0, 0, 0, 0,
             np.exp(
                 -1j *
                 np.deg2rad(phases[4] - phases[-1] + phases[2] - phases[0])),
             0, 0, 0
         ], [0, 0, 0, 0, 0, 0,
             np.exp(-1j * np.deg2rad(phases[5])), 0, 0],
         [
             0, 0, 0, 0, 0, 0, 0,
             np.exp(-1j * np.deg2rad(phases[5] + phases[1] - phases[0])), 0
         ],
         [
             0, 0, 0, 0, 0, 0, 0, 0,
             np.exp(-1j *
                    np.deg2rad(phases[4] - phases[-1] + phases[5] - phases[0]))
         ]],
        type='oper',
        dims=[[3, 3], [3, 3]])

    if U.type == 'oper':
        U = Ucorrection * U
        ptrace = np.abs((U.dag() * U_target).tr())**2
        dim = 9  # dimension of the whole space
        return np.real((ptrace + dim) / (dim * (dim + 1)))

    elif U.type == 'super':
        U = qtp.to_super(Ucorrection) * U
        return np.real(qtp.average_gate_fidelity(U, target=U_target_diffdims))
예제 #17
0
def verify_phicond(
    U
):  # benchmark to check that cond phase is computed correctly. Benchmark succeeded
    # superoperator case
    if U.type == 'oper':
        U = qtp.to_super(U)

    def calc_phi(U, list):
        # lists of 4 matrix elements 0 or 1
        number = 3 * list[0] + list[1] + list[2] * 27 + list[3] * 9
        phase = np.rad2deg(np.angle(U[number, number]))
        return phase

    phi_01 = calc_phi(U, [0, 1, 0, 0])
    phi_10 = calc_phi(U, [1, 0, 0, 0])
    phi_11 = calc_phi(U, [1, 1, 0, 0])
    phi_cond = (phi_11 - phi_01 - phi_10) % 360
    print(phi_cond)

    phi_01 = -calc_phi(U, [0, 0, 0, 1])
    phi_10 = calc_phi(U, [1, 0, 0, 1])
    phi_11 = calc_phi(U, [1, 1, 0, 1])
    phi_cond = (phi_11 - phi_01 - phi_10) % 360
    print(phi_cond)

    phi_01 = -calc_phi(U, [0, 0, 1, 0])
    phi_10 = calc_phi(U, [0, 1, 1, 0])
    phi_11 = calc_phi(U, [1, 1, 1, 0])
    phi_cond = (phi_11 - phi_01 - phi_10) % 360
    print(phi_cond)

    phi_01 = -calc_phi(U, [0, 0, 1, 1])
    phi_10 = calc_phi(U, [0, 1, 1, 1])
    phi_11 = -calc_phi(U, [1, 0, 1, 1])
    phi_cond = (phi_11 - phi_01 - phi_10) % 360
    print(phi_cond)
    return phi_cond
예제 #18
0
파일: spectrum.py 프로젝트: JonCYeh/GKP_DD
def state_twirl(N):
    square = itertools.product(range(-N, N + 1, 1), range(-N, N + 1, 1))
    Twirl = sum(Prob(n, m, N) * qt.to_super(Disp(n, m)) for n, m in square)
    return Twirl
예제 #19
0
파일: spectrum.py 프로젝트: JonCYeh/GKP_DD
def chan_twirl(S, N):
    square = itertools.product(range(-N, N + 1, 1), range(-N, N + 1, 1))
    Twirled = sum(
        Prob(n, m, N) * qt.to_super(Disp(-n, -m)) * S * qt.to_super(Disp(n, m))
        for n, m in square)
    return Twirled
예제 #20
0
Hq2_t_ind = qt.tensor(Iq1, rot2)  #Hq2_rot(constant term)
Hq2_t_dep = qt.tensor(Iq1, q2Freqs)  #Hq2_rot(modulation term)
Hint = QQ.Hint12 * (2 * pi)
H_rot = [Hq1_lab + Hq2_t_ind + Hint, [Hq2_t_dep, MW_shaped]]
tgstart = 48
tgend = 48

for gt in range(tgstart, tgend + 1):

    pulsesystem = CZpulse(Q1, Q2, g, the_f=0.88, lambda2=0.13, gatetime=gt)
    tg = pulsesystem.tg
    t_list, adiabaticpulse = pulsesystem.netzeropulse()
    degeneracy_freq = pulsesystem.qFreq20

    args = {'mwamp': 1.0, 'shape': adiabaticpulse}
    #res = qt.sesolve(H_rot, ini_state, t_list, e_ops=[], args=args, options=opts, progress_bar=None)
    _res = qt.propagator(H_rot,
                         t_list,
                         e_ops=[],
                         args=args,
                         options=opts,
                         progress_bar=None)
    res = []
    for i in range(len(_res)):
        sp = qt.to_super(_res[i])
        res.append(sp)
    res = np.array(res)

    print(len(res))
    print(res[1].dims)
    print(res[1].shape)
예제 #21
0
    def acquire_data_point(self, **kw):

        ### Extract relevant parameters to recreate the instrument locally (necessary for parallelization since intruments cannot be pickled)
        fluxlutman_args = {
            'sampling_rate': self.fluxlutman.sampling_rate(),
            'cz_length': self.fluxlutman.cz_length(),
            'q_J2': self.fluxlutman.q_J2(),
            'czd_double_sided': self.fluxlutman.czd_double_sided(),
            'cz_lambda_2': self.fluxlutman.cz_lambda_2(),
            'cz_lambda_3': self.fluxlutman.cz_lambda_3(),
            'cz_theta_f': self.fluxlutman.cz_theta_f(),
            'czd_length_ratio': self.fluxlutman.czd_length_ratio(),
            'q_polycoeffs_freq_01_det':
            self.fluxlutman.q_polycoeffs_freq_01_det(),
            'q_polycoeffs_anharm': self.fluxlutman.q_polycoeffs_anharm(),
            'q_freq_01': self.fluxlutman.q_freq_01(),
            'q_freq_10': self.fluxlutman.q_freq_10()
        }

        noise_parameters_CZ_args = {
            'Z_rotations_length':
            self.noise_parameters_CZ.Z_rotations_length(),
            'voltage_scaling_factor':
            self.noise_parameters_CZ.voltage_scaling_factor(),
            'distortions':
            self.noise_parameters_CZ.distortions(),
            'T1_q0':
            self.noise_parameters_CZ.T1_q0(),
            'T1_q1':
            self.noise_parameters_CZ.T1_q1(),
            'T2_q0_amplitude_dependent':
            self.noise_parameters_CZ.T2_q0_amplitude_dependent(),
            'T2_q1':
            self.noise_parameters_CZ.T2_q1(),
            'w_q1_sweetspot':
            self.noise_parameters_CZ.w_q1_sweetspot(),
            'alpha_q1':
            self.noise_parameters_CZ.alpha_q1(),
            'w_bus':
            self.noise_parameters_CZ.w_bus(),
            'dressed_compsub':
            self.noise_parameters_CZ.dressed_compsub(),
            'sigma_q0':
            self.noise_parameters_CZ.sigma_q0(),
            'sigma_q1':
            self.noise_parameters_CZ.sigma_q1(),
            'T2_scaling':
            self.noise_parameters_CZ.T2_scaling()
        }

        ### Discretize average (integral) over a Gaussian distribution
        mean = 0
        sigma_q0 = self.noise_parameters_CZ.sigma_q0()
        sigma_q1 = self.noise_parameters_CZ.sigma_q1(
        )  # one for each qubit, in units of Phi_0
        # 4e-6 is the same value as in the surface-17 paper of tom&brian. We see that 25 reproduces the T_phi^quasi-static for a Ramsey exp.

        qoi_plot = [
        ]  # used to verify convergence properties. If len(n_sampling_gaussian_vec)==1, it is useless
        n_sampling_gaussian_vec = self.noise_parameters_CZ.n_sampling_gaussian_vec(
        )  # 11 guarantees excellent convergence.
        # We choose it odd so that the central point of the Gaussian is included.
        # ALWAYS choose it odd
        for n_sampling_gaussian in n_sampling_gaussian_vec:
            # If sigma=0 there's no need for sampling
            if sigma_q0 != 0:
                samplingpoints_gaussian_q0 = np.linspace(
                    -5 * sigma_q0, 5 * sigma_q0,
                    n_sampling_gaussian)  # after 5 sigmas we cut the integral
                delta_x_q0 = samplingpoints_gaussian_q0[
                    1] - samplingpoints_gaussian_q0[0]
                values_gaussian_q0 = czf.gaussian(samplingpoints_gaussian_q0,
                                                  mean, sigma_q0)
            else:
                samplingpoints_gaussian_q0 = np.array([0])
                delta_x_q0 = 1
                values_gaussian_q0 = np.array([1])
            if sigma_q1 != 0:
                samplingpoints_gaussian_q1 = np.linspace(
                    -5 * sigma_q1, 5 * sigma_q1,
                    n_sampling_gaussian)  # after 5 sigmas we cut the integral
                delta_x_q1 = samplingpoints_gaussian_q1[
                    1] - samplingpoints_gaussian_q1[0]
                values_gaussian_q1 = czf.gaussian(samplingpoints_gaussian_q1,
                                                  mean, sigma_q1)
            else:
                samplingpoints_gaussian_q1 = np.array([0])
                delta_x_q1 = 1
                values_gaussian_q1 = np.array([1])

            input_to_parallelize = []
            weights = []
            number = -1  # used to number instruments that are created in the parallelization, to avoid conflicts

            for j_q0 in range(len(samplingpoints_gaussian_q0)):
                fluxbias_q0 = samplingpoints_gaussian_q0[
                    j_q0]  # q0 fluxing qubit
                for j_q1 in range(len(samplingpoints_gaussian_q1)):
                    fluxbias_q1 = samplingpoints_gaussian_q1[
                        j_q1]  # q1 spectator qubit

                    number = number + 1

                    if self.noise_parameters_CZ.cluster():
                        input_point = {
                            'fluxbias_q0':
                            fluxbias_q0,  # need to pass it like this to the cluster
                            'fluxbias_q1': fluxbias_q1,
                            'fluxlutman_args': fluxlutman_args,
                            'noise_parameters_CZ_args':
                            noise_parameters_CZ_args,
                            'fitted_stepresponse_ty':
                            self.fitted_stepresponse_ty,
                            'number': number,
                            'cluster': self.noise_parameters_CZ.cluster()
                        }
                    else:
                        input_point = {
                            'fluxbias_q0':
                            fluxbias_q0,  # need to pass it like this to the cluster
                            'fluxbias_q1': fluxbias_q1,
                            'fluxlutman': self.fluxlutman,
                            'noise_parameters_CZ': self.noise_parameters_CZ,
                            'fitted_stepresponse_ty':
                            self.fitted_stepresponse_ty,
                            'number': number,
                            'cluster': self.noise_parameters_CZ.cluster()
                        }

                    weight = values_gaussian_q0[
                        j_q0] * delta_x_q0 * values_gaussian_q1[
                            j_q1] * delta_x_q1
                    weights.append(weight)

                    input_to_parallelize.append(input_point)

            if self.noise_parameters_CZ.cluster():
                y_list_of_lists = map_jobqueue_repeat(
                    compute_propagator_parallelizable, input_to_parallelize
                )  # function defined in notebook cluster

                y_list_of_lists = np.array(y_list_of_lists)
                U_final_vec = y_list_of_lists[:, 0]
                t_final_vec = y_list_of_lists[:, 1]
            else:
                U_final_vec = []
                t_final_vec = []
                for input_arglist in input_to_parallelize:
                    result_list = compute_propagator_parallelizable(
                        input_arglist)
                    U_final_vec.append(result_list[0])
                    t_final_vec.append(result_list[1])

            for i in range(len(U_final_vec)):
                if U_final_vec[i].type == 'oper':
                    U_final_vec[i] = qtp.to_super(
                        U_final_vec[i]
                    )  # weighted averaging needs to be done for superoperators
                U_final_vec[i] = U_final_vec[i] * weights[i]
            U_superop_average = np.sum(np.array(
                U_final_vec))  # computing resulting average propagator
            #print(czf.verify_CPTP(U_superop_average))

            t_final = t_final_vec[
                0]  # equal for all entries, we need it to compute phases in the rotating frame
            w_q0, w_q1 = czf.dressed_frequencies(
                self.fluxlutman, self.noise_parameters_CZ
            )  # needed to compute phases in the rotating frame

            qoi = czf.simulate_quantities_of_interest_superoperator_new(
                U=U_superop_average, t_final=t_final, w_q0=w_q0, w_q1=w_q1)
            if self.noise_parameters_CZ.look_for_minimum(
            ):  # if we look only for the minimum avgatefid_pc in the heat maps,
                # then we optimize the search via higher-order cost function
                cost_func_val = (
                    -np.log10(1 - qoi['avgatefid_compsubspace_pc']))**4
            else:
                cost_func_val = (
                    -np.log10(1 - qoi['avgatefid_compsubspace_pc']))

            quantities_of_interest = [
                cost_func_val, qoi['phi_cond'], qoi['L1'] * 100,
                qoi['L2'] * 100, qoi['avgatefid_pc'] * 100,
                qoi['avgatefid_compsubspace_pc'] * 100, qoi['phase_q0'],
                qoi['phase_q1'], qoi['avgatefid_compsubspace'] * 100,
                qoi['avgatefid_compsubspace_pc_onlystaticqubit'] * 100,
                qoi['population_02_state'] * 100
            ]
            qoi_vec = np.array(quantities_of_interest)
            qoi_plot.append(qoi_vec)

        qoi_plot = np.array(qoi_plot)

        ## Plot to study the convergence properties of averaging over a Gaussian
        # for i in range(len(qoi_plot[0])):
        #     czf.plot(x_plot_vec=[n_sampling_gaussian_vec],
        #                   y_plot_vec=[qoi_plot[:,i]],
        #                   title='Study of convergence of average',
        #                   xlabel='n_sampling_gaussian points',ylabel=self.value_names[i])


        return qoi_plot[0,0], qoi_plot[0,1], qoi_plot[0,2], qoi_plot[0,3], qoi_plot[0,4], qoi_plot[0,5], qoi_plot[0,6], \
               qoi_plot[0,7], qoi_plot[0,8], qoi_plot[0,9], qoi_plot[0,10]
예제 #22
0
    def acquire_data_point(self, **kw):

        ramsey = self.control_parameters_ramsey.ramsey(
        )  # True for Ram-Z, False for Echo-Z
        sigma = self.control_parameters_ramsey.sigma(
        )  # width of the Gaussian distribution of the fluxbias
        detuning = self.control_parameters_ramsey.detuning_ramsey(
        )  # how much the freq of q0 is offset from the sweetspot

        t = self.control_parameters_ramsey.pulse_length(
        )  # separation time between the two pi/2 pulses

        qoi_plot = list(
        )  # used to verify convergence properties. If len(n_sampling_gaussian_vec)==1, it is useless
        n_sampling_gaussian_vec = [
            101
        ]  # 11 guarantees excellent convergence. We choose it odd so that the central point of the Gaussian is included.
        # ALWAYS choose it odd
        for n_sampling_gaussian in n_sampling_gaussian_vec:
            # If sigma=0 there's no need for sampling
            weights = []
            if sigma != 0:
                samplingpoints_gaussian = np.linspace(
                    -5 * sigma, 5 * sigma,
                    n_sampling_gaussian)  # after 5 sigmas we cut the integral
                delta_x = samplingpoints_gaussian[1] - samplingpoints_gaussian[
                    0]
                values_gaussian = czu.gaussian(samplingpoints_gaussian,
                                               mean=0,
                                               sigma=sigma)
            else:
                samplingpoints_gaussian = np.array([0])
                delta_x = 1
                values_gaussian = np.array([1])

            U_final_vec = list()

            for j_q0 in range(len(samplingpoints_gaussian)):
                fluxbias_q0 = samplingpoints_gaussian[j_q0]
                if sigma != 0:
                    weight = values_gaussian[j_q0] * delta_x
                    weights.append(weight)
                else:
                    weight = 1
                    weights.append(weight)

                f_q0_sweetspot = self.fluxlutman.q_freq_01()
                f_q0_detuned = f_q0_sweetspot + detuning

                H = []
                if ramsey:  # the freq shift takes a different sign at first order on the two sides of Echo-Z
                    positive = [True]
                else:
                    positive = [True, False]

                for pos in positive:
                    f_q0_biased = freq_shift_from_fluxbias(f_q0_detuned,
                                                           f_q0_sweetspot,
                                                           fluxbias_q0,
                                                           positive_arc=pos)
                    freq_rotating_frame_detuned = f_q0_biased - f_q0_sweetspot - detuning
                    H.append(
                        czu.coupled_transmons_hamiltonian_new(
                            w_q0=freq_rotating_frame_detuned,
                            w_q1=0,
                            alpha_q0=-2 * freq_rotating_frame_detuned,
                            alpha_q1=0,
                            J=0))
                    # convenient way of getting the uncpupled Hamiltonian for one qubit
                sim_step = t / len(positive)

                c_ops = []

                U_final = time_evolution(H, c_ops, sim_step)
                if U_final.type == 'oper':
                    U_final = qtp.to_super(U_final)
                U_final_vec.append(U_final * weight)

            weights = np.array(weights)

            U_superop_average = np.sum(
                np.array(U_final_vec))  # computing resulting superoperator

            qoi = calc_populations(U_superop_average)
            quantities_of_interest = [
                qoi['population_in_0'] * 100, qoi['population_in_1'] * 100
            ]
            qoi_vec = np.array(quantities_of_interest)

            qoi_plot.append(qoi_vec)

        qoi_plot = np.array(qoi_plot)

        ### Plot to study the convergence properties of averaging over a Gaussian
        # for i in range(len(qoi_plot[0])):
        #     czu.plot(x_plot_vec=[n_sampling_gaussian_vec],
        #                   y_plot_vec=[qoi_plot[:,i]],
        #                   title='Study of convergence of average',
        #                   xlabel='n_sampling_gaussian points',ylabel=self.value_names[i])

        return qoi_plot[0, 0], qoi_plot[0, 1]
예제 #23
0
def overrotation(x):
    return to_super((1j * np.pi * x * sigmax() / 2).expm())
    def acquire_data_point(self, **kw):

        #czf.plot_spectrum(fluxlutman=self.fluxlutman,noise_parameters_CZ=self.noise_parameters_CZ)
        
        ### Discretize average (integral) over a Gaussian distribution
        mean = 0
        sigma_q0 = self.noise_parameters_CZ.sigma_q0()
        sigma_q1 = self.noise_parameters_CZ.sigma_q1()          # one for each qubit, in units of Phi_0
                 # 4e-6 is the same value as in the surface-17 paper of tom&brian. We see that 25 reproduces the T_phi^quasi-static for a Ramsey exp.

        qoi_plot = []    # used to verify convergence properties. If len(n_sampling_gaussian_vec)==1, it is useless
        n_sampling_gaussian_vec = self.noise_parameters_CZ.n_sampling_gaussian_vec()  # 11 guarantees excellent convergence.
                                                                                          # We choose it odd so that the central point of the Gaussian is included.
                                                                                          # ALWAYS choose it odd
        for n_sampling_gaussian in n_sampling_gaussian_vec:
            # If sigma=0 there's no need for sampling
            if sigma_q0 != 0:
                samplingpoints_gaussian_q0 = np.linspace(-5*sigma_q0,5*sigma_q0,n_sampling_gaussian)    # after 5 sigmas we cut the integral
                delta_x_q0 = samplingpoints_gaussian_q0[1]-samplingpoints_gaussian_q0[0]
                values_gaussian_q0 = czf.gaussian(samplingpoints_gaussian_q0,mean,sigma_q0)
            else:
                samplingpoints_gaussian_q0 = np.array([0])
                delta_x_q0 = 1
                values_gaussian_q0 = np.array([1])
            if sigma_q1 != 0:
                samplingpoints_gaussian_q1 = np.linspace(-5*sigma_q1,5*sigma_q1,n_sampling_gaussian)    # after 5 sigmas we cut the integral
                delta_x_q1 = samplingpoints_gaussian_q1[1]-samplingpoints_gaussian_q1[0]
                values_gaussian_q1 = czf.gaussian(samplingpoints_gaussian_q1,mean,sigma_q1)
            else:
                samplingpoints_gaussian_q1 = np.array([0])
                delta_x_q1 = 1
                values_gaussian_q1 = np.array([1])



            input_to_parallelize = []
            weights=[]
            number=-1           # used to number instruments that are created in the parallelization, to avoid conflicts

            
            for j_q0 in range(len(samplingpoints_gaussian_q0)):
                fluxbias_q0 = samplingpoints_gaussian_q0[j_q0]                     # q0 fluxing qubit
                for j_q1 in range(len(samplingpoints_gaussian_q1)): 
                    fluxbias_q1 = samplingpoints_gaussian_q1[j_q1]                 # q1 spectator qubit

                    input_point = {'fluxbias_q0': fluxbias_q0,                  # need to pass it like this to the cluster
                                   'fluxbias_q1': fluxbias_q1,
                                   'fluxlutman': self.fluxlutman,
                                   'noise_parameters_CZ': self.noise_parameters_CZ,
                                   'fitted_stepresponse_ty': self.fitted_stepresponse_ty}

                    weight = values_gaussian_q0[j_q0]*delta_x_q0 * values_gaussian_q1[j_q1]*delta_x_q1
                    weights.append(weight)

                    input_to_parallelize.append(input_point)


            U_final_vec = []
            t_final_vec = []
            for input_arglist in input_to_parallelize:
                result_list = compute_propagator(input_arglist)
                U_final_vec.append(result_list[0])
                t_final_vec.append(result_list[1])


            for i in range(len(U_final_vec)):
                if U_final_vec[i].type == 'oper':
                    U_final_vec[i] = qtp.to_super(U_final_vec[i])           # weighted averaging needs to be done for superoperators
                U_final_vec[i] = U_final_vec[i] * weights[i]
            U_superop_average = np.sum(np.array(U_final_vec))               # computing resulting average propagator
            #print(czf.verify_CPTP(U_superop_average))


            t_final = t_final_vec[0]                                        # equal for all entries, we need it to compute phases in the rotating frame
            w_q0, w_q1, alpha_q0 = czf.dressed_frequencies(self.fluxlutman, self.noise_parameters_CZ)     # needed to compute phases in the rotating frame

            qoi = czf.quantities_of_interest_ramsey(U=U_superop_average,initial_state=self.noise_parameters_CZ.initial_state(),fluxlutman=self.fluxlutman,noise_parameters_CZ=self.noise_parameters_CZ)

            quantities_of_interest = [qoi['population_higher_state'], qoi['population_lower_state']]
            qoi_vec=np.array(quantities_of_interest)
            qoi_plot.append(qoi_vec)


        qoi_plot = np.array(qoi_plot)

        ## Uncomment to study the convergence properties of averaging over a Gaussian
        # for i in range(len(qoi_plot[0])):
        #     czf.plot(x_plot_vec=[n_sampling_gaussian_vec],
        #                   y_plot_vec=[qoi_plot[:,i]],
        #                   title='Study of convergence of average',
        #                   xlabel='n_sampling_gaussian points',ylabel=self.value_names[i])


        return qoi_plot[0,0], qoi_plot[0,1]
예제 #25
0
 def test_unitaries_equal_1(self, dimension):
     """Tests that for random unitaries U, AGF(U, U) = 1."""
     tol = 1e-7
     U = rand_unitary_haar(dimension)
     SU = to_super(U)
     assert average_gate_fidelity(SU, target=U) == pytest.approx(1, abs=tol)
예제 #26
0
    def acquire_data_point(self, **kw):

        ### Discretize average (integral) over a Gaussian distribution
        mean = 0
        sigma_q0 = self.noise_parameters_CZ.sigma_q0()
        sigma_q1 = self.noise_parameters_CZ.sigma_q1(
        )  # one for each qubit, in units of Phi_0

        qoi_plot = [
        ]  # used to verify convergence properties. If len(n_sampling_gaussian_vec)==1, it is useless
        n_sampling_gaussian_vec = self.noise_parameters_CZ.n_sampling_gaussian_vec(
        )  # 11 guarantees excellent convergence.
        # We choose it odd so that the central point of the Gaussian is included.
        # Always choose it odd
        for n_sampling_gaussian in n_sampling_gaussian_vec:
            # If sigma=0 there's no need for sampling
            if sigma_q0 != 0:
                samplingpoints_gaussian_q0 = np.linspace(
                    -5 * sigma_q0, 5 * sigma_q0,
                    n_sampling_gaussian)  # after 5 sigmas we cut the integral
                delta_x_q0 = samplingpoints_gaussian_q0[
                    1] - samplingpoints_gaussian_q0[0]
                values_gaussian_q0 = czf.gaussian(samplingpoints_gaussian_q0,
                                                  mean, sigma_q0)
            else:
                samplingpoints_gaussian_q0 = np.array([0])
                delta_x_q0 = 1
                values_gaussian_q0 = np.array([1])
            if sigma_q1 != 0:
                samplingpoints_gaussian_q1 = np.linspace(
                    -5 * sigma_q1, 5 * sigma_q1,
                    n_sampling_gaussian)  # after 5 sigmas we cut the integral
                delta_x_q1 = samplingpoints_gaussian_q1[
                    1] - samplingpoints_gaussian_q1[0]
                values_gaussian_q1 = czf.gaussian(samplingpoints_gaussian_q1,
                                                  mean, sigma_q1)
            else:
                samplingpoints_gaussian_q1 = np.array([0])
                delta_x_q1 = 1
                values_gaussian_q1 = np.array([1])

            input_to_parallelize = [
            ]  # This is actually the input that was parallelized in an old version.
            # Currently it just creates a list that is provided sequentially to compute_propagator
            weights = []
            number = -1  # used to number instruments that are created in the parallelization, to avoid conflicts in the cluster

            for j_q0 in range(len(samplingpoints_gaussian_q0)):
                fluxbias_q0 = samplingpoints_gaussian_q0[
                    j_q0]  # q0 fluxing qubit
                for j_q1 in range(len(samplingpoints_gaussian_q1)):
                    fluxbias_q1 = samplingpoints_gaussian_q1[
                        j_q1]  # q1 spectator qubit

                    input_point = {
                        'fluxbias_q0': fluxbias_q0,
                        'fluxbias_q1': fluxbias_q1,
                        'fluxlutman': self.fluxlutman,
                        'noise_parameters_CZ': self.noise_parameters_CZ,
                        'fitted_stepresponse_ty': self.fitted_stepresponse_ty
                    }

                    weight = values_gaussian_q0[
                        j_q0] * delta_x_q0 * values_gaussian_q1[
                            j_q1] * delta_x_q1
                    weights.append(weight)

                    input_to_parallelize.append(input_point)

            U_final_vec = []
            t_final_vec = []
            for input_arglist in input_to_parallelize:
                result_list = compute_propagator(input_arglist)
                U_final_vec.append(result_list[0])
                t_final_vec.append(result_list[1])

            t_final = t_final_vec[
                0]  # equal for all entries, we need it to compute phases in the rotating frame
            #w_q0, w_q1, alpha_q0, alpha_q1 = czf.dressed_frequencies(self.fluxlutman, self.noise_parameters_CZ)     # needed to compute phases in the rotating frame
            # not used anymore

            ## Reproducing Leo's plots of cond_phase and leakage vs. flux offset (I order vs II order)
            #czf.sensitivity_to_fluxoffsets(U_final_vec,input_to_parallelize,t_final,self.fluxlutman,self.noise_parameters_CZ)

            for i in range(len(U_final_vec)):
                if U_final_vec[i].type == 'oper':
                    U_final_vec[i] = qtp.to_super(
                        U_final_vec[i]
                    )  # weighted averaging needs to be done for superoperators
                U_final_vec[i] = U_final_vec[i] * weights[i]
            U_superop_average = sum(
                U_final_vec)  # computing resulting average propagator
            #print(czf.verify_CPTP(U_superop_average))

            qoi = czf.simulate_quantities_of_interest_superoperator_new(
                U=U_superop_average,
                t_final=t_final,
                fluxlutman=self.fluxlutman,
                noise_parameters_CZ=self.noise_parameters_CZ)

            if self.noise_parameters_CZ.look_for_minimum(
            ):  # if we look only for the minimum avgatefid_pc in the heat maps,
                # then we optimize the search via higher-order cost function
                cost_func_val = (
                    -np.log10(1 - qoi['avgatefid_compsubspace_pc']))**4
            else:
                cost_func_val = (
                    -np.log10(1 - qoi['avgatefid_compsubspace_pc']))

            quantities_of_interest = [
                cost_func_val, qoi['phi_cond'], qoi['L1'] * 100,
                qoi['L2'] * 100, qoi['avgatefid_pc'] * 100,
                qoi['avgatefid_compsubspace_pc'] * 100, qoi['phase_q0'],
                qoi['phase_q1'], qoi['avgatefid_compsubspace'] * 100,
                qoi['avgatefid_compsubspace_pc_onlystaticqubit'] * 100,
                qoi['population_02_state'] * 100, qoi['cond_phase02'],
                qoi['coherent_leakage11'] * 100,
                qoi['offset_difference'] * 100, qoi['missing_fraction'] * 100,
                qoi['population_transfer_12_21'] * 100,
                qoi['population_transfer_12_03'] * 100,
                qoi['phase_diff_12_02'], qoi['phase_diff_21_20'],
                qoi['cond_phase12'], qoi['cond_phase21'], qoi['cond_phase03'],
                qoi['cond_phase20']
            ]
            qoi_vec = np.array(quantities_of_interest)
            qoi_plot.append(qoi_vec)

            ## To study the effect of the coherence of leakage on repeated CZs (simpler than simulating a full RB experiment):
            #czf.repeated_CZs_decay_curves(U_superop_average,t_final,self.fluxlutman,self.noise_parameters_CZ)

            #czf.plot_spectrum(self.fluxlutman,self.noise_parameters_CZ)

        qoi_plot = np.array(qoi_plot)

        ## Uncomment to study the convergence properties of averaging over a Gaussian
        # for i in range(len(qoi_plot[0])):
        #     czf.plot(x_plot_vec=[n_sampling_gaussian_vec],
        #                   y_plot_vec=[qoi_plot[:,i]],
        #                   title='Study of convergence of average',
        #                   xlabel='n_sampling_gaussian points',ylabel=self.value_names[i])

        return_values = [qoi_plot[0,0], qoi_plot[0,1], qoi_plot[0,2], qoi_plot[0,3], \
            qoi_plot[0,4], qoi_plot[0,5], qoi_plot[0,6], \
            qoi_plot[0,7], qoi_plot[0,8], qoi_plot[0,9], qoi_plot[0,10], \
            qoi_plot[0,11], qoi_plot[0,12], qoi_plot[0,13], qoi_plot[0,14], qoi_plot[0,15], qoi_plot[0,16], qoi_plot[0,17], qoi_plot[0,18],
            qoi_plot[0,19], qoi_plot[0,20], qoi_plot[0,21], qoi_plot[0,22]]
        if self.qois != 'all':
            return np.array(return_values)[self.qoi_mask]

        else:
            return return_values
예제 #27
0
def had_mixture(x):
    id_chan = to_choi(qeye(2))
    S_eye = to_super(id_chan)
    S_H = to_super(hadamard_transform())
    return (1 - x) * S_eye + x * S_H
예제 #28
0
                     [0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0],
                     [0, 0, 0, 0, 0, 0, 0, 0, 1]],
                    type='oper',
                    dims=[[3, 3], [3, 3]])
#U_target._type = 'oper'
U_target_diffdims = qtp.Qobj(
    [[1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, -1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, -1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 1]],
    type='oper',
    dims=[[9], [9]])  # otherwise average_gate_fidelity doesn't work

# if there is noise the target is the corresponding superoperator
U_super_target = qtp.to_super(U_target)
'''
remember that qutip uses the Liouville (matrix) representation for superoperators,
with column stacking.
This means that 
rho_{xy,x'y'}=rho[3*x+y,3*x'+y']
rho_{xy,x'y'}=operator_to_vector(rho)[3*x+y+27*x'+9*y']				VERIFY
where xy is the row and x'y' is the column
'''


def jump_operators(T1_q0, T1_q1, Tphi_q0_ket0toket0, Tphi_q0_ket1toket1,
                   Tphi_q0_ket2toket2, Tphi_q1_ket0toket0, Tphi_q1_ket1toket1,
                   Tphi_q0_sigmaZ_01, Tphi_q0_sigmaZ_12, Tphi_q0_sigmaZ_02,
                   Tphi_q1_sigmaZ_01, Tphi_q1_sigmaZ_12, Tphi_q1_sigmaZ_02):
    # time independent case
예제 #29
0
    def acquire_data_point(self, **kw):

        # Discretize average (integral) over a Gaussian distribution
        mean_q0 = self.sim_control_CZ.fluxbias_mean()
        mean_q1 = self.sim_control_CZ.fluxbias_mean_q1()
        sigma_q0 = self.sim_control_CZ.sigma_q0()
        sigma_q1 = (self.sim_control_CZ.sigma_q1()
                    )  # one for each qubit, in units of Phi_0

        qoi_plot = (
            []
        )  # used to verify convergence properties. If len(n_sampling_gaussian_vec)==1, it is useless

        # 11 guarantees excellent convergence.
        # We choose it odd so that the central point of the Gaussian is included.
        # Always choose it odd
        n_sampling_gaussian_vec = self.sim_control_CZ.n_sampling_gaussian_vec()

        for n_sampling_gaussian in n_sampling_gaussian_vec:
            # If sigma=0 there's no need for sampling
            if sigma_q0 != 0:
                samplingpoints_gaussian_q0 = np.linspace(
                    -5 * sigma_q0 + mean_q0, 5 * sigma_q0 + mean_q0,
                    n_sampling_gaussian)  # after 5 sigmas we cut the integral
                delta_x_q0 = (samplingpoints_gaussian_q0[1] -
                              samplingpoints_gaussian_q0[0])
                values_gaussian_q0 = czf_v2.gaussian(
                    samplingpoints_gaussian_q0, mean_q0, sigma_q0)
            else:
                samplingpoints_gaussian_q0 = np.array([mean_q0])
                delta_x_q0 = 1
                values_gaussian_q0 = np.array([1])
            if sigma_q1 != 0:
                samplingpoints_gaussian_q1 = np.linspace(
                    -5 * sigma_q1 + mean_q1, 5 * sigma_q1 + mean_q1,
                    n_sampling_gaussian)  # after 5 sigmas we cut the integral
                delta_x_q1 = (samplingpoints_gaussian_q1[1] -
                              samplingpoints_gaussian_q1[0])
                values_gaussian_q1 = czf_v2.gaussian(
                    samplingpoints_gaussian_q1, mean_q1, sigma_q1)
            else:
                samplingpoints_gaussian_q1 = np.array([mean_q1])
                delta_x_q1 = 1
                values_gaussian_q1 = np.array([1])

            # This is actually the input that was parallelized in an old version.
            # Currently it just creates a list that is provided sequentially to compute_propagator
            input_to_parallelize = []

            weights = []
            number = (
                -1
            )  # used to number instruments that are created in the parallelization, to avoid conflicts in the cluster

            for j_q0 in range(len(samplingpoints_gaussian_q0)):
                fluxbias_q0 = samplingpoints_gaussian_q0[
                    j_q0]  # q0 fluxing qubit
                for j_q1 in range(len(samplingpoints_gaussian_q1)):
                    fluxbias_q1 = samplingpoints_gaussian_q1[
                        j_q1]  # q1 spectator qubit

                    input_point = {
                        "fluxbias_q0": fluxbias_q0,
                        "fluxbias_q1": fluxbias_q1,
                        "fluxlutman": self.fluxlutman,
                        "fluxlutman_static": self.fluxlutman_static,
                        "sim_control_CZ": self.sim_control_CZ,
                        "fitted_stepresponse_ty": self.fitted_stepresponse_ty,
                    }

                    weight = (values_gaussian_q0[j_q0] * delta_x_q0 *
                              values_gaussian_q1[j_q1] * delta_x_q1)
                    weights.append(weight)

                    input_to_parallelize.append(input_point)

            U_final_vec = []
            t_final_vec = []
            for input_arglist in input_to_parallelize:
                result_list = compute_propagator(input_arglist)
                if self.sim_control_CZ.double_cz_pi_pulses() != "":
                    # Experimenting with single qubit ideal pi pulses
                    if self.sim_control_CZ.double_cz_pi_pulses(
                    ) == "with_pi_pulses":
                        pi_single_qubit = qtp.Qobj([[0, 1, 0], [1, 0, 0],
                                                    [0, 0, 1]])
                        # pi_pulse = qtp.tensor(pi_single_qubit, qtp.qeye(n_levels_q0))
                        pi_op = qtp.tensor(pi_single_qubit, pi_single_qubit)
                        # pi_super_op = qtp.to_super(pi_op)
                        U_final = result_list[0]
                        U_final = pi_op * U_final * pi_op * U_final
                    elif self.sim_control_CZ.double_cz_pi_pulses(
                    ) == "no_pi_pulses":
                        U_final = result_list[0]
                        U_final = U_final * U_final
                    t_final = 2 * result_list[1]
                else:
                    U_final = result_list[0]
                    t_final = result_list[1]
                U_final_vec.append(U_final)
                t_final_vec.append(t_final)

            t_final = t_final_vec[
                0]  # equal for all entries, we need it to compute phases in the rotating frame
            # needed to compute phases in the rotating frame, not used anymore
            # w_q0, w_q1, alpha_q0, alpha_q1 = czf_v2.dressed_frequencies(self.fluxlutman, self.fluxlutman_static, self.sim_control_CZ, which_gate=self.sim_control_CZ.which_gate())

            # Reproducing Leo's plots of cond_phase and leakage vs. flux offset (I order vs II order)
            # czf_v2.sensitivity_to_fluxoffsets(U_final_vec,input_to_parallelize,t_final,self.fluxlutman,self.fluxlutman_static, which_gate=self.sim_control_CZ.which_gate())

            for i in range(len(U_final_vec)):
                if U_final_vec[i].type == "oper":
                    U_final_vec[i] = qtp.to_super(
                        U_final_vec[i]
                    )  # weighted averaging needs to be done for superoperators
                U_final_vec[i] = U_final_vec[i] * weights[i]
            U_superop_average = sum(
                U_final_vec)  # computing resulting average propagator
            # print(czf_v2.verify_CPTP(U_superop_average))

            qoi = czf_v2.simulate_quantities_of_interest_superoperator_new(
                U=U_superop_average,
                t_final=t_final,
                fluxlutman=self.fluxlutman,
                fluxlutman_static=self.fluxlutman_static,
                sim_control_CZ=self.sim_control_CZ,
                which_gate=self.sim_control_CZ.which_gate(),
            )

            # if we look only for the minimum avgatefid_pc in the heat maps,
            # then we optimize the search via higher-order cost function
            if self.sim_control_CZ.cost_func() is not None:
                cost_func_val = self.sim_control_CZ.cost_func()(qoi)
            elif self.sim_control_CZ.look_for_minimum():
                cost_func_val = (np.log10(1 - qoi["avgatefid_compsubspace_pc"])
                                 )**4  # sign removed for even powers
            else:
                cost_func_val = -np.log10(1 - qoi["avgatefid_compsubspace_pc"])

            quantities_of_interest = [
                cost_func_val, qoi["phi_cond"], qoi["L1"] * 100,
                qoi["L2"] * 100, qoi["avgatefid_pc"] * 100,
                qoi["avgatefid_compsubspace_pc"] * 100, qoi["phase_q0"],
                qoi["phase_q1"], qoi["avgatefid_compsubspace"] * 100,
                qoi["avgatefid_compsubspace_pc_onlystaticqubit"] * 100,
                qoi["population_02_state"] * 100, qoi["cond_phase02"],
                qoi["coherent_leakage11"] * 100,
                qoi["offset_difference"] * 100, qoi["missing_fraction"] * 100,
                qoi["population_transfer_12_21"] * 100,
                qoi["population_transfer_12_03"] * 100,
                qoi["phase_diff_12_02"], qoi["phase_diff_21_20"],
                qoi["cond_phase12"], qoi["cond_phase21"], qoi["cond_phase03"],
                qoi["cond_phase20"],
                self.fluxlutman.get("vcz_amp_sq_{}".format(
                    self.sim_control_CZ.which_gate())),
                self.fluxlutman.get("vcz_amp_fine_{}".format(
                    self.sim_control_CZ.which_gate())),
                qoi["population_transfer_01_10"],
                qoi["population_20_state"] * 100
            ]
            qoi_vec = np.array(quantities_of_interest)
            qoi_plot.append(qoi_vec)

            # To study the effect of the coherence of leakage on repeated CZs (simpler than simulating a full RB experiment):
            # czf_v2.repeated_CZs_decay_curves(U_superop_average,t_final,self.fluxlutman,self.fluxlutman_static, which_gate=self.sim_control_CZ.which_gate())

            # czf_v2.plot_spectrum(self.fluxlutman,self.fluxlutman_static, which_gate=self.sim_control_CZ.which_gate())

        qoi_plot = np.array(qoi_plot)

        # Uncomment to study the convergence properties of averaging over a Gaussian
        # for i in range(len(qoi_plot[0])):
        #     czf_v2.plot(x_plot_vec=[n_sampling_gaussian_vec],
        #                   y_plot_vec=[qoi_plot[:,i]],
        #                   title='Study of convergence of average',
        #                   xlabel='n_sampling_gaussian points',ylabel=self.value_names[i])

        return_values = [
            qoi_plot[0, 0], qoi_plot[0, 1], qoi_plot[0, 2], qoi_plot[0, 3],
            qoi_plot[0, 4], qoi_plot[0, 5], qoi_plot[0, 6], qoi_plot[0, 7],
            qoi_plot[0, 8], qoi_plot[0, 9], qoi_plot[0, 10], qoi_plot[0, 11],
            qoi_plot[0, 12], qoi_plot[0, 13], qoi_plot[0, 14], qoi_plot[0, 15],
            qoi_plot[0, 16], qoi_plot[0, 17], qoi_plot[0, 18], qoi_plot[0, 19],
            qoi_plot[0, 20], qoi_plot[0, 21], qoi_plot[0, 22], qoi_plot[0, 23],
            qoi_plot[0, 24], qoi_plot[0, 25], qoi_plot[0, 26]
        ]
        if self.qois != "all":
            return np.array(return_values)[self.qoi_mask]

        else:
            return return_values
예제 #30
0
def test_super_operator_creation(to_test):
    size = 2
    implicit = to_test([[size], [size]])
    explicit = qutip.to_super(to_test(size))
    assert implicit == explicit
예제 #31
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Aug  1 07:06:18 2018

@author: huang
"""
import qutip as qt
import numpy as np

X = qt.sigmax()
S = qt.spre(X) * qt.spost(X.dag())  # Represents conjugation by X.
print(X)
print(S)
S2 = qt.to_super(X)
print(S2)  # type of S is super

# Check if S is completely positive
print(S.iscp)