# XX and YY and ZZ Hamiltonians in vqe

I'm trying to implement a vqe in cirq and I have sort of a brain knot.

I have a 4 qubit chain with periodic boundary condition. So in fact a 2x2 qubit grid.

Now 2 of them each are coupled.

How do I get the correct measurements for the expectation value?

• Can you give some more details? What exactly do you mean by periodic boundary conditions? Can you give a code sample? Sep 21 '20 at 15:53
• Do you mean how to calculate expectation values for $XX$, $YY$, and $ZZ$ operators or do you mean circuit construction for $e^{-i XX t_1}$, $e^{-i YY t_2}$ and $e^{-i ZZ t_3}$ unitaries? Sep 21 '20 at 16:40
• I mean how to calculate the expectation values for XX, YY and ZZ operators. I have an Hamiltonian which is X xXx1x1+1xXxXx1+....+Xx1x1xX + same for Z and Y (x is tensorproduct and 1 is the unit-matrix). Sep 21 '20 at 17:05
• And I want to do this with 4 qubits but I don't really know how. Sep 21 '20 at 17:08
• Although this is not a Cirq implementation, I guess this answer (and the referred answers there) might be interesting. Sep 21 '20 at 17:15

There is a type cirq.PauliSum created when you add together products of Pauli operations. This type has a method expectation_from_state_vector and expectation_from_density_matrix. This is the easiest way to get the expectation values, if you're just calculating them instead of estimating them from samples taken from hardware.

Note that both methods require you to specify an index for each qubit. This is because the state vector is just a numpy array, with no information about which axes (or which bits of the index) correspond to which qubits..

import cirq

qubits = cirq.LineQubit.range(4)
pauli = cirq.Z

operator: cirq.PauliSum = sum(pauli(qubits[k - 1]) * pauli(qubits[k]) for k in range(4))
print("operator", operator)
# operator 1.000*Z(0)*Z(3)+1.000*Z(0)*Z(1)+1.000*Z(1)*Z(2)+1.000*Z(2)*Z(3)

a, b, c, d = qubits
circuit = cirq.Circuit(
cirq.H(a),
cirq.CNOT(a, b),
cirq.CNOT(a, c),
cirq.CNOT(a, d),
)
final_state = cirq.final_state_vector(circuit, qubit_order=qubits)

expectation = operator.expectation_from_state_vector(
final_state,
qubit_map={q: q.x for q in qubits})
print("z_expectation", expectation)
# z_expectation (3.999999761581421+0j)


If you instead want to estimate the operators based on samples, the process is more manual. For example, you could make three separate variations of the circuit. One where you measure all the qubits in the X basis, one where you measure all the qubits in the Y basis, and one where you measure all the qubits in the Z basis. You can then multiply (or xor) the individual measurement results together to get the paired measurement results and compute the average.

sampler = cirq.Simulator()  # or a hardware sampler

circuit_x = circuit + [[cirq.H(q), cirq.measure(q)] for q in qubits]
circuit_y = circuit + [[cirq.X(q)**0.5, cirq.measure(q)] for q in qubits]
circuit_z = circuit + [cirq.measure(q) for q in qubits]

import numpy as np
import pandas as pd
x_samples: pd.DataFrame = sampler.sample(circuit_x, repetitions=1000)
x_cols = [x_samples[str(q)] for q in qubits]
x_parity_bits = np.array([x_cols[k-1] ^ x_cols[k] for k in range(4)], dtype=np.int8)
x_parity_signs = 1 - 2 * x_parity_bits
x_expectation = np.mean(x_parity_signs)
print("x_expectation", x_expectation)
# x_expectation -0.011

• Okay thank you very much! I was looking for something like the PauliSum. Sep 21 '20 at 21:43
• @Schroedinger101 The type of qubit doesn't matter. Just change the assignment at the start. As for the VQE that's an entirely separate thing; it's the start of the circuit instead of the estimation part at the end. Sep 21 '20 at 23:32
• So if I had a Hamiltonian with XX and ZZ terms I would have to take the Pauli sum for cirq.X and cirq.Z and do the code you did for both and add the results? Sep 29 '20 at 14:19
• @Craig_Gidney So if I had a Hamiltonian with XX and ZZ terms I would have to take the Pauli sum for cirq.X and cirq.Z and do the code you did for both and add the results? Sep 29 '20 at 14:43
• @CraigGidney I would be interested in the question too. If you would have for example a XY-model on a 3 qubit chain, would you do the Pauli sum of all the X and all the Y- Pauli combinations and then do a circuit for X and for Y and calculate the expectation for X and Y each and after that add the expectation for the X-terms and for the Y-terms? Oct 18 '20 at 18:50