# Rxx gate as a set of rotations

I'm trying to represent Rxx gate as a set of physical rotations of two qubits in 3D space (or as rotations of Bloch Spheres that is the same). In some simple cases it works well:

If q0 is in the state |+⟩ then q1 rotates counterclock-wise, and for |-⟩ it's clockwise. But let's look at a more complicated case when we start from the next state:

After Rxx we have:

and the angles are the same as in the first example but Qiskit shows the arrows shorter. It looks like q1 rotates p/2 and then additionally ±p/4 with a random sign of the angle:

1. Why Qiskit shows the arrows shorter? Is it a bug or a feature (partially entangled states)?
2. What is the second rotation of q1? The sign can't be completely random because an additional Rxx(-pi/2) gate will return the system to its original state. So, what is the dependency?

I need Rxx gate to implement CNOT as a set of physical rotations with a correct "Phase Kickback".

Why Qiskit shows the arrows shorter? Is it a bug or a feature (partially entangled states)?

The arrows are shorter because of entanglement. This behavior is described in Qiskit's textbook[1]. One easy way to measure the entanglement in this bipartite state is by using entanglement_of_formation[2] function.

What is the second rotation of q1

For a multi-qubit quantum state, here is how you can get the cartesian coordinates of Bloch sphere vectors. Use these coordinates to calculate the angles.

from qiskit.visualization.utils import _bloch_multivector_data

bloch_data = (_bloch_multivector_data(state))
print(bloch_data)


I need Rxx gate to implement CNOT as a set of physical rotations with a correct "Phase Kickback".

Qiskit provides TwoQubitBasisDecomposer[3] class which can be used to decompose a 2-qubit unitary into minimal number of uses of a 2-qubit basis gate. Using this class you can implement CNOT using Rxx as follows:

from qiskit.circuit.library import CXGate, RXXGate
from qiskit.quantum_info.synthesis import TwoQubitBasisDecomposer

decomposer = TwoQubitBasisDecomposer(RXXGate(np.pi / 2), basis_fidelity = 1.0)
circ = decomposer(CXGate().to_matrix())


The result:

• I've tried to use "_bloch_multivector_data" but it was not useful, the result is [[0.70, 0.0, 0.0], [0.0, -0.7, 0.0]]. It just says "the arrows are shorter" and it's still unclear what q1 real rotations are. May 3 at 10:07
• If you want to calculate the rotation angles because of applying Rxx, you will need the cartesian coordinates before and after applying it. May 3 at 10:22
• Yes, I have coordinates before too - [[0.70, 0.70, 0.0], [0.0, 0.0, 1.0]]. What is the rotation matrix for Rxx for Cartesian coordinates? I can not calculate it using coordinates "after" because they are ambiguous (contain entanglement). May 3 at 10:32

Finally I found the answer. Bloch sphere coincides with a qubit only before the first controlled operation. After that Bloch sphere shows a "probability", while the real 3D-position of the qubits is the biggest mystery of the quantum world.

According to Bloch sphere there is only one rotation in Rxx (not two as I thought):

q1 rotates counterclock-wise with the probability of ~86% because q0 has the probability of ~86% to be measured as |+⟩. Bloch sphere indicates this as a short arrow pointed "left" because that position is more likely.

q0 rotates counterclock-wise with the probability of 50% because q1 has the probability of 50% to be measured as |+⟩. Bloch sphere indicates this as a short arrow pointed at |+⟩ because it's an average

Anyway Rxx can not be represented as just these two X-rotations, it also adds something else that we call entanglement. This is easy to prove:

This circuit with Rxx(pi/2)Rxx(-pi/2) will always return the qubits to their original state, while simple rotations with probabilities 86% and 50% will not.