I am reading cirq guide about Simulation and there is an example in "Expectation values" paragraph that I don't understand.

Everything boils down to the following snippet:

import cirq

q0 = cirq.GridQubit(0, 0)
q1 = cirq.GridQubit(1, 0)

def basic_circuit():
    sqrt_x = cirq.X**0.5
    yield sqrt_x(q0), sqrt_x(q1)
    yield cirq.CZ(q0, q1)
    yield sqrt_x(q0), sqrt_x(q1)

circuit = cirq.Circuit(basic_circuit())

XX_obs = cirq.X(q0) * cirq.X(q1)
ZZ_obs = cirq.Z(q0) * cirq.Z(q1)

ev_list = cirq.Simulator().simulate_expectation_values(circuit, observables=[XX_obs])
# Output:

First, I don't understand what XX_obs and ZZ_obs do. What does it mean to multiply two circuits by * operator. Is it the tensor product of the operations or something else?

Second, is simulating observable XX_obs the same as adding XX_obs at the end of circuit? If so, how to read the following printed output:

# Output:
(0, 0): ───X^0.5───@───X^0.5───PauliString(+X)───
                   │           │
(1, 0): ───X^0.5───@───X^0.5───X─────────────────

Third, if I simulate the above circuit without measurement I get the following output which does not resemble [(1+0j)] obtained previously:

result = cirq.Simulator().simulate(circuit)
# output:
measurements: (no measurements)
output vector: 0.5|00⟩ + 0.5j|01⟩ + 0.5j|10⟩ + 0.5|11⟩

Why is it so?

PS. It is my very first question on this site so be forgiving about tags I used or about some conventions that you use and I don't know.


1 Answer 1


$Z_{q0} Z_{q1}$ is an observable; a thing that you can measure.

If I tell you to measure $Z_{q0}$, I am telling you to measure qubit $q0$ in the computational basis (i.e. in the usual way, i.e. whether the qubit is $|0\rangle$ or $|1\rangle$).

If I tell you to measure $X_{q0}$, I am telling you to measure qubit $q0$ in the X basis (i.e. whether the qubit is $|+\rangle$ or $|-\rangle$). Typically you would do this by applying a Hadamard operation to $q0$ before applying the usual measurement operation.

If I tell you to measure $Z_{q0} Z_{q1}$, I am telling you to measure the parity of qubit $q0$ and qubit $q1$ in the computational basis (i.e. whether they are the same or different, i.e. whether you are in the $01$ and $10$ subspace or in the $00$ and $11$ subspace). Typically you would do this by applying a CNOT operation from $q0$ to an ancilla, and then from $q1$ to an ancilla, then measuring the ancilla. If you don't need to continue the circuit or measure other observables, you would instead just measure $Z_{q0}$ and also measure $Z_{q1}$ and check if they were the same using classical postprocessing.

If I tell you to measure $X_{q0} X_{q1}$, I am telling you to measure the parity between qubit $q0$ and $q1$ in the X basis.

If I ask for the expectation value of an observable, then I want you to run the circuit many times, measuring that observable at the end of the circuit each time, and tell me the average of the results.

So passing $X_{q0} X_{q1}$ into the method you are talking about doesn't put $X$ operations at the end of the circuit... it actually puts Hadamard and measurement operations at the end of the circuit, runs the circuit many times, and reports how frequently those two measurements differ from each other.

The reason we refer to observables in this product-of-operations way is because one way to measure an observable is to perform those operations, but controlled on an ancilla in the $|+\rangle$ state. This flips the ancilla to the $|-\rangle$ state via phase kickback, if the system state is in the -1 eigenspace of the product-of-operations. There are also a lot of other nice things about thinking about measurements in this way, e.g. it is the basis of the stabilizer formalism which allows Clifford circuits to be simulated efficiently.

  • $\begingroup$ Ok, so this * operation creates new observables which cares about parity. So I understand that $X_{q1}X_{q2}$ should look like state $c_1P + c_2NP$ where $P$ and $NP$ denotes parity and non-parity respectively. In such case, since expectation value returns scalar, there should be some scalar value assignment to P an NP (i.e. the parity should be a random variable). Is there such assignment (1 and -1 respectively for example)? $\endgroup$ Commented Apr 4, 2021 at 19:25
  • $\begingroup$ @FallenApart It's typically either False (0) for same and True (1) for different, or else +1 for same and -1 for different. Depends if you're thinking in bits or in signs. $\endgroup$ Commented Apr 4, 2021 at 20:33
  • $\begingroup$ Does this "parity check" operation * have any formal name? $\endgroup$ Commented Apr 4, 2021 at 21:02
  • $\begingroup$ @FallenApart It's just called multiplying the two observables. For Pauli observables on separate qubits you get an observable corresponding to a parity check. For other more complicated observables, or non-commuting observables, you get more complicated things. $\endgroup$ Commented Apr 4, 2021 at 22:31
  • $\begingroup$ Can you support me with some references, I am still unable to obtain the result [(1+0j)]? I just don't know where does it came from. $\endgroup$ Commented Apr 5, 2021 at 13:15

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.