qtcad.device.quantum module

Objects and operations in quantum theory.

class qtcad.device.quantum.MbState(bas_set, coeff, energy)

Bases: MbState

Many-body state defined in the \(N\)-particle Fock space.

As explained in the QTCAD documentation theory section, \(N\)-particle many-body states are represented as linear combinations of the many-body basis states that span the relevant \(N\)-particle subspace (represented by a Subspace object). The conventions employed to represent the many-body basis states within an \(N\)-particle subspace are described in the API reference of the Subspace class.

  • N (int) – particle number

  • bas_set (list of integers) – basis set spanning the N-particle Fock space. Each array in the list is an integer whose binary representation gives the occupation of each single-particle basis state in increasing energy order when read from the right to the left.

  • coeff (1d complex array) – coefficients on the basis set to define the many-body state.

  • energy (float) – eigenenergy if the state is an eigenstate of a many- body Hamiltonian.

class qtcad.device.quantum.Subspace(ham_hop, coulomb_mat, N, n_degen)

Bases: Subspace

Eigen-subspace of a given many-body Hamiltonian with a definite number of particles \(N\).

Each \(N\)-particle subspace is spanned by many-body basis states that may be represented as binary numbers. For example, assuming three spin-degenerate single-electron basis states, the 2-electron basis state in which the first and third single-particle basis states are occupied would be “000101”. We read this binary string from right to left, thus corresponding in ket notation to:

\[\mathrm{^{``}000101''} = |101000\rangle = c^\dagger_{0\downarrow} c^\dagger_{1\downarrow}|0\rangle,\]

where \(c^{(\dagger)}_{j\sigma}\) annihilates (creates) a particle in the single-particle orbital state \(j\) with spin \(\sigma\), and \(|0\rangle\) is the vacuum state. In this ket notation, each integer (0 or 1) labels the occupation of the corresponding single-particle basis state.

The single-particle basis states themselves are stored in the order in which they are input to the many-body solver (if they are) through the eigenfunctions attribute of the input Device object, or otherwise they are sorted from the lowest to the highest energy as output by the single-particle Schrödinger solver. If a degeneracy factor \(g\) is introduced (2 in the above example), then each single-particle state is copied \(g\) times, with copies of the same state stacked next to each other. For example, in the above example of a 3-level single-particle basis set with degeneracy g=2, the single-particle basis states are, respectively:

  • ground orbital state with spin down (\(|0\downarrow\rangle\));

  • ground orbital state with spin up (\(|0\uparrow\rangle\));

  • first-excited orbital state with spin down (\(|1\downarrow\rangle\));

  • first-excited orbital state with spin up (\(|1\uparrow\rangle\));

  • second-excited orbital state with spin down (\(|2\downarrow\rangle\)); and

  • second-excited orbital state with spin up (\(|2\uparrow\rangle\)).

Regarding ordering of the many-body basis states (binary strings), the convention is as follows. Each integer has a binary representation (it can be generated with the bin function in Python). For example, bin(33) = 100001. A given \(N\)-particle subspace may then be represented by the list of integers for which the binary representation has a Hamming weight (number of non-zero entries) that is equal to \(N\). Then, the \(N\)-particle basis states are sorted from the one with the lowest integer representation to the one with the highest integer representation. When the binary representation of an integer has less digits than the number of single-particle basis states (including degeneracy), then it should be understood as padded with zeros from the left. For example, in a 3-orbital spin-degenerate single-particle basis (total single-particle basis dimension of 6), and in the 2-electron subspace (Hamming weight = 2), the integer 5 has binary representation “101”, which is padded into “000101”, corresponding to occupation numbers [1,0,1,0,0,0] from the lowest to highest energy single-particle basis states (\(|101000\rangle\) in ket notation).

  • N (int) – Particle number

  • eigval (1d array) – Eigenvalues of the many-body Hamiltonian within this N-particle subspace, sorted in increasing energy order.

  • eigvec (2d array) – Eigenvectors of the many-body Hamiltonian, expressed as a linear combination of the many-body basis states in this N-particle subspace. The row index corresponds to the eigenstate index (eigenstates are stored from the lowest-energy to the highest-energy state). The column index labels many-body basis states.

__init__(ham_hop, coulomb_mat, N, n_degen)

initializes Subspace with given Hamiltonian and particle number

  • ham_hop (real/complex 2d-array) – single-body Hamiltonian

  • coulomb_mat (4d real/complex array) – interaction V_ijkl, where i,j,k,l are indices of one-particle orbitals.

  • N (int) – particle number in this subspace

  • n_degen (int) – Total degeneracy of the single-particle eigenstates in this subspace.


Gets the many-body basis set corresponding to this subspace.


dtype (str, optional) – The data type to use to represent each many-body eigenstate. Available types are "int", "str", and "array". Default: "int".


ndarray – An array whose entries represent many-body eigenstates.


  • When dtype is "int", each many-body eigenstate is labeled by an integer whose binary representation gives the occupation (0 or 1) of each orbital. This is the default behavior as, knowing the total number of basis states, this is the most compact representation of a many-body basis state.

  • When dtype is "str", each many-body eigenstate is labeled by a string giving the binary representation of the occupations (0 or 1) of each orbital. Note that the first digits are padded with zeros to match the total number of available orbitals. In addition, binary digits are read right-to-left when converting into particle occupation representation.

  • When dtype is "array", each state is given by an array of integers–1 if the orbital is occupied, 0 otherwise. The result is a 2D array whose first index (rows) labels many-body basis states and whose second index (columns) labels single-particle orbital occupation. The orbital occupations are read left-to-right, while binary digits are read right-to-left. This more “physical” representation should only be used for display purposes, since it is not optimal in terms of memory.

get_density(i, one_body_states)

Obtain particle density for a given energy eigenstate.

  • i (int) – Index of the energy eigenstate

  • one_body_states (2D or 3D array) – Eigenfunctions from a device. 2D if there is no band index, 3D if there is a band index (spin or hole bands)


1D array – Particle density over global nodes.


generates and returns a MbState-object corresponding to the i-th eigen-state in this subspace


i (int) – index of the eigenstate to be returned


MbState – the i-th eigen-state


Returns the many-body Hamiltonian for this subspace.


ndarray – The many-body Hamiltonian in SI energy units (Joules), written in the many-body basis set of this subspace.