# Finding the rotation axis and angle in a Bloch sphere for a arbitrary quantum gate

I have an arbitrary single qubit quantum gate $$U_3(t,f,l)$$ that transforms (rotates) a given qubit $$q$$ into the target qubit $$p$$. \begin{align}U_3(t,f,l) q = p && t,l,f \in \mathbb{R}; q,p \in \mathbb{C^2} \end{align} with $$U_3(t,f,l) = \begin{pmatrix}\cos{\frac{t}{2}} & - e^{i l}\sin{\frac{t}{2}} \\ e^{i f} \sin{\frac{t}{2}} & e^{i(f+l)} \cos{\frac{t}{2}} \end{pmatrix}$$ I'm able to transfer the qubits $$q$$ and $$p$$ into their Bloch sphere representations $$q'$$ and $$p'$$. But what is the Bloch sphere representation of $$U_3$$? There must be a matrix $$R_{(\vec{v},r)}$$ that fulfills this equation: \begin{align}R_{(\vec{v},r)} q' = p' && R_{(\vec{v},r)} \in \mathbb{R}^{3\times3}; q', p' \in \mathbb{R}^3\end{align} with $$\vec{v} = \begin{pmatrix}u\\v\\w\end{pmatrix};u,v,w,r \in \mathbb{R};u^2+v^2+w^2=1$$ where $$\vec{v}$$ is the rotation axis within the Bloch sphere and $$r$$ is the turning angle. For example, for the Hadamard gate this would be $$\vec{v} = \begin{pmatrix}1 \\ 0 \\ 1 \end{pmatrix}$$ and $$r=\pi$$.

I'm aware about https://quantumcomputing.stackexchange.com/a/16538/21105 but there seems to be an important step missing at the end.

• what step are you saying is missing in the answers to the linked post?
– glS
Commented Jul 27, 2022 at 16:59

1. Decompose the matrix into the Pauli basis $$U = wI + x(iX) + y(iY) + z(iZ)$$.
2. The coefficients you got can be multiplied by a common phase factor so that they are all on the real line. After phasing them like that, the coefficients are the same coefficients as a quaternion rotation $$w + \hat{i}x + \hat{j}y + \hat{k}z$$.
3. Convert the quaternion rotation to an axis angle rotation. The ijk part tells you the axis and the length of the real part is related to the angle.

Here's the code in Quirk (in the Matrix class) that does it:


/**
* Given a single-qubit operation matrix U, finds φ, θ, and v=[x,y,z] that satisfy
* U = exp(i φ) (I cos(θ/2) - v σ i sin(θ/2))
*
* @returns {!{axis: !Array.<!number>, angle: !number, phase: !number}}
*/
qubitOperationToAngleAxisRotation() {
Util.need(this.width() === 2 && this.height() === 2, "Need a 2x2 matrix.");
Util.need(this.isUnitary(0.01), "Need a unitary matrix.");

// Extract orthogonal components, adjusting for factors of i.
let [a, b, c, d] = this._2x2Breakdown();
let wφ = a.plus(d);
let xφ = b.plus(c).dividedBy(Complex.I);
let yφ = b.minus(c);
let zφ = a.minus(d).dividedBy(Complex.I);

// Cancel global phase factor, pushing all values onto the real line.
let φ = seq([wφ, xφ, yφ, zφ]).maxBy(e => e.abs()).unit().times(2);
let w = Math.min(1, Math.max(-1, wφ.dividedBy(φ).real));
let x = xφ.dividedBy(φ).real;
let y = yφ.dividedBy(φ).real;
let z = zφ.dividedBy(φ).real;
let θ = -2*Math.acos(w);

// Normalize axis.
let n = Math.sqrt(x*x + y*y + z*z);
if (n < 0.0000001) {
// There's an axis singularity near θ=0. Just default to no rotation around the X axis.
return {axis: [1, 0, 0], angle: 0, phase: φ.phase()};
}
x /= n;
y /= n;
z /= n;

// Prefer θ in [-π, π].
if (θ <= -Math.PI) {
θ += 2*Math.PI;
φ = φ.times(-1);
}

// Prefer axes that point positive-ward.
if (x + y + z < 0) {
x = -x;
y = -y;
z = -z;
θ = -θ;
}

return {axis: [x, y, z], angle: θ, phase: φ.phase()};
}