OpenFermion – Forest demo


Wayne H Nixalo – 2018/6/26

A codealong of Forest-OpenFermion_demo.ipynb

Generating and simulating circuits with OpenFermion Forest

The QubitOperator datastructure in OpenFermion is the main point of contact between OpenFermion and Forest. Translation of the QubitOperator to PauliTerms and PauliSums is the interface that is constructed in the OpenFermion–Forest module.

Fortunately, when traversing layers of abstraction in OpenFermion, the QubitOperator naturally appears in all types of simulations. Upon translation into the language of pyQuil, connections to the Forest-QVM or an alternative QVM (such as reference-qvm) that understand pyQuil Program objects can be initialized. The following demonstration starts with the interface between the QubitOperator data structure and the PauliTerm and PauliSum data structures of pyQuil, and then demonstrates how to cnostruct and simulate Hamiltonians starting from OpenFermion.


In [1]:
from openfermion.ops import QubitOperator
from forestopenfermion import pyquilpauli_to_qubitop, qubitop_to_pyquilpauli

The interface contains 2 methods that mediate the translation of PauliTerm and PauliSums to QubitOperators and vice-versa.


In [2]:
qubit_op = QubitOperator('X0 Y1 Z2')
pauli_term = qubitop_to_pyquilpauli(qubit_op)
print(pauli_term)

qubit_op_sum = QubitOperator('X1 Y5 Z2', coefficient=8) + QubitOperator('Y4 Z2', coefficient=1.5)
pauli_term_sum = qubitop_to_pyquilpauli(qubit_op_sum)
print(pauli_term_sum)


(1+0j)*X0*Y1*Z2
(8+0j)*X1*Z2*Y5 + (1.5+0j)*Z2*Y4

We can convert back from a PauliSum object to a QubitOperator


In [3]:
reversed_term = pyquilpauli_to_qubitop(pauli_term)
print(reversed_term.isclose(qubit_op))  # should return True
reversed_sum = pyquilpauli_to_qubitop(pauli_term_sum)
print(reversed_sum.isclose(qubit_op_sum))  # shuold return True


True
True

Let's generate the hopping terms for the Hubbard model Hamiltonian on 4-spatial sites.


In [4]:
from openfermion.ops import FermionOperator
from openfermion.transforms import jordan_wigner
from openfermion.utils import hermitian_conjugated

In [5]:
# we'll construct the Hamiltonian terms
hopping_hamiltonian = FermionOperator()

spatial_orbitals = 4
for i in range(spatial_orbitals):
    electron_hop_alpha = FermionOperator(((2*i, 1), (2*((i+1) % spatial_orbitals), 0)))
    electron_hop_beta  = FermionOperator(((2*i+1, 1), ((2*((i+1) % spatial_orbitals) + 1), 0)))                               
    hopping_hamiltonian += electron_hop_alpha + hermitian_conjugated(electron_hop_alpha)
    hopping_hamiltonian += electron_hop_beta  + hermitian_conjugated(electron_hop_beta)

We can turn the hopping hamiltonian into QubitOperator terms on 2 * (spatial_orbital) qubits using the OpenFermion Jorda-Wigner routine. OpenFermion-Forest provides an interface to convert the QubitOperator objects into pyquil objects and generate a Quil program from their exponentiation. The Quil program was generated by taking each PauliTerm and converting to a set of gates according to arXiv:1306.3991. Once the user has data in the pyQuil format, more pyquil tools, such as a Trotterization engine, can be used.


In [6]:
from pyquil.quil import Program
from forestopenfermion import exponentiate

hopping_term_generator = jordan_wigner(hopping_hamiltonian)

pyquil_program = exponentiate(hopping_term_generator)
print(pyquil_program)


H 0
H 2
CNOT 0 1
CNOT 1 2
RZ(1.0) 2
CNOT 1 2
CNOT 0 1
H 0
H 2
H 0
H 6
CNOT 0 1
CNOT 1 2
CNOT 2 3
CNOT 3 4
CNOT 4 5
CNOT 5 6
RZ(1.0) 6
CNOT 5 6
CNOT 4 5
CNOT 3 4
CNOT 2 3
CNOT 1 2
CNOT 0 1
H 0
H 6
H 1
H 3
CNOT 1 2
CNOT 2 3
RZ(1.0) 3
CNOT 2 3
CNOT 1 2
H 1
H 3
H 1
H 7
CNOT 1 2
CNOT 2 3
CNOT 3 4
CNOT 4 5
CNOT 5 6
CNOT 6 7
RZ(1.0) 7
CNOT 6 7
CNOT 5 6
CNOT 4 5
CNOT 3 4
CNOT 2 3
CNOT 1 2
H 1
H 7
H 2
H 4
CNOT 2 3
CNOT 3 4
RZ(1.0) 4
CNOT 3 4
CNOT 2 3
H 2
H 4
H 3
H 5
CNOT 3 4
CNOT 4 5
RZ(1.0) 5
CNOT 4 5
CNOT 3 4
H 3
H 5
H 4
H 6
CNOT 4 5
CNOT 5 6
RZ(1.0) 6
CNOT 5 6
CNOT 4 5
H 4
H 6
H 5
H 7
CNOT 5 6
CNOT 6 7
RZ(1.0) 7
CNOT 6 7
CNOT 5 6
H 5
H 7
RX(pi/2) 0
RX(pi/2) 2
CNOT 0 1
CNOT 1 2
RZ(1.0) 2
CNOT 1 2
CNOT 0 1
RX(-pi/2) 0
RX(-pi/2) 2
RX(pi/2) 0
RX(pi/2) 6
CNOT 0 1
CNOT 1 2
CNOT 2 3
CNOT 3 4
CNOT 4 5
CNOT 5 6
RZ(1.0) 6
CNOT 5 6
CNOT 4 5
CNOT 3 4
CNOT 2 3
CNOT 1 2
CNOT 0 1
RX(-pi/2) 0
RX(-pi/2) 6
RX(pi/2) 1
RX(pi/2) 3
CNOT 1 2
CNOT 2 3
RZ(1.0) 3
CNOT 2 3
CNOT 1 2
RX(-pi/2) 1
RX(-pi/2) 3
RX(pi/2) 1
RX(pi/2) 7
CNOT 1 2
CNOT 2 3
CNOT 3 4
CNOT 4 5
CNOT 5 6
CNOT 6 7
RZ(1.0) 7
CNOT 6 7
CNOT 5 6
CNOT 4 5
CNOT 3 4
CNOT 2 3
CNOT 1 2
RX(-pi/2) 1
RX(-pi/2) 7
RX(pi/2) 2
RX(pi/2) 4
CNOT 2 3
CNOT 3 4
RZ(1.0) 4
CNOT 3 4
CNOT 2 3
RX(-pi/2) 2
RX(-pi/2) 4
RX(pi/2) 3
RX(pi/2) 5
CNOT 3 4
CNOT 4 5
RZ(1.0) 5
CNOT 4 5
CNOT 3 4
RX(-pi/2) 3
RX(-pi/2) 5
RX(pi/2) 4
RX(pi/2) 6
CNOT 4 5
CNOT 5 6
RZ(1.0) 6
CNOT 5 6
CNOT 4 5
RX(-pi/2) 4
RX(-pi/2) 6
RX(pi/2) 5
RX(pi/2) 7
CNOT 5 6
CNOT 6 7
RZ(1.0) 7
CNOT 6 7
CNOT 5 6
RX(-pi/2) 5
RX(-pi/2) 7

The returned value from exponentiate is a pyQuil Program object. The object has some nice features such as a dagger function 🗡, easy classical control-flow construction, and introspection 🧐. The circuit can be simulated w/ or w/o noise by running on the Forest-QVM or on reference-qvm. In order to pyquil Programs on the Forest-QVM you'll need to sign up on the Forest Home Page for a key.


In [10]:
from pyquil.api import QVMConnection

qvm = QVMConnection()
wf  = qvm.wavefunction(pyquil_program)

The resulting Wavefunction object from pyQuil contains pretty printing features and the ability to access the wavefunction.


In [11]:
print(wf.amplitudes)


[ 7.00987799e-01-2.45326947e-17j  3.92994831e-17-3.93511578e-17j
  8.32667268e-17-2.94392336e-17j  1.23259516e-32-6.16297582e-33j
  7.28415967e-17+1.21789046e-17j  4.29322157e-18+4.72726933e-02j
 -2.31111593e-33-4.62223187e-33j  6.13317367e-19-1.73472348e-18j
  8.83177008e-17+8.32667268e-17j -1.54074396e-33-3.08148791e-33j
 -1.22663473e-17+4.72726933e-02j  1.22374427e-17+2.56124151e-17j
  4.62223187e-33-5.92223458e-33j -1.73472348e-18+3.06658683e-18j
  3.03052647e-18+8.12841312e-18j  3.18794070e-03+6.59316169e-18j
  5.98234944e-17-9.24978143e-17j -8.65320847e-02-1.83995210e-18j
  6.16297582e-33-3.85185989e-33j  1.73472348e-18+3.37324552e-18j
 -7.35980840e-18+2.49426544e-01j  3.84740581e-17+3.01653046e-17j
  4.90653893e-18+3.12250226e-17j  1.00148357e-32+6.16297582e-33j
  2.31111593e-33+4.62223187e-33j  7.35980840e-18+6.93889390e-18j
  2.23169186e-17-4.01382536e-17j  3.06658683e-18-5.83548631e-03j
 -4.16333634e-17-2.45326947e-17j -7.22223729e-33-4.62223187e-33j
  1.68206416e-02-2.45326947e-18j  3.74601732e-17+4.21741199e-18j
  5.55111512e-17-3.92523115e-17j  0.00000000e+00-7.70371978e-33j
 -8.65320847e-02-4.90653893e-18j -3.70701914e-18-3.92220690e-18j
 -2.31111593e-33+7.70371978e-34j  9.81307787e-18+5.20417043e-18j
  1.50806662e-17+1.66050154e-17j -9.19976050e-18+5.83548631e-03j
  0.00000000e+00+2.49426544e-01j  7.52545209e-18-8.93691050e-18j
  1.47196168e-17+5.55111512e-17j  9.77409447e-33+5.99445695e-33j
 -1.77044433e-17+8.81115958e-18j -1.68206416e-02+6.13317367e-19j
  1.54074396e-33-5.77778983e-33j -4.33680869e-18-1.37996408e-18j
 -1.54074396e-33-1.23259516e-32j  1.73472348e-18-9.81307787e-18j
 -1.62074246e-18+4.70464014e-18j -1.06817860e-02-7.35980840e-18j
  4.90653893e-17-3.12250226e-17j -1.21333586e-32+0.00000000e+00j
  2.94392336e-17-3.07899779e-02j  1.59355344e-18+3.32526298e-17j
  1.80210663e-17-9.69809204e-18j -9.81307787e-18+3.07899779e-02j
  8.85927774e-33-7.70371978e-33j -2.14661078e-18+6.07153217e-18j
  8.87513323e-02-2.94392336e-17j  3.04472614e-18-1.95211184e-17j
  4.68375339e-17-3.85185989e-34j  7.70371978e-33-5.77778983e-33j
  6.65821308e-18-3.54088865e-17j  2.57593294e-17+1.34765737e-01j
  1.54074396e-32+1.30963236e-32j  5.51985630e-18-3.46944695e-18j
 -2.96417285e-01+4.17055809e-17j -1.38138467e-18+1.13628532e-17j
 -2.42861287e-17+8.58644313e-18j  3.85185989e-33+5.00741786e-33j
 -9.24446373e-33+7.02964430e-33j  3.46944695e-18+9.81307787e-18j
 -9.41613524e-18-3.91718656e-18j -9.08823145e-03+1.10397126e-17j
  9.81307787e-18+0.00000000e+00j -7.70371978e-34+4.42963887e-33j
 -1.22663473e-18+1.99895682e-02j  5.55305287e-18+9.66284744e-18j
 -1.59462515e-17-1.61933501e-01j -1.17616004e-17-2.76276934e-18j
  8.58644313e-18-4.68375339e-17j -2.31111593e-33+3.08148791e-33j
  4.87156183e-17+5.01560530e-17j -7.36228577e-02+6.74649103e-18j
  5.44075209e-33+1.23259516e-32j  4.33680869e-18+1.83995210e-18j
 -6.93889390e-18+1.22663473e-17j -7.70371978e-34-3.85185989e-33j
  1.09203509e-02+1.34929821e-17j  6.10010204e-18+3.13977366e-18j
 -1.00148357e-32+3.08148791e-33j  8.58644313e-18-1.73472348e-18j
 -1.26336797e-17-1.73170072e-17j -4.81482486e-35+4.96492347e-03j
  3.46667390e-33+6.16297582e-33j  2.45326947e-17+5.20417043e-18j
 -9.96867836e-19-1.88322705e-17j  6.13317367e-18-1.66358961e-02j
  0.00000000e+00+2.94392336e-17j  0.00000000e+00+7.70371978e-34j
 -3.65906591e-02-1.71728863e-17j -1.14141731e-17-2.93788992e-18j
 -1.93961841e-17-1.15023427e-17j -4.79525495e-02+2.20794252e-17j
  9.62964972e-34-3.08148791e-33j -7.80625564e-18+5.21319762e-18j
 -4.41588504e-17-1.05471649e-01j -5.68178664e-19+1.46739168e-17j
  6.74649103e-18-1.21430643e-17j  1.15555797e-33+1.54074396e-33j
  2.45326947e-17+3.81639165e-17j  3.08148791e-33+0.00000000e+00j
  4.78387546e-17-1.99895682e-02j -1.30173658e-17+8.31670737e-18j
 -9.24446373e-33-6.16297582e-33j  1.73472348e-17+3.85185989e-34j
 -3.87639688e-18+9.18982535e-18j  9.08823145e-03+4.90653893e-18j
 -5.76194244e-02-2.69859641e-17j  7.27356903e-18+8.57198331e-18j
 -3.46944695e-17-1.31863234e-17j  9.24446373e-33+2.31111593e-33j
  5.46211569e-17+2.28354461e-17j  1.22663473e-17+2.61965972e-02j
  7.70371978e-34+3.08148791e-33j  2.45326947e-18+6.07153217e-18j
  1.22663473e-16-5.55111512e-17j  1.54074396e-32-6.16297582e-33j
  4.90653893e-18+1.34765737e-01j  9.73810266e-18+4.74894117e-17j
  3.85185989e-33-1.23259516e-32j  0.00000000e+00+1.04263952e-17j
  1.30247750e-17+7.13656563e-18j  9.08823145e-03+4.29322157e-18j
 -2.96417285e-01+9.81307787e-18j  1.09313985e-17+1.82527121e-17j
 -1.73472348e-17+4.17055809e-17j  9.24446373e-33-3.08148791e-33j
 -7.77412901e-19+2.54856364e-17j -6.13317367e-19-1.99895682e-02j
  2.31111593e-33+3.46667390e-33j  7.66646708e-19+1.51788304e-18j
  1.23259516e-32+0.00000000e+00j -1.04263952e-17+2.08166817e-17j
 -8.61178601e-18+6.21633285e-17j -4.59988025e-18+1.66358961e-02j
  4.16333634e-17+1.71728863e-17j  3.08148791e-33+1.23259516e-32j
 -4.79525495e-02+9.81307787e-18j -3.91585047e-17+4.19625555e-18j
  1.05155631e-17+1.25189319e-17j -3.65906591e-02-2.45326947e-18j
 -9.24446373e-33-4.62223187e-33j  3.03576608e-18-3.06658683e-18j
 -4.90653893e-18+1.05471649e-01j  4.71073556e-18-1.66334147e-18j
  2.45326947e-17+8.67361738e-18j  3.85185989e-33+0.00000000e+00j
  3.92523115e-17-1.61933501e-01j  4.72472151e-18+2.93762329e-17j
 -8.34111619e-17-1.38777878e-17j  6.16297582e-33+1.19407657e-32j
 -6.65336589e-18-1.05251962e-17j  1.09203509e-02-4.90653893e-18j
 -6.16297582e-33-1.38666956e-32j -1.73472348e-18+1.83995210e-18j
  2.77555756e-17+0.00000000e+00j  2.31111593e-33-6.16297582e-33j
 -7.36228577e-02-4.90653893e-17j -1.55178073e-19-6.52804421e-19j
  5.39260384e-33+3.08148791e-33j -1.28796647e-17+5.20417043e-18j
  4.64475607e-18+2.33993597e-17j  3.21991618e-18+4.96492347e-03j
 -1.28379296e-16-2.26660683e-17j -1.47196168e-17+1.99895682e-02j
  3.85185989e-34+3.37037740e-33j -6.13317367e-18-7.80625564e-18j
  5.76194244e-02+2.94392336e-17j -2.43862085e-17-1.34541155e-18j
  2.08166817e-17-2.94392336e-17j  3.08148791e-33-9.62964972e-35j
 -1.61778115e-32-2.00296714e-32j  1.04083409e-17+2.20794252e-17j
  1.69858607e-17+5.20307406e-18j  9.08823145e-03-9.19976050e-19j
 -9.81307787e-18-6.93889390e-18j  1.54074396e-33-4.81482486e-33j
  4.90653893e-18+2.61965972e-02j -6.67192901e-18-1.61044912e-17j
  9.24446373e-33-2.42667173e-32j  2.77555756e-17+6.13317367e-18j
 -5.52553868e-18+2.74102652e-17j  2.59088731e-02-1.16530300e-17j
  1.22663473e-17+5.55111512e-17j  3.08148791e-33+9.62964972e-35j
  1.59462515e-17-5.69865751e-02j -1.53994479e-18-1.16715351e-17j
  6.92787143e-19+2.10311262e-17j  7.70371978e-34+5.69865751e-02j
 -4.62223187e-33+1.23259516e-32j  1.22663473e-18-4.33680869e-18j
 -1.25341991e-01+2.94392336e-17j -2.08627668e-18+8.07605956e-18j
 -5.20417043e-18-1.59462515e-17j  7.70371978e-34-2.31111593e-33j
  0.00000000e+00+3.67990420e-18j  9.05187074e-33-3.08148791e-33j
  3.11319079e-02+9.81307787e-18j  1.52236307e-17-4.31593369e-18j
 -1.23259516e-32+6.16297582e-33j  1.83995210e-18+1.38777878e-17j
 -1.89978528e-17-1.40978401e-19j -3.06658683e-18+1.41540819e-02j
 -7.35980840e-18+6.84746420e-02j  9.29453247e-18-7.88667233e-18j
 -2.94392336e-17+7.80625564e-18j -3.85185989e-34-4.62223187e-33j
 -1.24750611e-17+7.47578871e-18j  3.11319079e-02-1.22663473e-18j
 -9.24446373e-33-3.08148791e-33j -2.16840434e-18-6.13317367e-19j
 -5.09712727e-17+1.95357294e-18j -3.11319079e-02+1.47196168e-17j
 -9.24446373e-33+4.81482486e-34j  1.73472348e-18+3.67990420e-18j
  2.94392336e-17-6.84746420e-02j -1.05653590e-17+4.70806762e-18j
  1.22663473e-17-3.12250226e-17j -5.97038283e-33+3.08148791e-33j
 -5.39260384e-33-1.84889275e-32j -7.35980840e-18+3.46944695e-18j
  2.05325972e-18-2.76276934e-18j  1.07330539e-17+1.41540819e-02j
 -6.93889390e-18+4.41588504e-17j  7.70371978e-33+4.52593537e-33j
  3.11319079e-02+2.26927426e-17j -9.54646388e-18-3.90723588e-18j
  3.74078674e-02+4.90653893e-18j -9.41613524e-18-2.15294650e-17j
  3.46944695e-17+2.57593294e-17j -7.70371978e-33-3.85185989e-33j
 -5.08732218e-17-2.66134636e-17j -4.90653893e-18-1.70074388e-02j
 -1.54074396e-33-1.00148357e-32j -1.22663473e-18-1.73472348e-18j
  9.07709703e-17+1.38777878e-17j -1.54074396e-33-2.31111593e-33j
  2.23860839e-17-1.70074388e-02j -1.08644193e-17+1.29753307e-17j
  4.62223187e-33+1.23259516e-32j  5.20417043e-18+4.90653893e-18j
  1.72252185e-17-7.77448904e-18j  7.73241016e-03-6.43983235e-18j]

We can also pretty-print the wavefunction (on by default) which prints the amplitudes and bitstrings in an easy to read fromat.


In [12]:
print(wf)


(0.7009877989+0j)|00000000> + 0.0472726933j|00000101> + 0.0472726933j|00001010> + (0.0031879407+0j)|00001111> + (-0.0865320847+0j)|00010001> + 0.2494265445j|00010100> + -0.0058354863j|00011011> + (0.0168206416+0j)|00011110> + (-0.0865320847+0j)|00100010> + 0.0058354863j|00100111> + 0.2494265445j|00101000> + (-0.0168206416+0j)|00101101> + (-0.010681786+0j)|00110011> + -0.0307899779j|00110110> + 0.0307899779j|00111001> + (0.0887513323+0j)|00111100> + 0.1347657371j|01000001> + (-0.2964172847+0j)|01000100> + (-0.0090882315+0j)|01001011> + 0.0199895682j|01001110> + (-0-0.1619335007j)|01010000> + (-0.0736228577+0j)|01010101> + (0.0109203509+0j)|01011010> + 0.0049649235j|01011111> + -0.0166358961j|01100011> + (-0.0365906591+0j)|01100110> + (-0.0479525495+0j)|01101001> + (-0-0.105471649j)|01101100> + -0.0199895682j|01110010> + (0.0090882315+0j)|01110111> + (-0.0576194244+0j)|01111000> + 0.0261965972j|01111101> + 0.1347657371j|10000010> + (0.0090882315+0j)|10000111> + (-0.2964172847+0j)|10001000> + (-0-0.0199895682j)|10001101> + 0.0166358961j|10010011> + (-0.0479525495+0j)|10010110> + (-0.0365906591+0j)|10011001> + 0.105471649j|10011100> + -0.1619335007j|10100000> + (0.0109203509+0j)|10100101> + (-0.0736228577+0j)|10101010> + 0.0049649235j|10101111> + 0.0199895682j|10110001> + (0.0576194244+0j)|10110100> + (0.0090882315+0j)|10111011> + 0.0261965972j|10111110> + (0.0259088731+0j)|11000011> + -0.0569865751j|11000110> + 0.0569865751j|11001001> + (-0.1253419914+0j)|11001100> + (0.0311319079+0j)|11010010> + 0.0141540819j|11010111> + 0.068474642j|11011000> + (0.0311319079+0j)|11011101> + (-0.0311319079+0j)|11100001> + -0.068474642j|11100100> + 0.0141540819j|11101011> + (0.0311319079+0j)|11101110> + (0.0374078674+0j)|11110000> + (-0-0.0170074388j)|11110101> + -0.0170074388j|11111010> + (0.0077324102+0j)|11111111>