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, 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()¶
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 = 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. Defaults to 1.
- Raises:
InvalidParameter – When shots is not a positive integer.
- 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 = 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. Defaults to 1.
- Raises:
InvalidParameter – When shots is not a positive integer.
- 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.
- property d¶
The number of modes.
- property covariance_matrix¶
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.\]The covariance matrix is a real-valued, skew-symmetric matrix.
- 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 maj_correlation_matrix¶
The correlation matrix in the Majorana operator basis.
- validate()¶
Validates the state.
- 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: np.ndarray) float¶
Returns the particle number detection probability using the occupation number specified as a parameter.
- mean_particle_numbers(modes)¶
Returns the mean particle numbers on the specified modes.
- 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.
- 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.
- reduced(modes)¶
Reduces the state to a subsystem on the specified modes.
- 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_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.\]
- copy() State¶
Returns an exact copy of this state.
- Returns:
An exact copy of this state.
- Return type:
- overlap(other)¶
Calculates the overlap between two fermionic Gaussian states.
The overlap is the Hilbert-Schmidt inner product of the density matrices.
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.
- 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.
- property d¶
The number of modes.
- 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.
- validate()¶
Validates the state.
- property density_matrix¶
- class PureFockSimulator(d: int, 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()¶
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 = 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. Defaults to 1.
- Raises:
InvalidParameter – When shots is not a positive integer.
- 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 = 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. Defaults to 1.
- Raises:
InvalidParameter – When shots is not a positive integer.
- 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.