def block_matrix(N): """Construct the block-diagonal matrix for the Dicke basis. Parameters ---------- N: int Number of two-level systems. Returns ------- block_matr: ndarray A 2D block-diagonal matrix of ones with dimension (nds,nds), where nds is the number of Dicke states for N two-level systems. """ nds = _num_dicke_states(N) # create a list with the sizes of the blocks, in order blocks_dimensions = int(N / 2 + 1 - 0.5 * (N % 2)) blocks_list = [(2 * (i + 1 * (N % 2)) + 1 * ((N + 1) % 2)) for i in range(blocks_dimensions)] blocks_list = np.flip(blocks_list, 0) # create a list with each block matrix as element square_blocks = [] k = 0 for i in blocks_list: square_blocks.append(np.ones((i, i))) k = k + 1 return block_diag(square_blocks)
def ghz(N, basis="dicke"): """ Generate the density matrix of the GHZ state. If the argument `basis` is "uncoupled" then it generates the state in a 2**N dim Hilbert space. Parameters ---------- N: int The number of two-level systems. basis: str The basis to use. Either "dicke" or "uncoupled". Returns ------- state: :class: qutip.Qobj The GHZ state density matrix in the requested basis. """ if basis == "uncoupled": return _uncoupled_ghz(N) nds = _num_dicke_states(N) rho = dok_matrix((nds, nds)) rho[0, 0] = 1 / 2 rho[N, N] = 1 / 2 rho[N, 0] = 1 / 2 rho[0, N] = 1 / 2 return Qobj(rho)
def ground(N, basis="dicke"): """ Generate the density matrix of the ground state. This state is given by |N/2, -N/2> in the Dicke basis. If the argument `basis` is "uncoupled" then it generates the state in a 2**N dim Hilbert space. Parameters ---------- N: int The number of two-level systems. basis: str The basis to use. Either "dicke" or "uncoupled" Returns ------- state: :class: qutip.Qobj The ground state density matrix in the requested basis. """ if basis == "uncoupled": state = _uncoupled_ground(N) return state nds = _num_dicke_states(N) rho = dok_matrix((nds, nds)) rho[N, N] = 1 return Qobj(rho)
def block_matrix(N): """Construct the block-diagonal matrix for the Dicke basis. Parameters ---------- N: int Number of two-level systems. Returns ------- block_matr: ndarray A 2D block-diagonal matrix of ones with dimension (nds,nds), where nds is the number of Dicke states for N two-level systems. """ nds = _num_dicke_states(N) # create a list with the sizes of the blocks, in order blocks_dimensions = int(N/2 + 1 - 0.5*(N % 2)) blocks_list = [(2 * (i+1 * (N % 2)) + 1*((N+1) % 2)) for i in range(blocks_dimensions)] blocks_list = np.flip(blocks_list, 0) # create a list with each block matrix as element square_blocks = [] k = 0 for i in blocks_list: square_blocks.append(np.ones((i, i))) k = k + 1 return block_diag(square_blocks)
def ground(N, basis="dicke"): """ Generate the density matrix of the ground state. This state is given by (N/2, -N/2) in the Dicke basis. If the argument `basis` is "uncoupled" then it generates the state in a :math:`2^N`-dimensional Hilbert space. Parameters ---------- N: int The number of two-level systems. basis: str The basis to use. Either "dicke" or "uncoupled" Returns ------- state: :class: qutip.Qobj The ground state density matrix in the requested basis. """ if basis == "uncoupled": state = _uncoupled_ground(N) return state nds = _num_dicke_states(N) rho = dok_matrix((nds, nds)) rho[N, N] = 1 return Qobj(rho)
def ghz(N, basis="dicke"): """ Generate the density matrix of the GHZ state. If the argument `basis` is "uncoupled" then it generates the state in a :math:`2^N`-dimensional Hilbert space. Parameters ---------- N: int The number of two-level systems. basis: str The basis to use. Either "dicke" or "uncoupled". Returns ------- state: :class: qutip.Qobj The GHZ state density matrix in the requested basis. """ if basis == "uncoupled": return _uncoupled_ghz(N) nds = _num_dicke_states(N) rho = dok_matrix((nds, nds)) rho[0, 0] = 1/2 rho[N, N] = 1/2 rho[N, 0] = 1/2 rho[0, N] = 1/2 return Qobj(rho)
def num_dicke_states(N): """Calculate the number of Dicke states. Parameters ---------- N: int The number of two-level systems. Returns ------- nds: int The number of Dicke states. """ return _num_dicke_states(N)
def dicke_basis(N, jmm1=None): """ Initialize the density matrix of a Dicke state for several (j, m, m1). This function can be used to build arbitrary states in the Dicke basis |j, m><j, m1|. We create coefficients for each (j, m, m1) value in the dictionary jmm1. For instance, if we start from the most excited state for N = 2, we have the following state represented as a density matrix of size (nds, nds) or (4, 4). 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 The mapping for the (i, k) index of the density matrix to the |j, m> values is given by the cythonized function `jmm1_dictionary`. Parameters ---------- N: int The number of two-level systems. jmm1: dict A dictionary of {(j, m, m1): p} that gives a density p for the (j, m, m1) matrix element. Returns ------- rho: :class: qutip.Qobj The density matrix in the Dicke basis. """ if jmm1 is None: msg = "Please specify the jmm1 values as a dictionary" msg += "or use the `excited(N)` function to create an" msg += "excited state where jmm1 = {(N/2, N/2, N/2): 1}" raise AttributeError(msg) nds = _num_dicke_states(N) rho = np.zeros((nds, nds)) jmm1_dict = jmm1_dictionary(N)[1] for key in jmm1: i, k = jmm1_dict[key] rho[i, k] = jmm1[key] return Qobj(rho)
def dicke_basis(N, jmm1=None): """ Initialize the density matrix of a Dicke state for several (j, m, m1). This function can be used to build arbitrary states in the Dicke basis :math:`|j, m\\rangle \\langle j, m^{\\prime}|`. We create coefficients for each (j, m, m1) value in the dictionary jmm1. The mapping for the (i, k) index of the density matrix to the |j, m> values is given by the cythonized function `jmm1_dictionary`. A density matrix is created from the given dictionary of coefficients for each (j, m, m1). Parameters ---------- N: int The number of two-level systems. jmm1: dict A dictionary of {(j, m, m1): p} that gives a density p for the (j, m, m1) matrix element. Returns ------- rho: :class: qutip.Qobj The density matrix in the Dicke basis. """ if jmm1 is None: msg = "Please specify the jmm1 values as a dictionary" msg += "or use the `excited(N)` function to create an" msg += "excited state where jmm1 = {(N/2, N/2, N/2): 1}" raise AttributeError(msg) nds = _num_dicke_states(N) rho = np.zeros((nds, nds)) jmm1_dict = jmm1_dictionary(N)[1] for key in jmm1: i, k = jmm1_dict[key] rho[i, k] = jmm1[key] return Qobj(rho)