ffsim.qiskit¶
Code that uses Qiskit, e.g. for constructing quantum circuits.
- class ffsim.qiskit.DiagCoulombEvolutionJW(norb, mat, time, *, z_representation=False, label=None)[source]¶
Bases:
GateDiagonal Coulomb evolution under the Jordan-Wigner transformation.
The diagonal Coulomb evolution gate has the unitary
\[\exp\left(-i t \sum_{\sigma, \tau, i, j} Z^{(\sigma \tau)}_{ij} n_{\sigma, i} n_{\tau, j} / 2\right)\]where \(n_{\sigma, i}\) denotes the number operator on orbital \(i\) with spin \(\sigma\), \(Z^{(\sigma \tau)}\) is a real-valued matrix.
This gate assumes that qubits are ordered such that the first norb qubits correspond to the alpha orbitals and the last norb qubits correspond to the beta orbitals.
- __init__(norb, mat, time, *, z_representation=False, label=None)[source]¶
Create new diagonal Coulomb evolution gate.
- Parameters:
norb (
int) – The number of spatial orbitals.mat (
ndarray|tuple[ndarray|None,ndarray|None,ndarray|None]) – The diagonal Coulomb matrix \(Z\). You can pass either a single Numpy array specifying the coefficients to use for all spin interactions, or you can pass a tuple of three Numpy arrays specifying independent coefficients for alpha-alpha, alpha-beta, and beta-beta interactions (in that order). If passing a tuple, you can set a tuple element toNoneto indicate the absence of interactions of that type. The alpha-alpha and beta-beta matrices are assumed to be symmetric, and only their upper triangular entries are used.time (
float) – The evolution time.z_representation (
bool) – Whether the input matrices are in the “Z” representation.label (
str|None) – The label of the gate.
- class ffsim.qiskit.DiagCoulombEvolutionSpinlessJW(norb, mat, time, *, label=None)[source]¶
Bases:
GateSpinless diagonal Coulomb evolution under the Jordan-Wigner transformation.
The spinless diagonal Coulomb evolution gate has the unitary
\[\exp\left(-i t \sum_{i, j} Z^{ij} n_i n_j / 2\right)\]where \(n_i\) denotes the number operator on orbital \(i\) and \(Z\) is a real symmetric matrix.
- __init__(norb, mat, time, *, label=None)[source]¶
Create new diagonal Coulomb evolution gate.
- Parameters:
norb (
int) – The number of spatial orbitals.mat (
ndarray) – The diagonal Coulomb matrix \(Z\). It is assumed to be symmetric, and only its upper triangular entries are used.time (
float) – The evolution time.label (
str|None) – The label of the gate.
- class ffsim.qiskit.DropNegligible(atol=1e-08)[source]¶
Bases:
TransformationPassDrop gates with negligible effects.
- class ffsim.qiskit.FfsimSampler(*, default_shots=1024, norb=None, nelec=None, global_depolarizing=0.0, seed=None)[source]¶
Bases:
BaseSamplerV2Implementation of the Qiskit Sampler primitive backed by ffsim.
- __init__(*, default_shots=1024, norb=None, nelec=None, global_depolarizing=0.0, seed=None)[source]¶
Initialize the ffsim Sampler.
FfsimSampler is an implementation of the Qiskit Sampler Primitive specialized for fermionic quantum circuits. It does not support arbitrary circuits, but only those with a certain structure. Generally speaking, there are two ways to construct a circuit that FfsimSampler can simulate:
1. Use gates from the
ffsim.qiskitmodule. The circuit should begin with a state preparation gate (one whose name begins with the prefixPrepare, such asPrepareHartreeFockJW) that acts on all of the qubits. Next, a number of unitary gates from theffsim.qiskitmodule are applied. Finally, measurement gates must only occur at the end of the circuit.2. Use Qiskit gates. The circuit should begin with some
Xgates. Next, a number of unitary gates are applied. The following unitary gates are supported: [CPhaseGate,CZGate,GlobalPhaseGate,iSwapGate,PhaseGate,RZGate,RZZGate,SGate,SdgGate,SwapGate,TGate,TdgGate,XXPlusYYGate,ZGate]. Finally, measurement gates must only occur at the end of the circuit.When simulating spinful circuits constructed from Qiskit gates, you should pass the norb and nelec arguments to the FfsimSampler initialization. Otherwise, a spinless simulation will be performed, which is less efficient.
Currently, spinless circuits are limited to 64 qubits, and spinful circuits are limited to 128 qubits.
- Parameters:
default_shots (
int) – The default shots to use if not specified during run.norb (
int|None) – The number of spatial orbitals.nelec (
int|tuple[int,int] |None) – Either a single integer representing the number of fermions for a spinless system, or a pair of integers storing the numbers of spin alpha and spin beta fermions.global_depolarizing (
float) – Depolarizing probability for a noisy simulation. Specifies the probability of sampling from the uniform distribution instead of the state vector.seed (
Generator|int|None) – A seed to initialize the pseudorandom number generator. Should be a valid input tonp.random.default_rng.
- run(pubs, *, shots=None)[source]¶
Run and collect samples from each pub.
- Parameters:
pubs (
Iterable[Union[QuantumCircuit,Tuple[QuantumCircuit],Tuple[QuantumCircuit,Mapping[Union[Parameter,str,Tuple[Union[Parameter,str],...]],Union[Buffer,_SupportsArray[dtype[Any]],_NestedSequence[_SupportsArray[dtype[Any]]],complex,bytes,str,_NestedSequence[complex|bytes|str]]]],Tuple[QuantumCircuit,Mapping[Union[Parameter,str,Tuple[Union[Parameter,str],...]],Union[Buffer,_SupportsArray[dtype[Any]],_NestedSequence[_SupportsArray[dtype[Any]]],complex,bytes,str,_NestedSequence[complex|bytes|str]]],Optional[Integral]]]]) – An iterable of pub-like objects. For example, a list of circuits or tuples(circuit, parameter_values).shots (
int|None) – The total number of shots to sample for each sampler pub that does not specify its own shots. IfNone, the primitive’s default shots value will be used, which can vary by implementation.
- Return type:
PrimitiveJob[PrimitiveResult[SamplerPubResult]]- Returns:
The job object of Sampler’s result.
- class ffsim.qiskit.GivensAnsatzOpJW(givens_ansatz_op, *, label=None)[source]¶
Bases:
GateGivens rotation ansatz operator under the Jordan-Wigner transformation.
See
ffsim.GivensAnsatzOpfor a description of this gate’s unitary.- __init__(givens_ansatz_op, *, label=None)[source]¶
Create a new Givens ansatz operator gate.
- Parameters:
givens_ansatz_op (
GivensAnsatzOp) – The Givens rotation ansatz operator.label (
str|None) – The label of the gate.
- class ffsim.qiskit.GivensAnsatzOpSpinlessJW(givens_ansatz_op, *, label=None)[source]¶
Bases:
GateSpinless Givens rotation ansatz operator under the Jordan-Wigner transformation.
Like
GivensAnsatzOpJWbut only acts on a single spin species.- __init__(givens_ansatz_op, *, label=None)[source]¶
Create a new Givens ansatz operator gate.
- Parameters:
givens_ansatz_op (
GivensAnsatzOp) – The Givens rotation ansatz operator.label (
str|None) – The label of the gate.
- class ffsim.qiskit.MergeOrbitalRotations(*args, **kwargs)[source]¶
Bases:
TransformationPassMerge consecutive orbital rotation gates.
- class ffsim.qiskit.NumNumAnsatzOpSpinBalancedJW(num_num_ansatz_op, *, label=None)[source]¶
Bases:
GateSpin-balanced number-number ansatz under the Jordan-Wigner transformation.
See
NumNumAnsatzOpSpinBalancedfor a description of this gate’s unitary.This gate assumes that qubits are ordered such that the first norb qubits correspond to the alpha orbitals and the last norb qubits correspond to the beta orbitals.
- __init__(num_num_ansatz_op, *, label=None)[source]¶
Create a new number-number ansatz operator gate.
- Parameters:
num_num_ansatz_op (
NumNumAnsatzOpSpinBalanced) – The number-number ansatz operator.label (
str|None) – The label of the gate.
- class ffsim.qiskit.NumOpSumEvolutionJW(norb, coeffs, time, *, label=None)[source]¶
Bases:
GateNumber operator sum evolution under the Jordan-Wigner transformation.
The number operator sum evolution gate has the unitary
\[\exp\left(-i t \sum_{\sigma, i} \lambda^{(\sigma)}_i n_{\sigma, i}\right)\]where \(n_{\sigma, i}\) denotes the number operator on orbital \(i\) with spin \(\sigma\) and the \(\lambda_i\) are real numbers.
This gate assumes that qubits are ordered such that the first norb qubits correspond to the alpha orbitals and the last norb qubits correspond to the beta orbitals.
- __init__(norb, coeffs, time, *, label=None)[source]¶
Create new number operator sum evolution gate.
- Parameters:
norb (
int) – The number of spatial orbitals.coeffs (
ndarray|tuple[ndarray|None,ndarray|None]) – The coefficients of the linear combination. You can pass either a single Numpy array specifying the coefficients to apply to both spin sectors, or you can pass a pair of Numpy arrays specifying independent coefficients for spin alpha and spin beta. If passing a pair, you can useNonefor one of the values in the pair to indicate that no operation should be applied to that spin sector.time (
float) – The evolution time.label (
str|None) – The label of the gate.
- class ffsim.qiskit.NumOpSumEvolutionSpinlessJW(norb, coeffs, time, *, label=None)[source]¶
Bases:
GateSpinless number operator sum evolution under the Jordan-Wigner transformation.
The spinless number operator sum evolution gate has the unitary
\[\exp\left(-i t \sum_{i} \lambda_i n_{i}\right)\]where \(n_i\) denotes the number operator on orbital \(i\) and the \(\lambda_i\) are real numbers.
- class ffsim.qiskit.OrbitalRotationJW(norb, orbital_rotation, *, label=None, validate=True, rtol=1e-05, atol=1e-08)[source]¶
Bases:
GateOrbital rotation under the Jordan-Wigner transformation.
An orbital rotation maps creation operators as
\[a^\dagger_{\sigma, i} \mapsto \sum_{j} U_{ji} a^\dagger_{\sigma, j}\]where \(U\) is a unitary matrix. This is equivalent to applying the transformation given by
\[\prod_{\sigma} \exp\left(\sum_{ij} \log(U)_{ij} a^\dagger_{\sigma, i} a_{\sigma, j}\right)\]This gate assumes that qubits are ordered such that the first norb qubits correspond to the alpha orbitals and the last norb qubits correspond to the beta orbitals.
- __init__(norb, orbital_rotation, *, label=None, validate=True, rtol=1e-05, atol=1e-08)[source]¶
Create new orbital rotation gate.
- Parameters:
norb (
int) – The number of spatial orbitals.orbital_rotation (
ndarray|tuple[ndarray|None,ndarray|None]) – The orbital rotation. You can pass either a single Numpy array specifying the orbital rotation to apply to both spin sectors, or you can pass a pair of Numpy arrays specifying independent orbital rotations for spin alpha and spin beta. If passing a pair, you can useNonefor one of the values in the pair to indicate that no operation should be applied to that spin sector.label (
str|None) – The label of the gate.validate (
bool) – Whether to check that the input orbital rotation(s) is unitary and raise an error if it isn’t.rtol (
float) – Relative numerical tolerance for input validation.atol (
float) – Absolute numerical tolerance for input validation.
- Raises:
ValueError – The input matrix is not unitary.
- class ffsim.qiskit.OrbitalRotationSpinlessJW(norb, orbital_rotation, *, label=None, validate=True, rtol=1e-05, atol=1e-08)[source]¶
Bases:
GateOrbital rotation under the Jordan-Wigner transformation, spinless version.
Like
OrbitalRotationJWbut only acts on a single spin species.- __init__(norb, orbital_rotation, *, label=None, validate=True, rtol=1e-05, atol=1e-08)[source]¶
Create new orbital rotation gate.
- Parameters:
norb (
int) – The number of spatial orbitals.orbital_rotation (
ndarray) – The orbital rotation.label (
str|None) – The label of the gate.validate (
bool) – Whether to check that the input orbital rotation(s) is unitary and raise an error if it isn’t.rtol (
float) – Relative numerical tolerance for input validation.atol (
float) – Absolute numerical tolerance for input validation.
- Raises:
ValueError – The input matrix is not unitary.
- ffsim.qiskit.PRE_INIT = <qiskit.transpiler.passmanager.PassManager object>¶
Pass manager recommended for the Qiskit transpiler
pre_initstage.See
pre_init_passes()for a description of the transpiler passes included in this pass manager.
- class ffsim.qiskit.PrepareHartreeFockJW(norb, nelec, label=None)[source]¶
Bases:
GateGate that prepares the Hartree-Fock state (under JWT) from the all zeros state.
This gate assumes the Jordan-Wigner transformation (JWT).
This gate is meant to be applied to the all zeros state. It decomposes simply as a sequence of X gates that prepares the Hartree-Fock electronic configuration.
This gate assumes that qubits are ordered such that the first norb qubits correspond to the alpha orbitals and the last norb qubits correspond to the beta orbitals.
- class ffsim.qiskit.PrepareHartreeFockSpinlessJW(norb, nelec, label=None)[source]¶
Bases:
GatePrepare the Hartree-Fock state (under JWT) from the zero state, spinless.
Like
PrepareHartreeFockJWbut only acts on a single spin species.
- class ffsim.qiskit.PrepareSlaterDeterminantJW(norb, occupied_orbitals, orbital_rotation=None, *, label=None, validate=True, rtol=1e-05, atol=1e-08)[source]¶
Bases:
GateGate that prepares a Slater determinant (under JWT) from the all zeros state.
This gate assumes the Jordan-Wigner transformation (JWT).
A Slater determinant is a state of the form
\[\mathcal{U} \lvert x \rangle,\]where \(\mathcal{U}\) is an orbital rotation and \(\lvert x \rangle\) is an electronic configuration (computational basis state). The reason this gate exists (when
OrbitalRotationJWalready exists) is that the preparation of a Slater determinant has a more optimized circuit than a generic orbital rotation.This gate is meant to be applied to the all zeros state. Its behavior when applied to any other state is not guaranteed. The global phase of the prepared state may be arbitrary.
This gate assumes that qubits are ordered such that the first norb qubits correspond to the alpha orbitals and the last norb qubits correspond to the beta orbitals.
Reference: arXiv:1711.05395
- __init__(norb, occupied_orbitals, orbital_rotation=None, *, label=None, validate=True, rtol=1e-05, atol=1e-08)[source]¶
Create new Slater determinant preparation gate.
- Parameters:
norb (
int) – The number of spatial orbitals.occupied_orbitals (
tuple[Sequence[int],Sequence[int]]) – The occupied orbitals in the electonic configuration. This is a pair of lists of integers, where the first list specifies the spin alpha orbitals and the second list specifies the spin beta orbitals.orbital_rotation (
ndarray|tuple[ndarray|None,ndarray|None] |None) – The optional orbital rotation. You can pass either a single Numpy array specifying the orbital rotation to apply to both spin sectors, or you can pass a pair of Numpy arrays specifying independent orbital rotations for spin alpha and spin beta. If passing a pair, you can useNonefor one of the values in the pair to indicate that no operation should be applied to that spin sector.label (
str|None) – The label of the gate.validate (
bool) – Whether to check that the input orbital rotation(s) is unitary and raise an error if it isn’t.rtol (
float) – Relative numerical tolerance for input validation.atol (
float) – Absolute numerical tolerance for input validation.
- Raises:
ValueError – The input orbital rotation matrix is not unitary.
- class ffsim.qiskit.PrepareSlaterDeterminantSpinlessJW(norb, occupied_orbitals, orbital_rotation=None, *, label=None, validate=True, rtol=1e-05, atol=1e-08)[source]¶
Bases:
GatePrepare a Slater determinant (under JWT) from the zero state, spinless version.
Like
PrepareSlaterDeterminantJWbut only acts on a single spin species.- __init__(norb, occupied_orbitals, orbital_rotation=None, *, label=None, validate=True, rtol=1e-05, atol=1e-08)[source]¶
Create new Slater determinant preparation gate.
- Parameters:
norb (
int) – The number of spatial orbitals.occupied_orbitals (
Sequence[int]) – The occupied orbitals in the electonic configuration.orbital_rotation (
ndarray|None) – The optional orbital rotation.label (
str|None) – The label of the gate.validate (
bool) – Whether to check that the input orbital rotation(s) is unitary and raise an error if it isn’t.rtol (
float) – Relative numerical tolerance for input validation.atol (
float) – Absolute numerical tolerance for input validation.
- Raises:
ValueError – The input orbital rotation matrix is not unitary.
- class ffsim.qiskit.SimulateTrotterDiagCoulombSplitOpJW(hamiltonian, time, *, n_steps=1, order=0, label=None)[source]¶
Bases:
GateSplit operator Trotter evolution of diagonal Coulomb Hamiltonian, Jordan-Wigner.
This gate assumes that qubits are ordered such that the first norb qubits correspond to the alpha orbitals and the last norb qubits correspond to the beta orbitals.
- __init__(hamiltonian, time, *, n_steps=1, order=0, label=None)[source]¶
Create diagonal Coulomb split-operator Trotter evolution gate.
- Parameters:
norb – The number of spatial orbitals.
hamiltonian (
DiagonalCoulombHamiltonian) – The Hamiltonian.time (
float) – The evolution time.n_steps (
int) – The number of Trotter steps.order (
int) – The order of the Trotter decomposition.label (
str|None) – The label of the gate.
- class ffsim.qiskit.SimulateTrotterDoubleFactorizedJW(hamiltonian, time, *, n_steps=1, order=0, label=None)[source]¶
Bases:
GateTrotter time evolution of double-factorized Hamiltonian, Jordan-Wigner.
This gate assumes that qubits are ordered such that the first norb qubits correspond to the alpha orbitals and the last norb qubits correspond to the beta orbitals.
- __init__(hamiltonian, time, *, n_steps=1, order=0, label=None)[source]¶
Create double-factorized Trotter evolution gate.
- Parameters:
norb – The number of spatial orbitals.
hamiltonian (
DoubleFactorizedHamiltonian) – The Hamiltonian.time (
float) – The evolution time.n_steps (
int) – The number of Trotter steps.order (
int) – The order of the Trotter decomposition.label (
str|None) – The label of the gate.
- class ffsim.qiskit.UCJOpSpinBalancedJW(ucj_op, *, label=None)[source]¶
Bases:
GateSpin-balanced UCJ operator under the Jordan-Wigner transformation.
See
ffsim.UCJOpSpinBalancedfor a description of this gate’s unitary.This gate assumes that qubits are ordered such that the first norb qubits correspond to the alpha orbitals and the last norb qubits correspond to the beta orbitals.
- __init__(ucj_op, *, label=None)[source]¶
Create a new spin-balanced unitary cluster Jastrow (UCJ) gate.
- Parameters:
ucj_op (
UCJOpSpinBalanced) – The UCJ operator.label (
str|None) – The label of the gate.
- class ffsim.qiskit.UCJOpSpinUnbalancedJW(ucj_op, *, label=None)[source]¶
Bases:
GateSpin-unbalanced UCJ operator under the Jordan-Wigner transformation.
See
ffsim.UCJOpSpinUnbalancedfor a description of this gate’s unitary.This gate assumes that qubits are ordered such that the first norb qubits correspond to the alpha orbitals and the last norb qubits correspond to the beta orbitals.
- __init__(ucj_op, *, label=None)[source]¶
Create a new spin-unbalanced unitary cluster Jastrow (UCJ) gate.
- Parameters:
ucj_op (
UCJOpSpinUnbalanced) – The UCJ operator.label (
str|None) – The label of the gate.
- class ffsim.qiskit.UCJOpSpinlessJW(ucj_op, *, label=None)[source]¶
Bases:
GateSpinless UCJ operator under the Jordan-Wigner transformation.
See
ffsim.UCJOpSpinlessfor a description of this gate’s unitary.- __init__(ucj_op, *, label=None)[source]¶
Create a new spinless unitary cluster Jastrow (UCJ) gate.
- Parameters:
ucj_op (
UCJOpSpinless) – The UCJ operator.label (
str|None) – The label of the gate.
- ffsim.qiskit.ffsim_vec_to_qiskit_vec(vec, norb, nelec)[source]¶
Convert an ffsim state vector to a Qiskit state vector.
- Parameters:
vec (
ndarray) – A state vector in ffsim/PySCF format. It should be a one-dimensional vector of lengthcomb(norb, n_alpha) * comb(norb, n_beta)in the spinful case, andcomb(norb, nelec)in the spinless case.norb (
int) – The number of spatial orbitals.nelec (
int|tuple[int,int]) – Either a single integer representing the number of fermions for a spinless system, or a pair of integers storing the numbers of spin alpha and spin beta fermions.
- Return type:
ndarray
- ffsim.qiskit.final_state_vector(circuit, norb=None, nelec=None)[source]¶
Return the final state vector of a fermionic quantum circuit.
- Parameters:
norb (
int|None) – The number of spatial orbitals.nelec (
int|tuple[int,int] |None) – Either a single integer representing the number of fermions for a spinless system, or a pair of integers storing the numbers of spin alpha and spin beta fermions.circuit (
QuantumCircuit) – The circuit composed of fermionic gates.
- Return type:
- Returns:
The final state vector that results from applying the circuit to the vacuum state.
- ffsim.qiskit.jordan_wigner(op, norb=None)[source]¶
Jordan-Wigner transformation.
Transform a fermion operator to a qubit operator using the Jordan-Wigner transformation. The Jordan-Wigner transformation maps fermionic annihilation operators to qubits as follows:
\[a_p \mapsto \frac12 (X_p + iY_p)Z_1 \cdots Z_{p-1}\]In the transformed operator, the first
norbqubits represent spin-up (alpha) orbitals, and the latternorbqubits represent spin-down (beta) orbitals. As a result of this convention, the qubit index that an orbital is mapped to depends on the total number of spatial orbitals. By default, the total number of spatial orbitals is automatically determined by the largest-index orbital present in the operator, but you can manually specify the number using the norb argument.- Parameters:
op (
FermionOperator) – The fermion operator to transform.norb (
int|None) – The total number of spatial orbitals. If not specified, it is determined by the largest-index orbital present in the operator.
- Return type:
SparsePauliOp- Returns:
The qubit operator as a Qiskit SparsePauliOp.
- Raises:
ValueError – Number of spatial orbitals was negative.
ValueError – Number of spatial orbitals was fewer than the number detected in the operator.
- ffsim.qiskit.pre_init_passes()[source]¶
Yield transpiler passes recommended for the Qiskit transpiler
pre_initstage.The following transpiler passes are yielded: :rtype:
Iterator[BasePass]Decompose pass that decomposes
PrepareHartreeFockJWandUCJOperatorJWgates to expose the underlyingPrepareSlaterDeterminantJWandOrbitalRotationJWgates.MergeOrbitalRotationspass to merge the Slater determinant preparation and orbital rotation gates.
- ffsim.qiskit.qiskit_vec_to_ffsim_vec(vec, norb, nelec)[source]¶
Convert a Qiskit state vector to an ffsim state vector.
- Parameters:
vec (
ndarray) – A state vector in Qiskit format. It should be a one-dimensional vector of length2 ** (2 * norb)in the spinful case, and2 ** norbin the spinless case.norb (
int) – The number of spatial orbitals.nelec (
int|tuple[int,int]) – Either a single integer representing the number of fermions for a spinless system, or a pair of integers storing the numbers of spin alpha and spin beta fermions.
- Return type:
ndarray