CHI_PRIME = 0 MAX_AMP_C = 2 * np.pi * 2e-3 #GHz MAX_AMP_T = 2 * np.pi * 2e-2 #GHz CAVITY_STATE_COUNT = 5 CAVITY_ZERO = np.array([[1], [0], [0], [0], [0]]) CAVITY_ONE = np.array([[0], [1], [0], [0], [0]]) CAVITY_TWO = np.array([[0], [0], [1], [0], [0]]) CAVITY_THREE = np.array([[0], [0], [0], [1], [0]]) CAVITY_FOUR = np.array([[0], [0], [0], [0], [1]]) CAVITY_PSI_UP = np.divide(CAVITY_ZERO + CAVITY_FOUR, np.sqrt(2)) CAVITY_PSI_DOWN = CAVITY_TWO I_C = np.eye(CAVITY_STATE_COUNT) A_C = get_annihilation_operator(CAVITY_STATE_COUNT) A_DAGGER_C = get_creation_operator(CAVITY_STATE_COUNT) A_DAGGER_2_A_2_C = matmuls(A_DAGGER_C, A_DAGGER_C, A_C, A_C) N_C = matmuls(A_DAGGER_C, A_C) TRANSMON_STATE_COUNT = 3 TRANSMON_G = np.array([[1], [0], [0]]) TRANSMON_E = np.array([[0], [1], [0]]) TRANSMON_F = np.array([[0], [0], [1]]) I_T = np.eye(TRANSMON_STATE_COUNT) A_T = get_annihilation_operator(TRANSMON_STATE_COUNT) A_DAGGER_T = get_creation_operator(TRANSMON_STATE_COUNT) A_DAGGER_2_A_2_T = matmuls(A_DAGGER_T, A_DAGGER_T, A_T, A_T) N_T = matmuls(A_DAGGER_T, A_T) HILBERT_SIZE = CAVITY_STATE_COUNT * TRANSMON_STATE_COUNT H_SYSTEM_0 = ( np.divide(KAPPA, 2) * np.kron(A_DAGGER_2_A_2_C, I_T) +
# 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)
def _evolve_step_schroedinger_discrete( dt, hamiltonian, states, time, control_eval_times=None, controls=None, interpolation_policy=InterpolationPolicy.LINEAR, magnus_policy=MagnusPolicy.M2, ): """ Use the exponential series method via magnus expansion to evolve the state vectors to the next time step under the schroedinger equation for time-discrete controls. Magnus expansions are implemented using the methods described in https://arxiv.org/abs/1709.06483. Arguments: dt hamiltonian states time control_eval_times controls interpolation_policy magnus_policy Returns: states """ # Choose an interpolator. if interpolation_policy == InterpolationPolicy.LINEAR: interpolate = interpolate_linear_set else: raise NotImplementedError("The interpolation policy {} " "is not yet supported for this method." "".format(interpolation_policy)) # Choose a control interpolator. if controls is not None and control_eval_times is not None: interpolate_controls = interpolate else: interpolate_controls = lambda x, xs, ys: None # Construct a function to interpolate the hamiltonian # for all time. def get_hamiltonian(time_): controls_ = interpolate_controls(time_, control_eval_times, controls) hamiltonian_ = hamiltonian(controls_, time_) return -1j * hamiltonian_ if magnus_policy == MagnusPolicy.M2: magnus = magnus_m2(get_hamiltonian, dt, time) elif magnus_policy == MagnusPolicy.M4: magnus = magnus_m4(get_hamiltonian, dt, time) elif magnus_policy == MagnusPolicy.M6: magnus = magnus_m6(get_hamiltonian, dt, time) else: raise ValueError("Unrecognized magnus policy {}." "".format(magnus_policy)) #ENDIF step_unitary = expm(magnus) states = matmuls(step_unitary, states) return states
# Define experimental constants. All units are in GHz. CAVITY_FREQ = 2 * np.pi * 4.4526 KAPPA = 2 * np.pi * -2.82e-6 TRANSMON_FREQ = 2 * np.pi * 5.6640 ALPHA = 2 * np.pi * -1.395126e-1 CHI_E = 2 * np.pi * -5.64453e-4 CHI_E_2 = 2 * np.pi * -7.3e-7 MAX_AMP_NORM_CAVITY = np.sqrt(2) * 2 * np.pi * 4e-4 MAX_AMP_NORM_TRANSMON = np.sqrt(2) * 2 * np.pi * 4e-3 # Define the system CAVITY_STATE_COUNT = 3 CAVITY_ANNIHILATE = get_annihilation_operator(CAVITY_STATE_COUNT) CAVITY_CREATE = get_creation_operator(CAVITY_STATE_COUNT) CAVITY_NUMBER = np.matmul(CAVITY_CREATE, CAVITY_ANNIHILATE) CAVITY_C2_A2 = matmuls(CAVITY_CREATE, CAVITY_CREATE, CAVITY_ANNIHILATE, CAVITY_ANNIHILATE) CAVITY_ID = np.eye(CAVITY_STATE_COUNT) CAVITY_VACUUM = np.zeros((CAVITY_STATE_COUNT, 1)) CAVITY_ZERO = np.copy(CAVITY_VACUUM) CAVITY_ZERO[0][0] = 1 CAVITY_ONE = np.copy(CAVITY_VACUUM) CAVITY_ONE[1][0] = 1 CAVITY_TWO = np.copy(CAVITY_VACUUM) CAVITY_TWO[2][0] = 1 TRANSMON_STATE_COUNT = 3 TRANSMON_ANNIHILATE = get_annihilation_operator(TRANSMON_STATE_COUNT) 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)
CORE_COUNT = 8 # Define experimental constants. BLOCKADE_LEVEL = 3 CHI_E = 2 * anp.pi * -5.672016e-4 #GHz KAPPA = 2 * anp.pi * 2.09e-6 #GHz OMEGA = 2 * anp.pi * 1.44e-4 #GHz MAX_AMP_C = anp.sqrt(2) * 2 * anp.pi * 1.5e-5 #GHz MAX_BND_C = 2 * OMEGA # Define the system. CAVITY_STATE_COUNT = 5 CAVITY_ANNIHILATE = get_annihilation_operator(CAVITY_STATE_COUNT) CAVITY_CREATE = get_creation_operator(CAVITY_STATE_COUNT) CAVITY_NUMBER = anp.matmul(CAVITY_CREATE, CAVITY_ANNIHILATE) CAVITY_QUADRATURE = matmuls(CAVITY_CREATE, CAVITY_ANNIHILATE, CAVITY_CREATE, CAVITY_ANNIHILATE) CAVITY_I = anp.eye(CAVITY_STATE_COUNT) CAVITY_VACUUM = anp.zeros((CAVITY_STATE_COUNT, 1)) CAVITY_ZERO = anp.copy(CAVITY_VACUUM) CAVITY_ZERO[0][0] = 1. CAVITY_ONE = anp.copy(CAVITY_VACUUM) CAVITY_ONE[1][0] = 1. TRANSMON_STATE_COUNT = 2 TRANSMON_I = anp.eye(TRANSMON_STATE_COUNT) TRANSMON_VACUUM = anp.zeros((TRANSMON_STATE_COUNT, 1)) TRANSMON_G = anp.copy(TRANSMON_VACUUM) TRANSMON_G[0][0] = 1. TRANSMON_G_DAGGER = conjugate_transpose(TRANSMON_G) TRANSMON_E = anp.copy(TRANSMON_VACUUM) TRANSMON_E[1][0] = 1.
def _evolve_step_schroedinger_discrete( dt, hamiltonian, states, time, control_sentinel=False, control_step=0, controls=None, interpolation_policy=InterpolationPolicy.LINEAR, magnus_policy=MagnusPolicy.M2, operation_policy=OperationPolicy.CPU, ): """ Use the exponential series method via magnus expansion to evolve the state vectors to the next time step under the schroedinger equation for time-discrete controls. Magnus expansions are implemented using the methods described in https://arxiv.org/abs/1709.06483. Args: control_sentinel control_step controls dt hamiltonian interpolation_policy magnus_policy operation_policy states time Returns: states """ controls_exist = not (controls is None) if magnus_policy == MagnusPolicy.M2: if controls_exist: c1 = controls[control_step] else: c1 = None a1 = -1j * hamiltonian(c1, time) magnus = magnus_m2(a1, dt, operation_policy=operation_policy) elif magnus_policy == MagnusPolicy.M4: t1 = time + dt * _M4_T1 t2 = time + dt * _M4_T2 if controls_exist: if control_sentinel: controls_left = controls[control_step - 1] controls_right = controls[control_step] time_left = time - dt time_right = time else: controls_left = controls[control_step] controls_right = controls[control_step + 1] time_left = time time_right = time + dt if interpolation_policy == InterpolationPolicy.LINEAR: c1 = interpolate_linear(time_left, time_right, t1, controls_left, controls_right) c2 = interpolate_linear(time_left, time_right, t2, controls_left, controls_right) else: raise ValueError( "The interpolation policy {} is not implemented" "for this method.".format(interpolation_policy)) else: c1 = c2 = None a1 = -1j * hamiltonian(c1, t1) a2 = -1j * hamiltonian(c2, t2) magnus = magnus_m4(a1, a2, dt) elif magnus_policy == MagnusPolicy.M6: t1 = time + dt * _M6_T1 t2 = time + dt * _M6_T2 t3 = time + dt * _M6_T3 if controls_exist: if control_sentinel: controls_left = controls[control_step - 1] controls_right = controls[control_step] time_left = time - dt time_right = time else: controls_left = controls[control_step] controls_right = controls[control_step + 1] time_left = time time_right = time + dt if interpolation_policy == InterpolationPolicy.LINEAR: c1 = interpolate_linear(time_left, time_right, t1, controls_left, controls_right, operation_policy=operation_policy) c2 = interpolate_linear(time_left, time_right, t2, controls_left, controls_right, operation_policy=operation_policy) c3 = interpolate_linear(time_left, time_right, t2, controls_left, controls_right, operation_policy=operation_policy) else: raise ValueError( "The interpolation policy {} is not implemented" "for this method.".format(interpolation_policy)) else: c1 = c2 = c3 = None a1 = -1j * hamiltonian(c1, t1) a2 = -1j * hamiltonian(c2, t2) a3 = -1j * hamiltonian(c3, t3) magnus = magnus_m6(a1, a2, a3, dt, operation_policy=operation_policy) #ENDIF step_unitary = expm(magnus, operation_policy=operation_policy) states = matmuls(step_unitary, states, operation_policy=operation_policy) return states