1
$\begingroup$

I have a following example problem in Cirq, representing a very simple operator given by

$$ \hat{H} = a^\dagger_0a_2 + a_0a^\dagger_1 + 0.9\, a^\dagger_0a_1a^\dagger_2a^\dagger_3 + a^\dagger_0a_1a_2a_3 $$

and an example ansatz, obtaining the expectation value in the end.

import cirq
import numpy as np
import openfermion as of
import sympy

H = of.FermionOperator('0^ 2', 1) + of.FermionOperator('0 1^', 1) + of.FermionOperator('0^ 1 2^ 3^', 0.9) \
    + of.FermionOperator('0^ 1 2 3', -0.1)

H = of.FermionOperator('0^ 1', 1) + of.FermionOperator('0 2^', 1) + of.FermionOperator('0^ 2 1^ 3^', 0.9) \
    + of.FermionOperator('0^ 2 1 3', -0.1)

Hmat = of.get_sparse_operator(H, n_qubits=4).A

print(H)
print(sorted(np.linalg.eig(Hmat)[0]))

circuit = cirq.Circuit()
qubits = cirq.LineQubit.range(4)

alpha = sympy.Symbol('alpha')
beta = sympy.Symbol('beta')
gamma = sympy.Symbol('gamma')
delta = sympy.Symbol('delta')

circuit.append(cirq.ry(alpha).on(qubits[0]))
circuit.append(cirq.ry(beta).on(qubits[1]))
circuit.append(cirq.ry(gamma).on(qubits[2]))
circuit.append(cirq.ry(delta).on(qubits[3]))
circuit.append(cirq.X(qubits[2]).controlled_by(qubits[0]))

full_circ = cirq.resolve_parameters(circuit, {'alpha': 1, 'beta': 1, 'gamma': 1, 'delta': 1})
sv = full_circ.final_state_vector()

print(sv)
print(sv.conj().T @ Hmat @ sv)

This Cirq code is giving the following output:

1.0 [0 2^] +
1 [0^ 1] +
-0.1 [0^ 2 1 3] +
0.9 [0^ 2 1^ 3^]
[(-0.547722557505166+5.551115123125783e-17j), (-7.994927024450326e-17-0.5477225575051663j), 0j, 0j, 0j, 0j, 0j, 0j, 0j, 0j, 0j, 0j, 0j, 0j, (4.85722573273506e-17+0.5477225575051662j), (0.5477225575051663+0j)]
[0.5931328 +0.j 0.32402992+0.j 0.32402992+0.j 0.17701835+0.j
 0.32402992+0.j 0.17701835+0.j 0.17701835+0.j 0.09670557+0.j
 0.17701835+0.j 0.09670557+0.j 0.32402992+0.j 0.17701835+0.j
 0.09670557+0.j 0.05283049+0.j 0.17701835+0.j 0.09670557+0.j]
(0.11040049624731614+0j)

I'd like to be able to rewrite this example into an equivalent code in Qiskit, where, as I'm aware is a different spin-orbital mapping, so that I switched 1st and 2nd qubits in ansatz. The code looks like this:

from qiskit import QuantumCircuit
from qiskit.circuit import ParameterVector
from qiskit.quantum_info import Statevector
from qiskit_nature.operators.second_quantization import FermionicOp
import numpy as np

H = FermionicOp([('+_0 -_2', 1), ('-_0 +_1', 1), ('+_0 -_1 +_2 +_3', 0.9), ('+_0 -_1 -_2 -_3', -0.1)], register_length=4)


print(H)
print(sorted(np.linalg.eig(H.to_matrix().A)[0]))

ansatz = QuantumCircuit(4)
p = ParameterVector('theta', length=4)
for i, q in enumerate(ansatz.qubits):
    ansatz.ry(p[i], q)
ansatz.cx(0, 1)

params = [1]*4

vecA = Statevector(ansatz.bind_parameters(params)).data

print(vecA)
print((vecA.conj().T @ H.to_matrix() @ vecA).real)

But the output is different:

Fermionic Operator
register length=4, number terms=4
  (1+0j) * ( +_0 -_2 )
+ (1+0j) * ( -_0 +_1 )
+ (0.9+0j) * ( +_0 -_1 +_2 +_3 )
+ (-0.1+0j) * ( +_0 -_1 -_2 -_3 )
[(-0.547722557505166+5.551115123125783e-17j), (-7.997636868137208e-17-0.5477225575051663j), 0j, 0j, 0j, 0j, 0j, 0j, 0j, 0j, 0j, 0j, 0j, 0j, (4.85722573273506e-17+0.5477225575051662j), (0.5477225575051663+0j)]
[0.5931328 +0.j 0.17701835+0.j 0.32402992+0.j 0.32402992+0.j
 0.32402992+0.j 0.09670557+0.j 0.17701835+0.j 0.17701835+0.j
 0.32402992+0.j 0.09670557+0.j 0.17701835+0.j 0.17701835+0.j
 0.17701835+0.j 0.05283049+0.j 0.09670557+0.j 0.09670557+0.j]
-0.02401568533842704

Why are the expectation values different? Is the operator rewritten in an incorrect way or does the ansatz need different treatment, when rewritten to Qiskit?

$\endgroup$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.