def test_fidelity_max_ket(): """Tests for ket states with respect to themselves to be equal to 1 (max)""" for _ in range(10): ket1 = jnp.asarray(rand_ket(25)) ket2 = jnp.asarray(rand_ket(25)) assert_almost_equal(fidelity(ket1, ket1), 1.0, decimal=6) assert_almost_equal(fidelity(ket2, ket2), 1.0, decimal=6)
def test_fidelity_max_dm(): """Tests for density matrices with respect to themselves to be equal to 1 (max)""" for _ in range(10): rho1 = jnp.asarray(rand_dm(25)) rho2 = jnp.asarray(rand_dm(25)) assert_almost_equal(fidelity(rho1, rho1), 1.0, decimal=4) assert_almost_equal(fidelity(rho2, rho2), 1.0, decimal=4)
def test_fidelity_bounded_purepure(tol=1e-7): """Tests for boundedness of fidelity among kets to be between [0, 1]""" for _ in range(10): ket1 = jnp.asarray(rand_ket(25)) ket2 = jnp.asarray(rand_ket(25)) F = fidelity(ket1, ket2) assert -tol <= F <= 1 + tol
def test_fidelity_bounded_mixedmixed(tol=1e-7): """Tests for boundedness of fidelity among mixed states to be between [0, 1]""" for _ in range(10): rho1 = jnp.asarray(rand_dm(25)) rho2 = jnp.asarray(rand_dm(25)) F = fidelity(rho1, rho2) assert -tol <= F <= 1 + tol
def test_score(params, inputs, outputs): """Calculates the average fidelity between the predicted and output kets for given parameters (averaged over the whole training set). Args: params (obj:`jnp.ndarray`): parameter vectors :math:`\vec{\theta}, \vec{\phi}, \vec{\omega}` inputs (obj:`jnp.ndarray`): input kets :math:`|\psi_{l} \rangle`in the dataset outputs (obj:`jnp.ndarray`): output kets :math:`U(\vec{t}, \vec{\tau})|ket_{input} \rangle` in the dataset Returns: float: fidelity between :math:`U(\vec{\theta}, \vec{\phi}, \vec{\omega})|ket_{input} \rangle` and the output (label) kets for given `params` """ fidel = 0 thetas, phis, omegas = params unitary = Unitary(N)(thetas, phis, omegas) for i in range(train_len): pred = jnp.dot(unitary, inputs[i]) step_fidel = fidelity(pred, outputs[i]) fidel += step_fidel return (fidel / train_len)[0][0]
def cost(params, initial, target): """ Calculates the cost between the target state and the one evolved by the action of three blocks. Args: ----- params (jnp.array): alpha and theta params of Displace and SNAP respectively initial (jnp.array): initial state to apply the blocks on target (jnp.array): desired state Returns: -------- cost (float): cost at a particular parameter vector """ alphas, thetas = params[0], params[1] evo = apply_blocks(alphas, thetas, initial) return 1 - fidelity(target, evo)[0][0]
def test_fidelity_bounded_puremixed(tol=1e-7): for _ in range(10): rho1 = jnp.asarray(rand_dm(25)) ket1 = jnp.asarray(rand_ket(25)) F = fidelity(rho1, ket1) assert -tol <= F <= 1 + tol
def test_fidelity(): """ Tests the fidelity function and computation of its gradient """ ket0 = jnp.array([[1.0], [0]]) # represents |0> ket1 = jnp.array([[0.0], [1]]) # represents |1> ket_plus = 1 / jnp.sqrt(2) * (ket0 + ket1) # represents |+> ket_minus = 1 / jnp.sqrt(2) * (ket0 - ket1) # represents |-> ket_complx = rand_ket(2).full() assert fidelity(ket0, ket1) == 0.0 assert fidelity(ket0, ket0) == 1.0 assert fidelity(ket1, ket1) == 1.0 assert_almost_equal(fidelity(ket_plus, ket_minus), 0.0) assert fidelity(rand_ket(4).full(), rand_ket(4).full()) <= 1.0 assert fidelity(rand_ket(10).full(), rand_ket(10).full()) >= 0.0 assert np.isclose(fidelity(ket_complx, ket_complx), 1.0) assert_almost_equal(fidelity(ket_plus, ket0), 1.0 / 2.0) assert_almost_equal(fidelity(ket_plus, ket1), 1.0 / 2.0) assert_almost_equal(fidelity(ket0, ket_minus), 1.0 / 2.0) assert_almost_equal(fidelity(ket1, ket_minus), 1.0 / 2.0)
# ## Testing on unseen kets # # We reserved the last $20$ (which is $20 \%$ of the total dataset) # kets for testing. # Now we shall apply our learned unitary matrix, call it # $U_{opt}(\vec{\theta}, \vec{\phi}, \vec{\omega})$ # to the unseen kets and measure the fidelity of the evolved ket # under $U_{opt}(\vec{\theta}, \vec{\phi}, \vec{\omega})$ # with those that evolved under the target unitary, $U$. theta_opt, phi_opt, omega_opt = params_hist[-1] opt_unitary = Unitary(N)(theta_opt, phi_opt, omega_opt) fidel = [] for i in range(train_len, m): # unseen data pred = jnp.dot(opt_unitary, ket_input[i]) fidel.append(fidelity(pred, ket_output[i])[0][0]) fidel # ## Conclusion # # We see that the testing fidelity is # $\sim 98 \%$, as opposed to training # fidelity $\sim 99 \%$. One would expect # this since drop as the unitary now # acts on unseen data. We, however, note # that we generalize well with # $\sim 98 \%$ accuracy, if you will. # # This learnt unitary # $U_{opt}(\vec{\theta}, \vec{\phi}, \vec{\omega})$ # can now be used to emulate the original