Class for storing Hamiltonians that are quadratic in the fermionic

Inherits From: PolynomialTensor

Used in the notebooks

Used in the tutorials

ladder operators. The operators stored in this class take the form

$$ \sum{p, q} (M{pq} - \mu \delta_{pq}) a^\dagger_p a_q

+ \frac12 \sum_{p, q}
    (\Delta_{pq} a^\dagger_p a^\dagger_q + \text{h.c.})
+ \text{constant}



- \\(M\\) is a Hermitian `n_qubits` x `n_qubits` matrix.
- \\(\Delta\\) is an antisymmetric `n_qubits` x `n_qubits` matrix.
- \\(\mu\\) is a real number representing the chemical potential.
- \\(\delta_{pq}\\) is the Kronecker delta symbol.

We separate the chemical potential \(\mu\) from \(M\) so that we can use it to adjust the expectation value of the total number of particles.

hermitian_part(ndarray): The matrix \(M\), which represents the coefficients of the particle-number-conserving terms. This is an n_qubits x n_qubits numpy array of complex numbers. antisymmetric_part(ndarray): The matrix \(\Delta\), which represents the coefficients of the non-particle-number-conserving terms. This is an n_qubits x n_qubits numpy array of complex numbers. constant(float, optional): A constant term in the operator. chemical_potential(float, optional): The chemical potential \(\mu\).

antisymmetric_part The antisymmetric part.
combined_hermitian_part The Hermitian part including the chemical potential.
conserves_particle_number Whether this Hamiltonian conserves particle number.
constant The value of the constant term.
hermitian_part The Hermitian part not including the chemical potential.




View source

Increase (or decrease) the chemical potential by some value.


View source

Compute the unitary that diagonalizes a quadratic Hamiltonian.

Any quadratic Hamiltonian can be rewritten in the form

\[ \sum_{j} \varepsilon_j b^\dagger_j b_j + \text{constant}, \]

where the \(b^\dagger_j\) are a new set fermionic creation operators that satisfy the canonical anticommutation relations. The new creation operators are linear combinations of the original ladder operators. In the most general case, creation and annihilation operators are mixed together:

\[ \begin{pmatrix} b^\dagger_1 \\ \vdots \\ b^\dagger_N \\ \end{pmatrix} = W \begin{pmatrix} a^\dagger_1 \\ \vdots \\ a^\dagger_N \\ a_1 \\ \vdots \\ a_N \end{pmatrix}, \]

where \(W\) is an \(N \times (2N)\) matrix. However, if the Hamiltonian conserves particle number then creation operators don't need to be mixed with annihilation operators and \(W\) only needs to be an \(N \times N\) matrix:

\[ \begin{pmatrix} b^\dagger_1 \\ \vdots \\ b^\dagger_N \\ \end{pmatrix} = W \begin{pmatrix} a^\dagger_1 \\ \vdots \\ a^\dagger_N \\ \end{pmatrix}, \]

This method returns the matrix \(W\).

spin_sector (optional str): An optional integer specifying a spin sector to restrict to: 0 for spin-up and 1 for spin-down. Should only be specified if the Hamiltonian includes a spin degree of freedom and spin-up modes do not interact with spin-down modes. If specified, the modes are assumed to be ordered so that spin-up orbitals come before spin-down orbitals.

orbital_energies(ndarray) A one-dimensional array containing the \(\varepsilon_j\) diagonalizing_unitary (ndarray): A matrix representing the transformation \(W\) of the fermionic ladder operators. If the Hamiltonian conserves particle number then this is \(N \times N\); otherwise it is \(N \times 2N\). If spin sector is specified, then \(N\) here represents the number of spatial orbitals rather than spin orbitals. constant(float) The constant


View source

Get a circuit for a unitary that diagonalizes this Hamiltonian

This circuit performs the transformation to a basis in which the Hamiltonian takes the diagonal form

\[ \sum_{j} \varepsilon_j b^\dagger_j b_j + \text{constant}. \]


circuit_description (list[tuple]):
    A list of operations describing the circuit. Each operation
    is a tuple of objects describing elementary operations that
    can be performed in parallel. Each elementary operation
    is either the string 'pht' indicating a particle-hole
    transformation on the last fermionic mode, or a tuple of
    the form \\((i, j, \theta, \varphi)\\),
    indicating a Givens rotation
    of modes \\(i\\) and \\(j\\) by angles \\(\theta\\)
    and \\(\varphi\\).


View source

Return the ground energy.


View source

Return the Majorana represention of the Hamiltonian.

Any quadratic Hamiltonian can be written in the form

\[ \frac{i}{2} \sum_{j, k} A_{jk} f_j f_k + \text{constant} \]

where the \(f_i\) are normalized Majorana fermion operators:

\(\) f_j = \frac{1}{\sqrt{2} } (a^\dagger_j + a_j)

f_{j + N} = \frac{i}{\sqrt{2} } (a^\dagger_j - a_j)


and \(A\) is a (2 * n_qubits) x (2 * n_qubits) real antisymmetric matrix. This function returns the matrix \(A\) and the constant.


View source

Return the orbital energies.

Any quadratic Hamiltonian is unitarily equivalent to a Hamiltonian of the form

\[ \sum_{j} \varepsilon_j b^\dagger_j b_j + \text{constant}. \]

We call the \(\varepsilon_j\) the orbital energies. The eigenvalues of the Hamiltonian are sums of subsets of the orbital energies (up to the additive constant).

non_negative(bool): If True, always return a list of orbital energies that are non-negative. This option is ignored if the Hamiltonian does not conserve particle number, in which case the returned orbital energies are always non-negative.


orbital_energies(ndarray) A one-dimensional array containing the \(\varepsilon_j\) constant(float) The constant


View source

Keep only selected elements.

selection (Union[int, Iterable[int]): If int, keeps terms with at most (exactly, if exact is True) that many unique indices. If iterable, keeps only terms containing (all of, if exact is True) the specified indices. exact (bool): Whether or not the selection is strict.


View source

Rotate the orbital basis of the PolynomialTensor.

rotation_matrix A square numpy array or matrix having dimensions of n_qubits by n_qubits. Assumed to be real and invertible.


View source


View source


View source

Return self==value.


View source

Look up matrix element.

args Tuples indicating which coefficient to get. For instance, my_tensor[(6, 1), (8, 1), (2, 0)] returns my_tensor.n_body_tensors[1, 1, 0][6, 8, 2]


View source

Iterate over non-zero elements of PolynomialTensor.


View source


View source


View source

Return self!=value.


View source


View source


View source


View source


View source


View source