def gkp(hilbert_size, delta, mu=0, zrange=20): """Generates a GKP state. For a detailed discussion on the definition see `Albert, Victor V. et al. “Performance and Structure of Single-Mode Bosonic Codes.” Physical Review A 97.3 (2018) <https://arxiv.org/abs/1708.05010>`_ and `Ahmed, Shahnawaz et al., “Classification and reconstruction of quantum states with neural networks.” Journal <https://arxiv.org/abs/1708.05010>`_ Args: hilbert_size (int): Hilbert space size (cutoff). delta (float): mu (int, optional): Logical encoding (0/1) default: 0 zrange (int, optional): The number of lattice points to loop over to construct the grid of states. This depends on the Hilbert space size and the delta value. default: 20 Returns: :class:`qutip.Qobj`: GKP state. """ gkp = 0 * coherent(hilbert_size, 0) c = np.sqrt(np.pi / 2) zrange = range(-20, 20) for n1 in zrange: for n2 in zrange: a = c * (2 * n1 + mu + 1j * n2) alpha = coherent(hilbert_size, a) gkp += (np.exp(-(delta**2) * np.abs(a)**2) * np.exp(-1j * c**2 * 2 * n1 * n2) * alpha) ket = gkp.unit() return ket
def test_wigner_coherent(): "wigner: test wigner function calculation for coherent states" xvec = np.linspace(-5.0, 5.0, 100) yvec = xvec X, Y = np.meshgrid(xvec, yvec) a = X + 1j * Y # consistent with g=2 option to wigner function dx = xvec[1] - xvec[0] dy = yvec[1] - yvec[0] N = 20 beta = rand() + rand() * 1.0j psi = coherent(N, beta) # calculate the wigner function using qutip and analytic formula W_qutip = wigner(psi, xvec, yvec, g=2) W_analytic = 2 / np.pi * np.exp(-2 * abs(a - beta) ** 2) # check difference assert_(np.sum(abs(W_qutip - W_analytic) ** 2) < 1e-4) # check normalization assert_(np.sum(W_qutip) * dx * dy - 1.0 < 1e-8) assert_(np.sum(W_analytic) * dx * dy - 1.0 < 1e-8)
def test_wigner_coherent(): "wigner: test wigner function calculation for coherent states" xvec = np.linspace(-5.0, 5.0, 100) yvec = xvec X, Y = np.meshgrid(xvec, yvec) a = X + 1j * Y # consistent with g=2 option to wigner function dx = xvec[1] - xvec[0] dy = yvec[1] - yvec[0] N = 20 beta = rand() + rand() * 1.0j psi = coherent(N, beta) # calculate the wigner function using qutip and analytic formula W_qutip = wigner(psi, xvec, yvec, g=2) W_qutip_cl = wigner(psi, xvec, yvec, g=2, method='clenshaw') W_analytic = 2 / np.pi * np.exp(-2 * abs(a - beta)**2) # check difference assert_(np.sum(abs(W_qutip - W_analytic)**2) < 1e-4) assert_(np.sum(abs(W_qutip_cl - W_analytic)**2) < 1e-4) # check normalization assert_(np.sum(W_qutip) * dx * dy - 1.0 < 1e-8) assert_(np.sum(W_qutip_cl) * dx * dy - 1.0 < 1e-8) assert_(np.sum(W_analytic) * dx * dy - 1.0 < 1e-8)
def cat(hilbert_size, alpha, S=0, mu=0): """ Generates a cat state. For a detailed discussion on the definition see `Albert, Victor V. et al. “Performance and Structure of Single-Mode Bosonic Codes.” Physical Review A 97.3 (2018) <https://arxiv.org/abs/1708.05010>`_ and `Ahmed, Shahnawaz et al., “Classification and reconstruction of quantum states with neural networks.” Journal <https://arxiv.org/abs/1708.05010>`_ Args: ----- hilbert_size (int): Hilbert size dimension. alpha (complex64): Complex number determining the amplitude. S (int): An integer >= 0 determining the number of coherent states used to generate the cat superposition. S = {0, 1, 2, ...}. corresponds to {2, 4, 6, ...} coherent state superpositions. default: 0 mu (int): An integer 0/1 which generates the logical 0/1 encoding of a computational state using the cat state. default: 0 Returns: ------- cat (:class:`qutip.Qobj`): Cat state ket. """ kend = 2 * S + 1 cstates = 0 * (coherent(hilbert_size, 0)) for k in range(0, int((kend + 1) / 2)): sign = 1 if k >= S: sign = (-1)**int(mu > 0.5) prefactor = np.exp(1j * (np.pi / (S + 1)) * k) cstates += sign * coherent(hilbert_size, prefactor * alpha * (-((1j)**mu))) cstates += sign * coherent(hilbert_size, -prefactor * alpha * (-((1j)**mu))) ket = cstates.unit() return ket
def test_sparse_nonsymmetric_reverse_permute(): "Sparse: Nonsymmetric Reverse Permute" # CSR square array check A = rand_dm(25, 0.5) rperm = np.random.permutation(25) cperm = np.random.permutation(25) x = sp_permute(A.data, rperm, cperm) B = sp_reverse_permute(x, rperm, cperm) assert_equal((A.full() - B.toarray()).all(), 0) # CSC square array check A = rand_dm(25, 0.5) rperm = np.random.permutation(25) cperm = np.random.permutation(25) B = A.data.tocsc() x = sp_permute(B, rperm, cperm) B = sp_reverse_permute(x, rperm, cperm) assert_equal((A.full() - B.toarray()).all(), 0) # CSR column vector check A = coherent(25, 1) rperm = np.random.permutation(25) x = sp_permute(A.data, rperm, []) B = sp_reverse_permute(x, rperm, []) assert_equal((A.full() - B.toarray()).all(), 0) # CSC column vector check A = coherent(25, 1) rperm = np.random.permutation(25) B = A.data.tocsc() x = sp_permute(B, rperm, []) B = sp_reverse_permute(x, rperm, []) assert_equal((A.full() - B.toarray()).all(), 0) # CSR row vector check A = coherent(25, 1).dag() cperm = np.random.permutation(25) x = sp_permute(A.data, [], cperm) B = sp_reverse_permute(x, [], cperm) assert_equal((A.full() - B.toarray()).all(), 0) # CSC row vector check A = coherent(25, 1).dag() cperm = np.random.permutation(25) B = A.data.tocsc() x = sp_permute(B, [], cperm) B = sp_reverse_permute(x, [], cperm) assert_equal((A.full() - B.toarray()).all(), 0)