I am simulating a circuit in cirq, and I need to measure an observable $$A(\theta) = R^\dagger_z(\theta)XR_z(\theta),$$ and I am not quite sure how to do that.

My first thought was to apply these gates to the qubit and then measure in the computational basis, but that didn't give the right result.

I read in the documentation that you can measure specific observables using pauli strings, so I tried defining a pauli string along the lines of

pauli_string = cirq.Z(q_in)**(-np.pi/4)*cirq.X(q_in)*cirq.Z(q_in)**(np.pi/4)

But I am getting an error saying i can't construct pauli strings out of the exponantiated bit

    pauli_string = cirq.PauliString(cirq.Z(q_in))**(-np.pi/4)*cirq.X(q_in)*cirq.Z(q_in)**(np.pi/4)
TypeError: unsupported operand type(s) for *: 'GateOperation' and 'SingleQubitPauliStringGateOperation'

I am not quite sure anymore how to simulate measuring this observable using cirq. If the answer is pauli strings, how can I make it work? If there is an easier/more correct way to do it, what is it?


1 Answer 1


By default Cirq offers Z basis measurement, not unlike a physical device (though there is the Pauli string wrapper around it as you mentioned which does the same thing under the hood I detail). When you want to change the Z observable measured, you should think of each gate conjugating it. I.e. $X=HZH$, $A(\theta)=R_z(-\theta) H Z H R_z(\theta)$. Thus, you'll need to apply the $R_z$ rotation, then H, then simply cirq.measure. As you are working with arXiv:2209.07345v2, I implemented the circuit from Fig 1, having $|\psi\rangle = T|+\rangle$ and $\theta=0.2\pi$ and I undid the rotations $HZ^sR_z(\theta)$ by applying the inverses in reverse order. The final state vector shows that we have $T|+\rangle$ on the second qubit, while the first one is probabilistically $|0\rangle$ or $|1\rangle$.

a, b = cirq.LineQubit.range(2)
theta = 0.2 * np.pi
c= cirq.Circuit(
          cirq.H(a), cirq.T(a) # T rotation on a 
          , cirq.H(b) # plus state on b 
          , cirq.CZ(a,b)
          , cirq.rz(theta)(a), cirq.H(a) ,cirq.measure(a, key='a'), # measure A(theta) 
          cirq.H(b), # undo H
          cirq.Z(b).with_classical_controls('a'), # undo classical CZ 
          cirq.rz(-theta)(b), # undoing the theta rotation           

for _ in range(10): 
  res = cirq.Simulator().simulate(c)

Results in something similar to this, showing that we get back the T rotated state on b:

0.71|10⟩ + (0.5+0.5j)|11⟩
0.71|00⟩ + (0.5+0.5j)|01⟩
0.71|10⟩ + (0.5+0.5j)|11⟩
0.71|00⟩ + (0.5+0.5j)|01⟩
0.71|10⟩ + (0.5+0.5j)|11⟩
0.71|10⟩ + (0.5+0.5j)|11⟩
0.71|10⟩ + (0.5+0.5j)|11⟩
0.71|00⟩ + (0.5+0.5j)|01⟩
0.71|00⟩ + (0.5+0.5j)|01⟩
0.71|10⟩ + (0.5+0.5j)|11⟩
  • $\begingroup$ Thank you, but this doesn't seem to work either and i'm not sure why. I am testing it by trying to implement a T gate through teleportation (a CNOT, then a measurement on the rotated basis, then a Z gate correction depending on the result, as seen in arXiv:2209.07345v2). The circuit looks like: CNOT(in, out), H(in), Rz(0.25pi)in, measure(in), Z.with_classical_controls(out). Passing a |+⟩ state through a T gate gives ` 0.707|0⟩ + (0.5+0.5j)|1⟩, while passing it though this circuit just gives back a |+⟩` state $\endgroup$ Commented Feb 5 at 13:38
  • $\begingroup$ I made a mistake in the ordering - Rz first then H. I looked at the paper and updated my answer with a working example, hope the comments make sense. I am doing a T rotation now on a, and get back the T rotation (after undoing the H, Z^s and Rz rotation) on the resulting state. Hope this helps! $\endgroup$ Commented Feb 5 at 17:00
  • $\begingroup$ Here's a quirk circuit implementing the circuit from Figure 1 in the paper with the undoing of the rotations, you get back the original state (message). $\endgroup$ Commented Feb 5 at 18:59

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.