def H_rot(): chi_a, chi_b, chi2_a, chi2_b = hparams["chi_a"], hparams["chi_b"], hparams[ "chi2_a"], hparams["chi2_b"] chi_ab, chi2_ab, K_a, K_b = hparams["chi_ab"], hparams["chi2_ab"], hparams[ "K_a"], hparams["K_b"] freq_ge, mode_ens = 0, 0 # GHz, in lab frame chi_a_arr = np.zeros(qnum) chi_b_arr = np.zeros(qnum) chi2_a_arr = np.zeros(qnum) chi2_b_arr = np.zeros(qnum) chi_a_arr[1] = chi_a[0] # ge of a chi_b_arr[1] = chi_b[0] # ge of b chi2_a_arr[1] = chi2_a[0] #ge of a chi2_b_arr[1] = chi2_b[0] #ge of b if qnum > 2: chi_a_arr[2] = chi_a[1] #ef of a chi_b_arr[2] = chi_b[1] #ef of b chi2_a_arr[2] = chi2_a[1] #ef of a chi2_b_arr[2] = chi2_b[1] #ef of b #self-kerr of the cavity modes mode_ens_a = np.array( [K_a / 2 * ii * (ii - 1) for ii in np.arange(mnum_a)]) mode_ens_b = np.array( [K_b / 2 * ii * (ii - 1) for ii in np.arange(mnum_b)]) H_m_a = np.diag(mode_ens_a) H_m_b = np.diag(mode_ens_b) H0 = krons(Q_I, H_m_a, M_I_b) + krons(Q_I, M_I_a, H_m_b) H0_1 = 2 * (krons(np.diag(chi_a_arr), M_z_a, M_I_b) + krons(np.diag(chi_b_arr), M_I_a, M_z_b)) H0_2 = krons(np.diag(chi2_a_arr), np.diag(np.array([ii*(ii-1) for ii in np.arange(mnum_a)])), M_I_b)\ + krons(np.diag(chi2_b_arr), M_I_a, np.diag(np.array([ii*(ii-1) for ii in np.arange(mnum_b)]))) H0_3 = 2 *chi_ab * krons(Q_I, num(mnum_a).full(), num(mnum_b).full()) \ + 0*chi2_ab * krons(num(qnum).full(), num(mnum_a).full(), num(mnum_b).full()) # Check this line with Vatsan return 2 * pi * (H0 + H0_1 + H0_2)
# Next, we define the system hamiltonian. # qoc requires you to specify your hamiltonian as a function of control parameters # and time, i.e. # hamiltonian_function :: (controls :: ndarray (control_count), # time :: float) # -> hamiltonian_matrix :: ndarray (hilbert_size x hilbert_size) # You will see this notation in the qoc documentation. The symbol `::` is read "as". # It specifies the object type of the argument. E.g. 1 :: int, True :: bool, 'hello' :: str. # The parens that follow the `ndarray` type specifies the shape of the array. # E.g. anp.array([[1, 2], [3, 4]]) :: ndarray (2 x 2) # Control parameters are values that you will use to vary time-dependent control fields # that act on your system. Note that qoc supports both complex and real control parameters. # In this case, we are controlling a charge drive on the cavity, and a charge drive on the transmon. # Each drive is parameterized by a single, complex control parameter. SYSTEM_HAMILTONIAN = (W_C * krons(matmuls(A_DAGGER, A), B_ID) + KAPPA_BY_2 * krons(matmuls(A_DAGGER, A_DAGGER, A , A), B_ID) + W_T * krons(A_ID, matmuls(B_DAGGER, B)) + ALPHA_BY_2 * krons(A_ID, matmuls(B_DAGGER, B_DAGGER, B, B)) + CHI * krons(matmuls(A_DAGGER, A), matmuls(B_DAGGER, B)) + CHIP_BY_2 * krons(matmuls(A_DAGGER, A_DAGGER, A, A), matmuls(B_DAGGER, B))) CONTROL_0 = krons(A, B_ID) CONTROL_0_DAGGER = krons(A_DAGGER, B_ID) CONTROL_1 = krons(A_ID, B) CONTROL_1_DAGGER = krons(A_ID, B_DAGGER) def hamiltonian(controls, time): return (SYSTEM_HAMILTONIAN + controls[0] * CONTROL_0 + anp.conjugate(controls[0]) * CONTROL_0_DAGGER + controls[1] * CONTROL_1 + anp.conjugate(controls[1]) * CONTROL_1_DAGGER)
TRANSMON_C2_A2 = matmuls(TRANSMON_CREATE, TRANSMON_CREATE, TRANSMON_ANNIHILATE, TRANSMON_ANNIHILATE) TRANSMON_ID = np.eye(TRANSMON_STATE_COUNT) TRANSMON_VACUUM = np.zeros((TRANSMON_STATE_COUNT, 1)) TRANSMON_G = np.copy(TRANSMON_VACUUM) TRANSMON_G[0][0] = 1 TRANSMON_G_DAGGER = conjugate_transpose(TRANSMON_G) TRANSMON_E = np.copy(TRANSMON_VACUUM) TRANSMON_E[1][0] = 1 TRANSMON_E_DAGGER = conjugate_transpose(TRANSMON_E) TRANSMON_F = np.copy(TRANSMON_VACUUM) TRANSMON_F[2][0] = 1 TRANSMON_F_DAGGER = conjugate_transpose(TRANSMON_F) H_SYSTEM = ( # CAVITY_FREQ * krons(CAVITY_NUMBER, TRANSMON_ID) + (KAPPA / 2) * krons(CAVITY_C2_A2, TRANSMON_ID) # + TRANSMON_FREQ * krons(CAVITY_ID, TRANSMON_NUMBER) + (ALPHA / 2) * krons(CAVITY_ID, TRANSMON_C2_A2) + 2 * CHI_E * krons(CAVITY_NUMBER, np.matmul(TRANSMON_E, TRANSMON_E_DAGGER)) + CHI_E_2 * krons(CAVITY_C2_A2, np.matmul(TRANSMON_E, TRANSMON_E_DAGGER)) ) H_CONTROL_0 = krons(CAVITY_ANNIHILATE, TRANSMON_ID) H_CONTROL_0_DAGGER = conjugate_transpose(H_CONTROL_0) H_CONTROL_1 = krons(CAVITY_ID, np.matmul(TRANSMON_G, TRANSMON_E_DAGGER)) H_CONTROL_1_DAGGER = conjugate_transpose(H_CONTROL_1) H_CONTROL_2 = krons(CAVITY_ID, np.matmul(TRANSMON_E, TRANSMON_F_DAGGER)) H_CONTROL_2_DAGGER = conjugate_transpose(H_CONTROL_2) hamiltonian = lambda controls, time: ( H_SYSTEM + controls[0] * H_CONTROL_0
H_m_b = np.diag(mode_ens_b) H0 = krons(Q_I, H_m_a, M_I_b) + krons(Q_I, M_I_a, H_m_b) H0_1 = 2 * (krons(np.diag(chi_a_arr), M_z_a, M_I_b) + krons(np.diag(chi_b_arr), M_I_a, M_z_b)) H0_2 = krons(np.diag(chi2_a_arr), np.diag(np.array([ii*(ii-1) for ii in np.arange(mnum_a)])), M_I_b)\ + krons(np.diag(chi2_b_arr), M_I_a, np.diag(np.array([ii*(ii-1) for ii in np.arange(mnum_b)]))) H0_3 = 2 *chi_ab * krons(Q_I, num(mnum_a).full(), num(mnum_b).full()) \ + 0*chi2_ab * krons(num(qnum).full(), num(mnum_a).full(), num(mnum_b).full()) # Check this line with Vatsan return 2 * pi * (H0 + H0_1 + H0_2) H_SYSTEM = H_rot() XII = krons(Q_x, M_I_a, M_I_b) YII = krons(Q_y, M_I_a, M_I_b) IXI = krons(Q_I, M_x_a, M_I_b) IYI = krons(Q_I, M_y_a, M_I_b) IIX = krons(Q_I, M_I_a, M_x_b) IIY = krons(Q_I, M_I_a, M_y_b) Hops = [XII, YII, IXI, IYI, IIX, IIY] CONTROL_COUNT = len(Hops) COMPLEX_CONTROLS = False MAX_CONTROL_NORMS = np.array((max_amp_qubit,max_amp_qubit,\ max_amp_mode_a,max_amp_mode_a,max_amp_mode_b,max_amp_mode_b)) hamiltonian = lambda controls, time: (H_SYSTEM + controls[0] * Hops[ 0] + controls[1] * Hops[1] + controls[2] * Hops[2] + controls[3] * Hops[ 3] + controls[4] * Hops[4] + controls[5] * Hops[5])
TRANSMON_CREATE = get_creation_operator(TRANSMON_STATE_COUNT) TRANSMON_NUMBER = np.matmul(TRANSMON_CREATE, TRANSMON_ANNIHILATE) TRANSMON_C2_A2 = matmuls(TRANSMON_CREATE, TRANSMON_CREATE, TRANSMON_ANNIHILATE, TRANSMON_ANNIHILATE) TRANSMON_ID = np.eye(TRANSMON_STATE_COUNT) TRANSMON_VACUUM = np.zeros((TRANSMON_STATE_COUNT, 1)) TRANSMON_ZERO = np.copy(TRANSMON_VACUUM) TRANSMON_ZERO[0][0] = 1 TRANSMON_ONE = np.copy(TRANSMON_VACUUM) TRANSMON_ONE[1][0] = 1 TRANSMON_TWO = np.copy(TRANSMON_VACUUM) TRANSMON_TWO[2][0] = 1 H_SYSTEM = ( # CAVITY_FREQ * krons(CAVITY_NUMBER, TRANSMON_ID) +(KAPPA / 2) * krons(CAVITY_C2_A2, TRANSMON_ID) # + TRANSMON_FREQ * krons(CAVITY_ID, TRANSMON_NUMBER) + (ALPHA / 2) * krons(CAVITY_ID, TRANSMON_C2_A2) + 2 * CHI * krons(CAVITY_NUMBER, TRANSMON_NUMBER) + CHI_PRIME * krons(CAVITY_NUMBER, TRANSMON_C2_A2)) H_CONTROL_0 = krons(CAVITY_ANNIHILATE, TRANSMON_ID) H_CONTROL_0_DAGGER = conjugate_transpose(H_CONTROL_0) H_CONTROL_1 = krons(CAVITY_ID, TRANSMON_ANNIHILATE) H_CONTROL_1_DAGGER = conjugate_transpose(H_CONTROL_1) hamiltonian = lambda controls, hargs, time: (H_SYSTEM + controls[ 0] * H_CONTROL_0 + anp.conjugate(controls[ 0]) * H_CONTROL_0_DAGGER + controls[1] * H_CONTROL_1 + anp.conjugate( controls[1]) * H_CONTROL_1_DAGGER) CONTROL_COUNT = 2 COMPLEX_CONTROLS = True