def test_grape_lindblad_discrete(): """ Run end-to-end test on the grape_lindblad_discrete function. NOTE: We mostly care about the tests for evolve_lindblad_discrete. For grape_lindblad_discrete we care that everything is being passed through functions properly, but autograd has a really solid testing suite and we trust that their gradients are being computed correctly. """ import numpy as np from qoc.core.lindbladdiscrete import grape_lindblad_discrete from qoc.standard import ( conjugate_transpose, ForbidDensities, SIGMA_X, SIGMA_Y, ) # Test that parameters are clipped if they grow too large. hilbert_size = 4 hamiltonian_matrix = np.divide( 1, 2) * (np.kron(SIGMA_X, SIGMA_X) + np.kron(SIGMA_Y, SIGMA_Y)) hamiltonian = lambda controls, t: (controls[0] * hamiltonian_matrix) initial_states = np.array([[[0], [1], [0], [0]]]) initial_densities = np.matmul(initial_states, conjugate_transpose(initial_states)) forbidden_states = np.array([[[[0], [1], [0], [0]]]]) forbidden_densities = np.matmul(forbidden_states, conjugate_transpose(forbidden_states)) control_count = 1 evolution_time = 10 system_eval_count = control_eval_count = 11 max_norm = 1e-10 max_control_norms = np.repeat(max_norm, control_count) costs = [ForbidDensities(forbidden_densities, system_eval_count)] iteration_count = 5 log_iteration_step = 0 result = grape_lindblad_discrete(control_count, control_eval_count, costs, evolution_time, initial_densities, system_eval_count, hamiltonian=hamiltonian, iteration_count=iteration_count, log_iteration_step=log_iteration_step, max_control_norms=max_control_norms) for i in range(result.best_controls.shape[1]): assert (np.less_equal(np.abs(result.best_controls[:, i]), max_control_norms[i]).all())
def random_hermitian_matrix(matrix_size): """ Generate a random, square, hermitian matrix of size `matrix_size`. """ import numpy as np from qoc.standard import conjugate_transpose matrix = random_complex_matrix(matrix_size) return (matrix + conjugate_transpose(matrix)) / 2
def test_targetdensityinfidelitytime(): import numpy as np from qoc.standard import conjugate_transpose from qoc.standard.costs.targetdensityinfidelitytime import TargetDensityInfidelityTime system_eval_count = 11 state0 = np.array([[0], [1]]) density0 = np.matmul(state0, conjugate_transpose(state0)) target_state0 = np.array([[1], [0]]) target_density0 = np.matmul(target_state0, conjugate_transpose(target_state0)) densities = np.stack((density0, ), axis=0) targets = np.stack((target_density0, ), axis=0) ti = TargetDensityInfidelityTime(system_eval_count, targets) cost = ti.cost(None, densities, None) assert (np.allclose(cost, 0.1)) ti = TargetDensityInfidelityTime(system_eval_count, densities) cost = ti.cost(None, densities, None) assert (np.allclose(cost, 0.05)) state0 = np.array([[1], [0]]) state1 = (np.array([[1j], [1]]) / np.sqrt(2)) density0 = np.matmul(state0, conjugate_transpose(state0)) density1 = np.matmul(state1, conjugate_transpose(state1)) target_state0 = np.array([[1j], [0]]) target_state1 = np.array([[1], [0]]) target_density0 = np.matmul(target_state0, conjugate_transpose(target_state0)) target_density1 = np.matmul(target_state1, conjugate_transpose(target_state1)) densities = np.stack(( density0, density1, ), axis=0) targets = np.stack(( target_density0, target_density1, ), axis=0) ti = TargetDensityInfidelityTime(system_eval_count, targets) cost = ti.cost(None, densities, None) expected_cost = 0.0625 assert (np.allclose(cost, expected_cost))
def test_forbiddensities(): import numpy as np from qoc.standard import conjugate_transpose from qoc.standard.costs.forbiddensities import ForbidDensities system_eval_count = 11 state0 = np.array([[1], [0]]) density0 = np.matmul(state0, conjugate_transpose(state0)) forbid0_0 = np.array([[1], [0]]) density0_0 = np.matmul(forbid0_0, conjugate_transpose(forbid0_0)) forbid0_1 = np.divide(np.array([[1], [1]]), np.sqrt(2)) density0_1 = np.matmul(forbid0_1, conjugate_transpose(forbid0_1)) state1 = np.array([[0], [1]]) density1 = np.matmul(state1, conjugate_transpose(state1)) forbid1_0 = np.divide(np.array([[1], [1]]), np.sqrt(2)) density1_0 = np.matmul(forbid1_0, conjugate_transpose(forbid1_0)) forbid1_1 = np.divide(np.array([[1j], [1j]]), np.sqrt(2)) density1_1 = np.matmul(forbid1_1, conjugate_transpose(forbid1_1)) densities = np.stack(( density0, density1, )) forbidden_densities0 = np.stack(( density0_0, density0_1, )) forbidden_densities1 = np.stack(( density1_0, density1_1, )) forbidden_densities = np.stack(( forbidden_densities0, forbidden_densities1, )) fd = ForbidDensities(forbidden_densities, system_eval_count) cost = fd.cost(None, densities, None) expected_cost = 7 / 640 assert (np.allclose( cost, expected_cost, ))
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) + np.divide(ALPHA, 2) * np.kron(I_C, A_DAGGER_2_A_2_T) + CHI_E * np.kron(N_C, np.matmul(TRANSMON_E, conjugate_transpose(TRANSMON_E))) + CHI_F * np.kron(N_C, np.matmul(TRANSMON_F, conjugate_transpose(TRANSMON_F)))) # + np.divide(CHI_PRIME, 2) * np.kron(A_DAGGER_2_A_2_C, N_T)) H_CONTROL_0_0 = np.kron(A_C, I_T) H_CONTROL_0_1 = np.kron(A_DAGGER_C, I_T) H_CONTROL_1_0 = np.kron(I_C, A_T) H_CONTROL_1_1 = np.kron(I_C, A_DAGGER_T) hamiltonian = (lambda params, t: H_SYSTEM_0 + params[ 0] * H_CONTROL_0_0 + anp.conjugate(params[0]) * H_CONTROL_0_1 + params[1] * H_CONTROL_1_0 + anp.conjugate(params[1]) * H_CONTROL_1_1) # Define the optimization. PARAM_COUNT = 2 MAX_PARAM_NORMS = ( MAX_AMP_C,
# The operators defined here follow from e.q. 9 of [1]. L_OP_0 = krons(A, B_ID) L_OP_1 = krons(A_ID, B) L_OP_2 = krons(A_ID, matmuls(B_DAGGER, B)) G_0 = 1 / T1_C G_1 = 1 / T1_T G_2 = 1 / TP_T LINDBLAD_DISSIPATORS = anp.array((G_0, G_1, G_2,)) LINDBLAD_OPERATORS = anp.stack((L_OP_0, L_OP_1, L_OP_2,)) lindblad_data = lambda time: (LINDBLAD_DISSIPATORS, LINDBLAD_OPERATORS) # Notice that the lindblad equation operates on density matrices; it does not operate on state vectors # like the schroedinger equation. # Therefore, we need to redefine the initial state of our system, and our cost functions, # using density matrices. INITIAL_DENSITIES = matmuls(INITIAL_STATES, conjugate_transpose(INITIAL_STATES)) TARGET_DENSITIES = matmuls(TARGET_STATES, conjugate_transpose(TARGET_STATES)) COSTS = [TargetDensityInfidelity(TARGET_DENSITIES)] # As mentioned earlier, the `system_eval_count` argument has no bearing on # the accuracy of the lindblad integrator. Therefore, if you do not have any cost # functions that require evaluation at intermediary time steps in the evolution, # it is recommended that you set `system_eval_count` = 2. # This means that the lindblad integrator will only evaluate the density matrices # at time=0 and time=EVOLUTION_TIME. SYSTEM_EVAL_COUNT = 2 SAVE_INTERMEDIATE_DENSITIES = True # TODO: This optimization does not converge, and it is slow. # Either tweak the parameters to get the optimization to converge, # or consider demonstrating a different example.
def test_evolve_lindblad_discrete(): """ Run end-to-end tests on evolve_lindblad_discrete. """ import numpy as np from qutip import mesolve, Qobj from qoc.core.lindbladdiscrete import evolve_lindblad_discrete from qoc.standard import ( conjugate_transpose, SIGMA_X, SIGMA_Y, matrix_to_column_vector_list, SIGMA_PLUS, SIGMA_MINUS, get_creation_operator, get_annihilation_operator, ) big = 4 # Test that evolution WITH a hamiltonian and WITHOUT lindblad operators # yields a known result. # Use e.q. 109 from # https://arxiv.org/abs/1904.06560 hilbert_size = 4 identity_matrix = np.eye(hilbert_size, dtype=np.complex128) iswap_unitary = np.array( ((1, 0, 0, 0), (0, 0, -1j, 0), (0, -1j, 0, 0), (0, 0, 0, 1))) initial_states = matrix_to_column_vector_list(identity_matrix) target_states = matrix_to_column_vector_list(iswap_unitary) initial_densities = np.matmul(initial_states, conjugate_transpose(initial_states)) target_densities = np.matmul(target_states, conjugate_transpose(target_states)) system_hamiltonian = ( (1 / 2) * (np.kron(SIGMA_X, SIGMA_X) + np.kron(SIGMA_Y, SIGMA_Y))) hamiltonian = lambda controls, time: system_hamiltonian system_eval_count = 2 evolution_time = np.pi / 2 result = evolve_lindblad_discrete(evolution_time, initial_densities, system_eval_count, hamiltonian=hamiltonian) final_densities = result.final_densities assert (np.allclose(final_densities, target_densities)) # Note that qutip only gets this result within 1e-5 error. tlist = np.array([0, evolution_time]) c_ops = list() e_ops = list() for i, initial_density in enumerate(initial_densities): result = mesolve( Qobj(system_hamiltonian), Qobj(initial_density), tlist, c_ops, e_ops, ) final_density = result.states[-1].full() target_density = target_densities[i] #ENDFOR # Test that evolution WITHOUT a hamiltonian and WITH lindblad operators # yields a known result. # This test ensures that dissipators are working correctly. # Use e.q.14 from # https://inst.eecs.berkeley.edu/~cs191/fa14/lectures/lecture15.pdf. hilbert_size = 2 gamma = 2 lindblad_dissipators = np.array((gamma, )) sigma_plus = np.array([[0, 1], [0, 0]]) lindblad_operators = np.stack((sigma_plus, )) lindblad_data = lambda time: (lindblad_dissipators, lindblad_operators) evolution_time = 1. system_eval_count = 2 inv_sqrt_2 = 1 / np.sqrt(2) a0 = np.random.rand() c0 = 1 - a0 b0 = np.random.rand() b0_star = np.conj(b0) initial_density_0 = np.array(((a0, b0), (b0_star, c0))) initial_densities = np.stack((initial_density_0, )) gt = gamma * evolution_time expected_final_density = np.array( ((1 - c0 * np.exp(-gt), b0 * np.exp(-gt / 2)), (b0_star * np.exp(-gt / 2), c0 * np.exp(-gt)))) result = evolve_lindblad_discrete(evolution_time, initial_densities, system_eval_count, lindblad_data=lindblad_data) final_density = result.final_densities[0] assert (np.allclose(final_density, expected_final_density)) # Test that evolution WITH a random hamiltonian and WITH random lindblad operators # yields a similar result to qutip. matrix_size = 4 evolution_time = 5 system_eval_count = 2 e_ops_qutip = list() tlist = np.array(( 0, evolution_time, )) for i in range(big): # Evolve under lindbladian. hamiltonian_matrix = random_hermitian_matrix(matrix_size) hamiltonian = lambda controls, time: hamiltonian_matrix lindblad_operator_count = np.random.randint(1, matrix_size) lindblad_operators = np.stack([ random_complex_matrix(matrix_size) for _ in range(lindblad_operator_count) ]) lindblad_dissipators = np.ones((lindblad_operator_count, )) lindblad_data = lambda time: (lindblad_dissipators, lindblad_operators) density_matrix = random_hermitian_matrix(matrix_size) initial_densities = np.stack((density_matrix, )) result = evolve_lindblad_discrete(evolution_time, initial_densities, system_eval_count, hamiltonian=hamiltonian, lindblad_data=lindblad_data) final_density = result.final_densities[0] # Evolve under lindbladian with qutip. hamiltonian_qutip = Qobj(hamiltonian_matrix) initial_density_qutip = Qobj(density_matrix) lindblad_operators_qutip = [ Qobj(lindblad_operator) for lindblad_operator in lindblad_operators ] result_qutip = mesolve( hamiltonian_qutip, initial_density_qutip, tlist, lindblad_operators_qutip, e_ops_qutip, ) final_density_qutip = result_qutip.states[-1].full() assert (np.allclose(final_density, final_density_qutip)) #ENDFOR # Test that evolvution with a random hamiltonain, # random control amplitudes, and random lindblad operators yields # a similar result to qutip. # qoc constatns matrix_size = 4 evolution_time = 5 system_eval_count = 2 control_eval_count = 100 control_count = 1 controls_shape = (control_eval_count, control_count) create = get_creation_operator(matrix_size) annihilate = get_annihilation_operator(matrix_size) # qutip constants e_ops_qutip = list() tlist = np.linspace(0, evolution_time, control_eval_count) hc0_qutip = Qobj(annihilate + create) hc1_qutip = Qobj(1j * (annihilate - create)) lindblad_operator_count = 1 for i in range(big): hamiltonian_matrix = random_hermitian_matrix(matrix_size) hamiltonian = lambda controls, time: (hamiltonian_matrix + controls[ 0] * annihilate + np.conjugate(controls[0]) * create) lindblad_operators = np.stack([ random_complex_matrix(matrix_size) for _ in range(lindblad_operator_count) ]) lindblad_dissipators = np.ones((lindblad_operator_count, )) lindblad_data = lambda time: (lindblad_dissipators, lindblad_operators) density_matrix = random_hermitian_matrix(matrix_size) initial_densities = np.stack((density_matrix, )) controls = np.random.rand( *controls_shape) + 1j * np.random.rand(*controls_shape) result = evolve_lindblad_discrete(evolution_time, initial_densities, system_eval_count, controls=controls, hamiltonian=hamiltonian, lindblad_data=lindblad_data) final_density = result.final_densities[0] hamiltonian_qutip = Qobj(hamiltonian_matrix) c0_qutip = np.real(controls)[:, 0] c1_qutip = np.imag(controls)[:, 0] h0_ones = np.ones_like(controls[:, 0]) h_list = [[hamiltonian_qutip, h0_ones], [hc0_qutip, c0_qutip], [hc1_qutip, c1_qutip]] initial_density_qutip = Qobj(density_matrix) lindblad_operators_qutip = [ Qobj(lindblad_operator) for lindblad_operator in lindblad_operators ] result_qutip = mesolve( h_list, initial_density_qutip, tlist, lindblad_operators_qutip, e_ops_qutip, ) final_density_qutip = result_qutip.states[-1].full() # Qutip does a cubic fit, by default, on their controls and we do a linear fit, # by default. # 1e-2 is reasonable, taking interpolation method differences # into consideration. assert (np.allclose(final_density, final_density_qutip, atol=1e-2))
) # Subject the system to T1 type decoherence per fig. 11 of # https://www.sciencedirect.com/science/article/pii/S0003491617301252. LINDBLAD_OPERATORS = anp.stack((ANNIHILATION_OPERATOR, )) T1 = 1e3 #ns GAMMA_1 = 1 / T1 LINDBLAD_DISSIPATORS = anp.stack((GAMMA_1, )) lindblad_data = lambda time: (LINDBLAD_DISSIPATORS, LINDBLAD_OPERATORS) # Define the problem. INITIAL_STATE_0 = anp.array([[1], [0]]) TARGET_STATE_0 = anp.array([[0], [1]]) INITIAL_STATES = anp.stack((INITIAL_STATE_0, ), axis=0) TARGET_STATES = anp.stack((TARGET_STATE_0, ), axis=0) INITIAL_DENSITIES = anp.matmul(INITIAL_STATES, conjugate_transpose(INITIAL_STATES)) TARGET_DENSITIES = anp.matmul(TARGET_STATES, conjugate_transpose(TARGET_STATES)) # Note that the TargetDensityInfidelity function uses the frobenius inner product. # Even if our evolved and target matrices are identical, the total optimization error # should not reach zero. COSTS = [TargetDensityInfidelity(TARGET_DENSITIES)] # Define the optimization. COMPLEX_CONTROLS = True MAX_CONTROL_NORMS = anp.array((5, )) CONTROL_COUNT = 1 EVOLUTION_TIME = 10 # nanoseconds CONTROL_EVAL_COUNT = 11 SYSTEM_EVAL_COUNT = 2 ITERATION_COUNT = int(1e6)
# 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_ZERO = anp.array(((1, ), (0, ), (0, ), (0, ), (0, ))) CAVITY_ONE = anp.array(((0, ), (1, ), (0, ), (0, ), (0, ))) CAVITY_TWO = anp.array(((0, ), (0, ), (1, ), (0, ), (0, ))) CAVITY_THREE = anp.array(((0, ), (0, ), (0, ), (1, ), (0, ))) CAVITY_FOUR = anp.array(((0, ), (0, ), (0, ), (0, ), (1, ))) CAVITY_I = anp.eye(CAVITY_STATE_COUNT) TRANSMON_STATE_COUNT = 3 TRANSMON_G = anp.array(((1, ), (0, ), (0, ))) TRANSMON_G_DAGGER = conjugate_transpose(TRANSMON_G) TRANSMON_E = anp.array(((0, ), (1, ), (0, ))) TRANSMON_E_DAGGER = conjugate_transpose(TRANSMON_E) TRANSMON_F = anp.array(((0, ), (0, ), (1, ))) TRANSMON_F_DAGGER = conjugate_transpose(TRANSMON_F) TRANSMON_I = anp.eye(TRANSMON_STATE_COUNT) H_SYSTEM = ( CHI_E * anp.kron(anp.matmul(TRANSMON_E, TRANSMON_E_DAGGER), CAVITY_NUMBER) + CHI_F * anp.kron(anp.matmul(TRANSMON_F, TRANSMON_F_DAGGER), CAVITY_NUMBER)) H_GE = anp.kron(anp.matmul(TRANSMON_G, TRANSMON_E_DAGGER), CAVITY_I) H_GE_DAGGER = conjugate_transpose(H_GE) H_EF = anp.kron(anp.matmul(TRANSMON_E, TRANSMON_F_DAGGER), CAVITY_I) H_EF_DAGGER = conjugate_transpose(H_EF) H_C = anp.kron(TRANSMON_I, CAVITY_ANNIHILATE)
def _test_evolve_lindblad_discrete(): """ Run end-to-end tests on evolve_lindblad_discrete. """ import numpy as np from qutip import mesolve, Qobj, Options from qoc.standard import ( conjugate_transpose, SIGMA_X, SIGMA_Y, matrix_to_column_vector_list, SIGMA_PLUS, SIGMA_MINUS, ) def _generate_complex_matrix(matrix_size): return (np.random.rand(matrix_size, matrix_size) + 1j * np.random.rand(matrix_size, matrix_size)) def _generate_hermitian_matrix(matrix_size): matrix = _generate_complex_matrix(matrix_size) return (matrix + conjugate_transpose(matrix)) * 0.5 # Test that evolution WITH a hamiltonian and WITHOUT lindblad operators # yields a known result. # Use e.q. 109 from # https://arxiv.org/pdf/1904.06560.pdf. hilbert_size = 4 identity_matrix = np.eye(hilbert_size, dtype=np.complex128) iswap_unitary = np.array( ((1, 0, 0, 0), (0, 0, -1j, 0), (0, -1j, 0, 0), (0, 0, 0, 1))) initial_states = matrix_to_column_vector_list(identity_matrix) target_states = matrix_to_column_vector_list(iswap_unitary) initial_densities = np.matmul(initial_states, conjugate_transpose(initial_states)) target_densities = np.matmul(target_states, conjugate_transpose(target_states)) system_hamiltonian = ( (1 / 2) * (np.kron(SIGMA_X, SIGMA_X) + np.kron(SIGMA_Y, SIGMA_Y))) hamiltonian = lambda controls, time: system_hamiltonian control_step_count = int(1e3) evolution_time = np.pi / 2 result = evolve_lindblad_discrete(control_step_count, evolution_time, initial_densities, hamiltonian=hamiltonian) final_densities = result.final_densities assert (np.allclose(final_densities, target_densities)) # Note that qutip only gets this result within 1e-5 error. tlist = np.linspace(0, evolution_time, control_step_count) c_ops = list() e_ops = list() options = Options(nsteps=control_step_count) for i, initial_density in enumerate(initial_densities): result = mesolve(Qobj(system_hamiltonian), Qobj(initial_density), tlist, c_ops, e_ops, options=options) final_density = result.states[-1].full() target_density = target_densities[i] assert (np.allclose(final_density, target_density, atol=1e-5)) #ENDFOR # Test that evolution WITHOUT a hamiltonian and WITH lindblad operators # yields a known result. # This test ensures that dissipators are working correctly. # Use e.q.14 from # https://inst.eecs.berkeley.edu/~cs191/fa14/lectures/lecture15.pdf. hilbert_size = 2 gamma = 2 lindblad_dissipators = np.array((gamma, )) lindblad_operators = np.stack((SIGMA_MINUS, )) lindblad_data = lambda time: (lindblad_dissipators, lindblad_operators) evolution_time = 1. control_step_count = int(1e3) inv_sqrt_2 = 1 / np.sqrt(2) a0 = np.random.rand() c0 = 1 - a0 b0 = np.random.rand() b0_star = np.conj(b0) initial_density_0 = np.array(((a0, b0), (b0_star, c0))) initial_densities = np.stack((initial_density_0, )) gt = gamma * evolution_time expected_final_density = np.array( ((1 - c0 * np.exp(-gt), b0 * np.exp(-gt / 2)), (b0_star * np.exp(-gt / 2), c0 * np.exp(-gt)))) result = evolve_lindblad_discrete(control_step_count, evolution_time, initial_densities, lindblad_data=lindblad_data) final_density = result.final_densities[0] assert (np.allclose(final_density, expected_final_density)) # Test that evolution WITH a random hamiltonian and WITH random lindblad operators # yields a similar result to qutip. # Note that the allclose tolerance may need to be adjusted. for matrix_size in range(2, _BIG): # Evolve under lindbladian. hamiltonian_matrix = _generate_hermitian_matrix(matrix_size) hamiltonian = lambda controls, time: hamiltonian_matrix lindblad_operator_count = np.random.randint(1, matrix_size) lindblad_operators = np.stack([ _generate_complex_matrix(matrix_size) for _ in range(lindblad_operator_count) ]) lindblad_dissipators = np.ones((lindblad_operator_count)) lindblad_data = lambda time: (lindblad_dissipators, lindblad_operators) density_matrix = _generate_hermitian_matrix(matrix_size) initial_densities = np.stack((density_matrix, )) evolution_time = 1 control_step_count = int(1e4) result = evolve_lindblad_discrete(control_step_count, evolution_time, initial_densities, hamiltonian=hamiltonian, lindblad_data=lindblad_data) final_density = result.final_densities[0] # Evolve under lindbladian with qutip. hamiltonian_qutip = Qobj(hamiltonian_matrix) initial_density_qutip = Qobj(density_matrix) lindblad_operators_qutip = [ Qobj(lindblad_operator) for lindblad_operator in lindblad_operators ] e_ops_qutip = list() tlist = np.linspace(0, evolution_time, control_step_count) options = Options(nsteps=control_step_count) result_qutip = mesolve( hamiltonian_qutip, initial_density_qutip, tlist, lindblad_operators_qutip, e_ops_qutip, ) final_density_qutip = result_qutip.states[-1].full() assert (np.allclose(final_density, final_density_qutip, atol=1e-6))
def _generate_hermitian_matrix(matrix_size): matrix = _generate_complex_matrix(matrix_size) return (matrix + conjugate_transpose(matrix)) * 0.5
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) 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) qnum = 2 mnum = 6 #Qubit rotation matrices Q_x = np.diag(np.sqrt(np.arange(1, qnum)), 1) + np.diag( np.sqrt(np.arange(1, qnum)), -1) Q_y = (0 + 1j) * (np.diag(np.sqrt(np.arange(1, qnum)), 1) - np.diag(np.sqrt(np.arange(1, qnum)), -1))
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) 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)) )
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 MAX_CONTROL_NORMS = np.array(( MAX_AMP_NORM_CAVITY, MAX_AMP_NORM_TRANSMON, )) # Define the problem
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. TRANSMON_E_DAGGER = conjugate_transpose(TRANSMON_E) H_SYSTEM = (2 * CHI_E * anp.kron(CAVITY_NUMBER - BLOCKADE_LEVEL, anp.matmul(TRANSMON_E, TRANSMON_E_DAGGER)) + OMEGA * anp.kron(CAVITY_I, anp.matmul(TRANSMON_G, TRANSMON_E_DAGGER) + anp.matmul(TRANSMON_E, TRANSMON_G_DAGGER)) + KAPPA / 2 * anp.kron(anp.matmul(CAVITY_NUMBER, CAVITY_NUMBER - CAVITY_I), TRANSMON_I)) assert(anp.allclose(H_SYSTEM, conjugate_transpose(H_SYSTEM))) H_C = anp.kron(CAVITY_ANNIHILATE, TRANSMON_I) H_C_DAGGER = conjugate_transpose(H_C) hamiltonian = (lambda controls, time: H_SYSTEM + controls[0] * H_C
def _random_hermitian_matrix(matrix_size): """ Generate a random, square, hermitian matrix of size `matrix_size`. """ matrix = _random_complex_matrix(matrix_size) return np.divide(matrix + conjugate_transpose(matrix), 2)