# How to calculate the probabilities of observing quantum states using the “expectation_from_wavefunction” in cirq (and why)

I am currently simulating some quantum circuits, and want to calculate the probabilities of observing each individual state. I am able to use Cirq for this, and calculate it using $$P_{00} = |\alpha|^2$$. Code:

import cirq
import sympy
x0, x1 = sympy.symbols('x0 x1')
q = cirq.GridQubit.rect(1, 2)
circuit = cirq.Circuit(
cirq.rx(x0).on(q[0]), cirq.rx(x1).on(q[1]),
cirq.ry(3.14/4).on(q[0]), cirq.ry(3.14/4).on(q[1]))
resolver = cirq.ParamResolver({x0: 0.2, x1: 0.3})
simulator = cirq.Simulator()
results = simulator.simulate(program=circuit, param_resolver=resolver,
qubit_order=q).final_state
print("Internal quantum state:", results)
print("Probabilities of observing each state:", [abs(x)**2 for x in results])


Output:

internal quantum state: [0.8377083+0.08743566j 0.3529709-0.11249491j 0.35297093-0.06251574j 0.13120411-0.08743566j]
probabilities of observing each state: [0.7094002059173512, 0.13724355108492148, 0.12849669756020887, 0.024859516013751914]


However, in multiple tutorials (for instance from TFQ) I see the use of "expectation_from_wavefunction":

z0 = cirq.Z(q[0])
qubit_map={q[0]: 1, q[1]: 1}
z0.expectation_from_wavefunction(results, qubit_map).real


output:

0.6757938265800476


My question: How can I use expectation_from_wavefunction to obtain the probabilities of observing the individual states ($$P_{00}, P_{01}, P_{10}, P_{11}$$)?
Bonus question: why would I favor this approach?

• Why would want to use "expectation_from_wavefunction()" to calculate the probabilities when you can just do what you did; square the values of your wavefunction? The former takes more work than the latter. – Victory Omole Mar 22 '20 at 14:24
• @VictoryOmole Because in the tutorial of TFQ that I refer to, they only use the "expectation_from_wavefunction". All following examples build upon it. I think it helps with batching, but I am not sure. – Thomas Hubregtsen Mar 22 '20 at 21:06
• sorry, forgot to mention: the top approach works in Cirq. I am trying to run Tensorflow Quantum, and all tutorials here rely on this method. – Thomas Hubregtsen Mar 22 '20 at 21:23
• Tensorflow Quantum combines Tensorflow with Cirq. If you can "import tfq" you can "import cirq" and thus use all the functionality in Cirq. – Victory Omole Mar 23 '20 at 16:14
• expectation_from_wavefunction is used when you don't want to write the logic for yourself. This is more useful in cases with multi-qubit observables involving the X and Y axies. – Craig Gidney Apr 21 '20 at 22:56

why would I favor this approach?

The Expectation value is defined as $$\langle A \rangle= \langle\psi|A|\psi\rangle$$ where $$\psi$$ is the wavefunction and $$A$$ is the operator. Use "expectation_from_wavefunction()" if you don't want to write code that calculates $$\langle\psi|A|\psi\rangle$$.

• Thanks. I see now that the bottom approach calculates the expectation value, which is defined as ⟨𝐴⟩=⟨𝜓|𝐴|𝜓⟩. But how does this relate to the answer from the top approach? Because I see no relation between the numeric outcomes. For a 1-qubit system, would the expectation value not give me the probability of observing the qubit in the state 1? – Thomas Hubregtsen Mar 22 '20 at 21:49
• If you don't see the relation, what calculation did you perform? What do you get? – Victory Omole Mar 23 '20 at 17:00
• The code and its output should be shown in my question. I embed using Rx followed by an Ry. The top approach provides: internal quantum state: [0.8377083+0.08743566j 0.3529709-0.11249491j 0.35297093-0.06251574j 0.13120411-0.08743566j] probabilities of observing each state: [0.7094002059173512, 0.13724355108492148, 0.12849669756020887, 0.024859516013751914] The bottom approach (that seems to have an extra Rz, which I have also experimented with in the top approach to no affect) gives as output for the real component 0.6757938265800476. – Thomas Hubregtsen Mar 23 '20 at 21:20
• I meant: did you take the wavefunction and do a pen-and-paper calculation of that expectation value and get the same answer that z0.expectation_from_wavefunction(results, qubit_map).real gives you? – Victory Omole Mar 23 '20 at 23:17

The expectation value that the system provided me with was 0.6757938265800476. This was in a range of [-1,1]. Mapping this to a range of [0,1]: (0.6757938265800476+1)/2=0.837896913290024. The expectation value was the expectation value for qubit 0. This implies that it observed qubit 0 in state 0 83.7896913290024% of the time, and 1-0.837896913290024 in state 1.

The system also printed the following probabilities:
$$P_{00} = 0.7094002059173512$$
$$P_{01} = 0.13724355108492148$$
$$P_{10} = 0.12849669756020887$$
$$P_{11} = 0.024859516013751914$$

The probability to observe qubit 0 (indexing right to left) in state 0:
$$E_{q0} = 0.8378969 = 0.7094002 + 0.1284966 = P_{00} + P_{10}$$

To answer the question "How can I use expectation_from_wavefunction to obtain the probabilities of observing the individual states": you can't. You can only relate this particular expectation value (with Pauli Z) to a set of state probabilities, but not to individual ones without extra information (such as observables in different computational basis)

"Why would I favor this approach": access to the internal quantum state is not realistic with quantum system, and would require more computation.

P.S. this is my current interpretation which I expect to be right on a high level. I think I still have details wrong, such as parts of the explanation. Very open to opinions.