Fermionic Exponentiated Ansatz¶
The FermionSpaceStateExp
class is essentially a thin wrapper over
TrotterAnsatz
(see previous section), and serves as the basis
for all the Unitary Coupled Cluster ansatzes. It accepts a FermionOperatorList
object as an input,
maps it to a corresponding QubitOperatorList
object, and provides the latter as an input
to TrotterAnsatz
.
If one has an idea for a chemically inspired unitary ansatz, which can be written in terms of
fermionic operators, and would like to build and handle the corresponding circuit in InQuanto, this
can be achieved by first instantiating a list of fermionic operators, and then providing it to a
FermionSpaceStateExp
constructor.
As an illustrative example, let us generate a reduced UCCD ansatz from scratch for a system of two electrons in six spin-orbitals. We first need to write the double excitations of interest:
from inquanto.spaces import FermionSpace
from inquanto.ansatzes import FermionSpaceAnsatzUCCD
from inquanto.operators import (
FermionOperatorString,
FermionOperator,
FermionOperatorList
)
from sympy import Symbol
# Generate example state and space
space = FermionSpace(n_spin_orb=6)
state = space.generate_occupation_state(n_fermion=2)
# Construct a list of two double excitation operators
d0 = FermionOperatorString.from_string("2^ 0 3^ 1")
d1 = FermionOperatorString.from_string("4^ 0 5^ 1")
term_list = FermionOperatorList(
[
(Symbol("d0"), FermionOperator(d0, 1)),
(Symbol("d1"), FermionOperator(d1, 1))
]
)
print(f"Fermion state: {state}")
print(f"Fermion operator list: \n{term_list}")
Fermion state: (1.0, {0: np.int64(1), 1: np.int64(1), 2: np.int64(0), 3: np.int64(0), 4: np.int64(0), 5: np.int64(0)})
Fermion operator list:
d0 [(1, F2^ F0 F3^ F1 )],
d1 [(1, F4^ F0 F5^ F1 )]
Here, we should think of term_list
as a product of exponents of single
FermionOperator
objects, constructed from a certain string of creation-annihilation
fermionic operators, and pre-multiplied by symbolic terms d0
and d1
.
In order to ensure the ansatz operator is unitary, we make the expressions under the exponents
anti-hermitian by taking the difference of each term with its adjoint. The resulting
FermionOperatorList
is then passed to the FermionSpaceStateExp
constructor, together with the FermionState
object and the fermion-to-qubit mapping class of choice:
from inquanto.ansatzes import FermionSpaceStateExp
from inquanto.mappings import QubitMappingJordanWigner
anti_hermitian_term_list = FermionOperatorList(
[(symbol, operator - operator.dagger()) for operator, symbol in term_list.items()]
)
my_ansatz = FermionSpaceStateExp(
anti_hermitian_term_list,
state,
QubitMappingJordanWigner()
)
The ansatz object thus constructed can generate a circuit and be used with any of the algorithms or computable objects of InQuanto.