def test_dag_ket(): r"""Tests the dagger operation :math:`A^{\dagger}` on operator :math:`A`""" # test with all real entries assert_array_equal(dag(basis(2, 0)), [[1.0, 0.0]]) assert_array_equal(dag(basis(2, 1)), [[0.0, 1.0]]) # test with all complex entries ket1 = jnp.array( [ [0.04896761 + 0.18014458j], [0.6698803 + 0.13728367j], [-0.07598839 + 0.38113445j], [-0.00505985 + 0.10700243j], [-0.18735261 + 0.5476768j], ], dtype=jnp.complex64, ) ket1_dag = jnp.array( [ [ 0.04896761 - 0.18014458j, 0.6698803 - 0.13728367j, -0.07598839 - 0.38113445j, -0.00505985 - 0.10700243j, -0.18735261 - 0.5476768j, ] ], dtype=jnp.complex64, ) assert_array_equal(dag(ket1), ket1_dag)
def circuit(params): thetax, thetay, thetaz = params layer0 = jnp.kron(basis(2, 0), basis(2, 0)) layer1 = jnp.kron(ry(jnp.pi / 4), ry(jnp.pi / 4)) layer2 = jnp.kron(rx(thetax), jnp.eye(2)) layer3 = jnp.kron(ry(thetay), rz(thetaz)) layers = [layer1, cnot(), layer2, cnot(), layer3] unitary = reduce(lambda x, y: jnp.dot(x, y), layers) return jnp.dot(unitary, layer0)
def circuit(params): thetax, thetay, thetaz = params layer0 = jnp.kron(basis(2, 0), basis(2, 0)) layer1 = J() layer2 = jnp.kron(rx(thetax), rx(thetax)) layer3 = jnp.kron(ry(thetay), ry(thetay)) layer4 = jnp.kron(rz(thetaz), rz(thetaz)) layer5 = J_dag() layers = [layer5, layer4, layer3, layer2, layer1] unitary = reduce(lambda x, y: jnp.dot(x, y), layers) #unitary = np.dot(layer5,np.dot(layer4, np.dot(layer3, np.dot(layer2, layer1)))) return jnp.dot(unitary, layer0)
def test_to_dm(): """Tests the `to_dm` method that converts kets and bras to density matrices""" dm0 = jnp.array( [[1.0 + 0.0j, 0.0 + 0.0j], [0.0 + 0.0j, 0.0 + 0.0j]], dtype=jnp.complex64 ) dm1 = jnp.array( [[0.0 + 0.0j, 0.0 + 0.0j], [0.0 + 0.0j, 1.0 + 0.0j]], dtype=jnp.complex64 ) # testing kets assert_array_equal(to_dm(basis(2, 0)), dm0) assert_array_equal(to_dm(basis(2, 1)), dm1) # testing bras assert_array_equal(to_dm(dag(basis(2, 0))), dm0) assert_array_equal(to_dm(dag(basis(2, 1))), dm1)
def test_create(): """Tests for the creation operator""" b3 = basis(5, 3) c5 = create(5) raised = jnp.dot(c5, b3) assert_equal(np.allclose(raised, 2.0 * basis(5, 4)), True) c3 = create(3) matrix3 = jnp.asarray( [ [0.00000000 + 0.0j, 0.00000000 + 0.0j, 0.00000000 + 0.0j], [1.00000000 + 0.0j, 0.00000000 + 0.0j, 0.00000000 + 0.0j], [0.00000000 + 0.0j, 1.41421356 + 0.0j, 0.00000000 + 0.0j], ] ) assert_equal(np.allclose(matrix3, c3), True)
def test_expect_sigmaxyz(op, state): """Tests the `expect` function on Pauli-X, Pauli-Y and Pauli-Z.""" # The stacked pytest decorators check all the argument combinations like a Cartesian product if jnp.all(op != sigmaz()): assert expect(op, state) == 0.0 elif jnp.all(state == basis(2, 0)): assert expect(op, state) == 1.0 else: assert expect(op, state) == -1.0
def test_destroy(): """Tests the annihilation/destroy/lowering operator""" # Destruction operator annihilates the bosonic number state b9 = basis(10, 9) # Fock/number state with 1 at 9th index d10 = destroy(10) # 10-dimensional destroy operator lowered = jnp.dot(d10, b9) assert_array_almost_equal(lowered, 3.0 * basis(10, 8)) d3 = destroy(3) matrix3 = jnp.asarray( [ [0.00000000 + 0.0j, 1.00000000 + 0.0j, 0.00000000 + 0.0j], [0.00000000 + 0.0j, 0.00000000 + 0.0j, 1.41421356 + 0.0j], [0.00000000 + 0.0j, 0.00000000 + 0.0j, 0.00000000 + 0.0j], ] ) assert_equal(np.allclose(matrix3, d3), True) assert_equal(np.allclose(dag(destroy(3)), create(3)), True)
def test_isdm(): # Check when matrix is non-semi-positive-definite non_spd = jnp.array([[1, 1], [-1, 1]]) assert isdm(non_spd) == False # Check standard density matrices assert isdm(to_dm(basis(2, 0))) == True # Check when matrix is non-hermitian assert isdm(sigmax() * sigmay()) == False # Check when trace is non-unity assert isdm(jnp.eye(2) * 2) == False
def circuit(params): """Returns the state evolved by the parametrized circuit Args: params (list): rotation angles for x, y, and z rotations respectively. Returns: :obj:`jnp.array`: state evolved by a parametrized circuit """ thetax, thetay, thetaz = params layer0 = jnp.kron(basis(2, 0), basis(2, 0)) layer1 = jnp.kron(ry(jnp.pi / 4), ry(jnp.pi / 4)) layer2 = jnp.kron(rx(thetax), jnp.eye(2)) layer3 = jnp.kron(ry(thetay), rz(thetaz)) layers = [layer1, cnot(), layer2, cnot(), layer3] unitary = reduce(lambda x, y: jnp.dot(x, y), layers) return jnp.dot(unitary, layer0)
def snap(hilbert_size, thetas): """ Constructs the matrix for a SNAP gate operation that can be applied to a state. Args: hilbert_size (int): Hilbert space cuttoff thetas (:obj:`jnp.ndarray`): A vector of theta values to apply SNAP operation Returns: :obj:`jnp.ndarray`: matrix representing the SNAP gate """ op = 0 * jnp.eye(hilbert_size) for i, theta in enumerate(thetas): op += jnp.exp(1j * theta) * to_dm(basis(hilbert_size, i)) return op
# $\alpha$ and $\vec{\theta}$ def show_state(state): """Shows the Hinton plot and Wigner function for the state""" fig, ax = plt.subplots(1, 2, figsize=(11, 5)) if state.shape[1] == 1: # State is a ket dm = Qobj(onp.array(jnp.dot(state, dag(state)))) hinton(dm, ax=ax[0]) plot_wigner(dm, ax=ax[1]) plt.show() N = 10 # Hilbert space cutoff initial_state = basis(N, 0) # initial vacuum state show_state(initial_state) alphas = jnp.array([1.0, 0.5, 1.0]) # Displace parameters theta1, theta2, theta3 = [0.5], [0.5, 1.5, 0.5], [0.5, 1.5, 0.5, 1.3] # SNAP parameters # NOTE: No input values to JAX differentiable functions should be int thetas = jnp.array([pad_thetas(N, p) for p in [theta1, theta2, theta3]]) evolved_state = apply_blocks(alphas, thetas, initial_state) show_state(evolved_state) # The target state that we aim to reach is visualized below. # The aim is to act `apply_blocks` function to the initial # state with the optimized parameters, say $\alpha_{opt}$
def test_basis(): """Tests the `basis` method""" np_arr = np.zeros((4, 1), dtype=np.complex64) np_arr[2, 0] = 1.0 assert np.array_equal(basis(4, 2), jnp.asarray(np_arr))
def test_sigmax(): assert_array_equal(sigmax(), jnp.array([[0.0, 1.0], [1.0, 0.0]])) def test_sigmay(): assert_array_equal( sigmay(), jnp.array([[0.0 + 0.0j, 0.0 - 1.0j], [0.0 + 1.0j, 0.0 + 0.0j]]) ) def test_sigmaz(): assert_array_equal(sigmaz(), jnp.array([[1.0, 0.0], [0.0, -1.0]])) @pytest.mark.parametrize("op", [sigmax(), sigmay(), sigmaz()]) @pytest.mark.parametrize("state", [basis(2, 0), basis(2, 1)]) def test_expect_sigmaxyz(op, state): """Tests the `expect` function on Pauli-X, Pauli-Y and Pauli-Z.""" # The stacked pytest decorators check all the argument combinations like a Cartesian product if jnp.all(op != sigmaz()): assert expect(op, state) == 0.0 elif jnp.all(state == basis(2, 0)): assert expect(op, state) == 1.0 else: assert expect(op, state) == -1.0 @pytest.mark.parametrize( "oper, state", [ (rand_herm(2).full(), basis(2, 0)),
def test_coherent(): """Tests the coherent state method""" assert abs(expect(destroy(10), coherent(10, 0.5)) - 0.5) < 1e-4 # Tests the border case with alpha = 0 for N in range(2, 30, 5): assert_array_almost_equal(coherent(N, 0), basis(N, 0))