Fermionic package¶
Piquasso package for Fermionic quantum computation.
Note
This feature is still experimental.
Basic notations¶
Let \(f_k\) and \(f_k^\dagger\) denote the Dirac operators. These fulfill the CAR algebra, i.e.,
Let us define \(\mathbf{f}\) as
The Majorana operators are defined as
where \(f_k\) and \(f_k^\dagger\) denote the Dirac operators.
\(\mathbf{m}\) denotes the vector of Majorana operators, i.e.,
Fermionic instructions¶
Extra instructions specific for Fermionic quantum computing.
- class ParentHamiltonian(hamiltonian)¶
Bases:
PreparationPrepares the fermionic Gaussian state with a specified parent Hamiltonian.
The density matrix is of the form
\[\rho = \frac{e^{\hat{H}}}{\operatorname{Tr} e^{\hat{H}}},\]where \(\hat{H}\) is the parent Hamiltonian and has the form
\[\begin{split}\hat{H} &= \mathbf{f}^\dagger H \mathbf{f}, \\\\ H &= \begin{bmatrix} - \overline{A} & B \\ - \overline{B} & A \end{bmatrix}. \\\\\end{split}\]Here, \(A\) is self-adjoint and \(B\) is skew-symmetric.
- class GaussianHamiltonian(hamiltonian)¶
Bases:
GateApplies a fermionic Gaussian transformation using its quadratic Hamiltonian.
The gate unitary is of the form
\[U = e^{i \hat{H}},\]where
\[\begin{split}\hat{H} &= \mathbf{f} H \mathbf{f}^\dagger, \\\\ H &= \begin{bmatrix} A & -\overline{B} \\ B & -\overline{A} \end{bmatrix}.\end{split}\]Here, \(A\) is self-adjoint and \(B\) is skew-symmetric.
- class ControlledPhase(phi: float)¶
Bases:
GateControlled-phase gate.
The controlled-phase gate is defined via the unitary operator
\[\text{CPhase}_{ij} (\phi) = \exp \left ( i \phi n_i n_j \right ).\]Note
This is a non-linear gate, therefore it couldn’t be used with
GaussianSimulator.Note
This is analoguous to the
CrossKerrgate in the photonic setting.- Parameters:
phi (float) – The controlled-phase angle.
- class IsingXX(phi: float)¶
Bases:
GateIsing XX coupling gate.
The Ising XX gate is defined via the unitary operator
\[\text{XX}_{ij} (\phi) = \exp \left ( i \phi X \otimes X \right ) = \cos \phi I + i \sin \phi (X \otimes X).\]Considering a two-mode system with Majorana operators \(m_1, m_2, m_3, m_4\), \(X \otimes X\) can also be written as
\[X \otimes X = -i m_2 m_3.\]- Parameters:
phi (float) – The rotation angle.
Fermionic Gaussian simulations¶
This is a package for Fermionic Linear Optics (FLO) or Fermionic Gaussian states.
- class GaussianSimulator(d: int | None = None, config: Config | None = None, connector: BaseConnector | None = None)¶
Bases:
BuiltinSimulatorFermionic Gaussian simulator.
Example usage:
passive_hamiltonian = np.array([[1, 2j, 3j], [-2j, 5, 6], [-3j, 6, 7]]) U = expm(1j * passive_hamiltonian) state_vector = [1, 0, 1] with pq.Program() as program: pq.Q() | pq.StateVector(state_vector) pq.Q() | pq.Interferometer(U) simulator = pq.fermionic.GaussianSimulator(d=3, connector=connector) state = simulator.execute(program).state
- Supported preparations:
- Supported gates:
Interferometer,Beamsplitter,Phaseshifter,GaussianHamiltonian.
- create_initial_state(d=None)¶
Creates an initial state with no instructions executed.
Note
This is not necessarily a vacuum state.
- Returns:
The initial state of the simulation.
- Return type:
- execute(program: Program, shots: int | None = 1, initial_state: State | None = None) Result¶
Executes the specified program.
- Parameters:
program (Program) – The program to execute.
initial_state (State, optional) – A state to execute the instructions on. Defaults to the state created by
create_initial_state().shots (int, optional) – The number of times the program should execute. If it is None, the simulator will execute the program once, returning the exact probability distribution instead of samples. Defaults to 1.
- Raises:
InvalidParameter – When shots is not a positive integer or not None.
- Returns:
The result of the simulation containing the resulting state and samples if any measurement is specified in program.
- Return type:
- execute_instructions(instructions: List[Instruction], initial_state: State | None = None, shots: int | None = 1) Result¶
Executes the specified instruction list.
- Parameters:
instructions (List[Instruction]) – The instructions to execute.
initial_state (State, optional) – A state to execute the instructions on. Defaults to the state created by
create_initial_state().shots (int, optional) – The number of times the program should be execute. If it is None, the simulator will execute the program once, returning the exact probability distribution instead of samples. Defaults to 1.
- Raises:
InvalidParameter – When shots is not a positive integer or not None.
InvalidSimulation – When the number of modes cannot be inferred and d was not provided during simulator initialization.
- Returns:
The result of the simulation containing the resulting state and samples if any measurement is specified in instructions.
- Return type:
- validate(program: Program) None¶
Validates the specified program.
- Raises:
InvalidInstruction – When invalid instructions are defined in the program.
InvalidSimulation – When the instructions are valid, but the simulator couldn’t execute the specified program.
- Parameters:
program (Program) – The program to validate.
- class GaussianState(d: int, connector: BaseConnector, config: Config | None = None)¶
Bases:
StateA fermionic Gaussian state.
- copy() State¶
Returns an exact copy of this state.
- Returns:
An exact copy of this state.
- Return type:
- property correlation_matrix¶
The correlation matrix in the Dirac basis.
The correlation matrix is defined by
\[\begin{split}\Gamma := \begin{bmatrix} \Gamma^{f^\dagger f} & \Gamma^{f^\dagger f^\dagger} \\ \Gamma^{f f} & \Gamma^{f f^\dagger} \end{bmatrix},\end{split}\]where \(\Gamma_{i,j}^{f^\dagger f} = \langle f_i^\dagger f_j \rangle\) and \(\Gamma_{i,j}^{f f} = \langle f_i f_j \rangle\).
By CAR, we know that \(\Gamma_{i,j}^{f^\dagger f} = - \overline{\Gamma_{i,j}^{f f^\dagger }}\) and \(\Gamma_{i,j}^{f f} = I - \overline{\Gamma_{i,j}^{f^\dagger f^\dagger }}\)
The correlation matrix is a self-adjoint matrix.
- property covariance_matrix: np.ndarray¶
The covariance matrix.
A fermionic Gaussian state can be fully characterized by its covariance matrix defined by
\[\Sigma_{ij} := -i \operatorname{Tr} (\rho [\mathbf{m}_i, \mathbf{m}_j]) / 2,\]where \(\mathbf{m}\) is defined by Eq. (1). The covariance matrix is a real-valued, skew-symmetric matrix.
- Returns:
The covariance matrix.
- Return type:
np.ndarray
- property d¶
The number of modes.
- property density_matrix: np.ndarray¶
Density matrix in the lexicographic ordering.
When applicable, the density matrix is just
\[\rho = e^{\hat{H}} / \operatorname{Tr} e^{\hat{H}},\]where \(\hat{H}\) is the parent hamiltonian (see
get_parent_hamiltonian()) given by\[\begin{split}\hat{H} = \mathbf{f}^\dagger H \mathbf{f}, \\\\ H = \begin{bmatrix} A & -\overline{B} \\ B & -\overline{A} \end{bmatrix}.\end{split}\]where \(A^\dagger = A\) and \(B^T = - B\).
Note
The density matrix is returned in matrix form here. This will probably change in the future to tensor form.
- property fock_probabilities: np.ndarray¶
Returns the particle detection probabilities.
Note
The ordering of the Fock basis is increasing with particle numbers, and in each particle number conserving subspace, lexicographic ordering is used.
- Returns:
The particle detection probabilities.
- Return type:
- get_majorana_monomial_expectation_value(indices)¶
Calculates Majorana monomial expectation values using Wick’s theorem.
The monomial indices are understood in the xxpp-ordering.
- Parameters:
indices – Indices of the Majorana operators in any order with possible with possible multiplicities.
- get_parent_hamiltonian()¶
Calculates the parent Hamiltonian.
When the correlation matrix is not singular, the density matrix is
\[\rho = e^{\hat{H}} / \operatorname{Tr} e^{\hat{H}},\]where \(\hat{H}\) is the parent hamiltonian (see
get_parent_hamiltonian()) given by\[ \begin{align}\begin{aligned}\begin{split}\hat{H} = \mathbf{f}^\dagger H \mathbf{f}, \\\\\end{split}\\\begin{split}H = \begin{bmatrix} A & -\overline{B} \\ B & -\overline{A} \end{bmatrix}.\end{split}\end{aligned}\end{align} \]where \(A^\dagger = A\) and \(B^T = - B\).
- Raises:
PiquassoException – When the correlation matrix is singular.
- get_parity_operator_expectation_value()¶
Calculates the expectation value of the parity operator.
The parity operator is defined as
\[P = i^d m_1 \dots m_{2d} = i^d x_1 \dots x_d p_1 \dots p_d.\]
- get_particle_detection_probability(occupation_number: np.ndarray) float¶
Returns the particle number detection probability using the occupation number specified as a parameter.
- property maj_correlation_matrix¶
The correlation matrix in the Majorana operator basis.
- mean_particle_numbers(modes)¶
Returns the mean particle numbers on the specified modes.
- overlap(other)¶
Calculates the overlap between two fermionic Gaussian states.
The overlap is the Hilbert-Schmidt inner product of the density matrices.
- reduced(modes)¶
Reduces the state to a subsystem on the specified modes.
- validate()¶
Validates the state.
Fermionic Fock space-based simulators¶
This is a package for Fock space-based simulations of fermionic states.
- class PureFockState(d: int, connector: BaseConnector, config: Config | None = None)¶
Bases:
StateA fermionic pure Fock state.
- copy() State¶
Returns an exact copy of this state.
- Returns:
An exact copy of this state.
- Return type:
- property covariance_matrix: np.ndarray¶
The covariance matrix.
The covariance matrix is defined by
\[\Sigma_{ij} := -i \operatorname{Tr} (\rho [\mathbf{m}_i, \mathbf{m}_j]) / 2,\]where \(\mathbf{m}\) is defined by Eq. (1). The covariance matrix is a real-valued, skew-symmetric matrix.
Note
The covariance matrix does not fully characterize this state in general, only if it is a Gaussian state. For manipulating Gaussian states, visit
GaussianState.- Returns:
The covariance matrix.
- Return type:
np.ndarray
- property d¶
The number of modes.
- property density_matrix: np.ndarray¶
The density matrix of the state.
Warning
The primary ordering of the Fock basis is by number of particles, and the secondary is anti-lexicographic.
Example for 3 modes:
\[\ket{000}, \ket{100}, \ket{010}, \ket{001}, \ket{200}, \ket{110}, \ket{101}, \ket{020}, \ket{011}, \ket{002}, \dots\]This is in contrast with
density_matrix(), where the primary ordering is lexicographic.- Returns:
The density matrix.
- Return type:
np.ndarray
- property fock_probabilities: np.ndarray¶
Returns the particle detection probabilities.
Note
The ordering of the Fock basis is increasing with particle numbers, and in each particle number conserving subspace, lexicographic ordering is used.
- Returns:
The particle detection probabilities.
- Return type:
- get_particle_detection_probability(occupation_number)¶
Returns the particle number detection probability using the occupation number specified as a parameter.
- property state_vector¶
The state vector of the quantum state.
Warning
The primary ordering of the Fock basis is by number of particles, and the secondary is anti-lexicographic.
Example for 3 modes:
\[\ket{000}, \ket{100}, \ket{010}, \ket{001}, \ket{200}, \ket{110}, \ket{101}, \ket{020}, \ket{011}, \ket{002}, \dots\]This is in contrast with
density_matrix(), where the primary ordering is lexicographic.
- validate()¶
Validates the state.
- class PureFockSimulator(d: int | None = None, config: Config | None = None, connector: BaseConnector | None = None)¶
Bases:
BuiltinSimulatorFermionic pure Fock state simulator.
Example usage:
U = scipy.stats.unitary_group.rvs(4) with pq.Program() as program: pq.Q() | pq.StateVector([0, 0, 1, 1]) / np.sqrt(2) pq.Q() | pq.StateVector([1, 1, 0, 0]) / np.sqrt(2) pq.Q() | pq.Interferometer(U) simulator = pq.fermionic.PureFockSimulator( d=4, config=pq.Config(cutoff=4 + 1) ) state = simulator.execute(program).state
- Supported preparations:
- Supported gates:
- create_initial_state(d=None)¶
Creates an initial state with no instructions executed.
Note
This is not necessarily a vacuum state.
- Returns:
The initial state of the simulation.
- Return type:
- execute(program: Program, shots: int | None = 1, initial_state: State | None = None) Result¶
Executes the specified program.
- Parameters:
program (Program) – The program to execute.
initial_state (State, optional) – A state to execute the instructions on. Defaults to the state created by
create_initial_state().shots (int, optional) – The number of times the program should execute. If it is None, the simulator will execute the program once, returning the exact probability distribution instead of samples. Defaults to 1.
- Raises:
InvalidParameter – When shots is not a positive integer or not None.
- Returns:
The result of the simulation containing the resulting state and samples if any measurement is specified in program.
- Return type:
- execute_instructions(instructions: List[Instruction], initial_state: State | None = None, shots: int | None = 1) Result¶
Executes the specified instruction list.
- Parameters:
instructions (List[Instruction]) – The instructions to execute.
initial_state (State, optional) – A state to execute the instructions on. Defaults to the state created by
create_initial_state().shots (int, optional) – The number of times the program should be execute. If it is None, the simulator will execute the program once, returning the exact probability distribution instead of samples. Defaults to 1.
- Raises:
InvalidParameter – When shots is not a positive integer or not None.
InvalidSimulation – When the number of modes cannot be inferred and d was not provided during simulator initialization.
- Returns:
The result of the simulation containing the resulting state and samples if any measurement is specified in instructions.
- Return type:
- validate(program: Program) None¶
Validates the specified program.
- Raises:
InvalidInstruction – When invalid instructions are defined in the program.
InvalidSimulation – When the instructions are valid, but the simulator couldn’t execute the specified program.
- Parameters:
program (Program) – The program to validate.