12
$\begingroup$

In IBM Qiskit and Quantum Experience, the custom U3 gate is defined as

$$ U(\theta, \phi, \lambda) = \begin{pmatrix} \cos\left(\frac{\theta}{2}\right) & -e^{i\lambda} \sin\left(\frac{\theta}{2}\right) \\ e^{i\phi} \sin\left(\frac{\theta}{2}\right) & e^{i(\lambda + \phi)} \cos\left(\frac{\theta}{2}\right) \end{pmatrix} $$

Is there any way to quickly obtain the parameters $\theta, \phi$ and $\lambda$ for any arbitrary $2\times 2$ unitary $X$? I know it's possible to write up a lengthy program which could do this, but is there already a similar program out there? Any of the common programming languages would be fine.


Related: What are theta, phi and lambda in cu1(theta, ctl, tgt) and cu3(theta, phi, lam, ctl, tgt)? What are the rotation matrices being used?

$\endgroup$

4 Answers 4

6
$\begingroup$

Python - Sympy

It could be done in python using sympy. I am not really an expert and maybe there could be ways to optimize this, but the following works fine for me. Assuming you have the matrix $$\begin{bmatrix}a & b\\ c & d\end{bmatrix}$$

My program

from sympy import *

def get_angles(a, b, c, d):
    if im(a) == 0:
        print("Not phasing")
        s = _compute_angles(a, b, c, d)
        res = _final_constraint(s)
        if len(res) != 0:
            return res
    print("Phasing by first element...")
    matr = Matrix([[a, b], [c, d]])
    ph = arg(matr[0])
    matr_phased = simplify(matr/(cos(ph) + I*sin(ph)))
    s = _compute_angles(matr_phased[0], matr_phased[1], matr_phased[2],
                        matr_phased[3])
    return _final_constraint(s)


def _compute_angles(a, b, c, d):
    theta, phi, lamb = symbols('\\theta \\phi \\lambda', real=True)
    a_eq = Eq(cos(theta / 2), a)
    b_eq = Eq(-exp(I * lamb) * sin(theta / 2), b)
    c_eq = Eq(exp(I * phi) * sin(theta / 2), c)
    d_eq = Eq(exp(I * (phi + lamb)) * cos(theta / 2), d)
    return solve([a_eq, b_eq, c_eq, d_eq], [theta, phi, lamb], dict=True)


def _final_constraint(result):
    res = []
    for sol in result:
        to_add = True
        for k, v in sol.items():
            if str(k) == '\\theta' and (v < 0 or v > pi):
                to_add = False
                break
            elif str(k) == '\\phi' and (v < 0 or v >= 2 * pi):
                to_add = False
                break
        if to_add:
            res.append(simplify(sol))
    return res

Note that for Qiskit U matrix you should only check if the first number is imaginary and, if it so, you could divide the whole matrix by it. It is not really necessary to divide by the determinant, provided that the matrix represent indeed a valid quantum gate (or, said differently, the magnitude are all less than 1).

To avoid Python evaluation of fractions, instead of simply using 1/2 a common trick is to use S(1)/2 or Rational(1,2)

Examples

A generic unitary

get_angles(sqrt(S(1)/5), sqrt(S(4)/5), -sqrt(S(4)/5), sqrt(S(1)/5)) returns

$$ \left[ \left\{ \lambda : \pi, \ \phi : \pi, \ \theta : 2 \operatorname{acos}{\left(\frac{\sqrt{5}}{5} \right)}\right\}\right] $$

Pauli-Y matrix

$$\begin{bmatrix} 0 & -i \\ i & 0 \end{bmatrix}$$

get_angles(0, -I, I, 0) returns $$ \left[ \left\{ \lambda : \frac{\pi}{2}, \ \phi : \frac{\pi}{2}, \ \theta : \pi\right\}\right] $$

$\sqrt{NOT}$

sqnot = Matrix([[1+I, 1-I], [1-I, 1+I]]) * Rational(1,2)
get_angles(sqnot[0], sqnot[1], sqnot[2], sqnot[3])

$$ \left[ \left\{ \lambda : \frac{\pi}{2}, \ \phi : \frac{3 \pi}{2}, \ \theta : \frac{\pi}{2}\right\}\right] $$

Matrix of Sanchayan Dutta answer

get_angles(-1/sqrt(2), I/sqrt(2), I/sqrt(2), -1/sqrt(2)) $$ \left[ \left\{ \lambda : \frac{\pi}{2}, \ \phi : \frac{3 \pi}{2}, \ \theta : \frac{\pi}{2}\right\}\right] $$

$\endgroup$
14
  • $\begingroup$ Nice! Note that there are some edge cases though. Like when $a$ lies outside the range of $\cos(\theta/2)$. Moreover, you'd have to place the restrictions $0\leq \theta \leq \pi$ and $0 \leq \phi <2\pi$. $\endgroup$ Commented May 26, 2019 at 15:50
  • $\begingroup$ @SanchayanDutta which edge cases are you referring to? For the restrictions, you are right. I have not been able to place them yet, if I simply those equations in the solve function sympy returns an empty result. As I said, I am not really an expert on sympy, but I'll try to figure out something. $\endgroup$
    – tigerjack
    Commented May 26, 2019 at 16:14
  • $\begingroup$ Say, your code wouldn't work for 1/2[[1+i,1-i],[1-i,1+i]] i.e. the square root of NOT. $\endgroup$ Commented May 26, 2019 at 16:17
  • $\begingroup$ @SanchayanDutta well, I think this is a limitation of Qiskit. If I remember correctly, the square root of not is implemented by an $R_Z(\pi/2)$ sandwiched between two H gates. I don't know if they can implement it directly. $\endgroup$
    – tigerjack
    Commented May 26, 2019 at 17:53
  • 1
    $\begingroup$ @SanchayanDutta I think this is the final version $\endgroup$
    – tigerjack
    Commented May 29, 2019 at 15:13
4
$\begingroup$

Qiskit

You can also do this directly from Qiskit using this piece of code

from qiskit.quantum_info.synthesis import euler_angles_1q 
from scipy.linalg import sqrtm 
import numpy as np 

x_matrix = np.array([[0, 1], [1, 0]]) 
x_90_matrix = sqrtm(x_matrix)
# Returns (theta, phi, lambda) 
euler_angles_1q(x_90_matrix)                                                                                 
Out[4]: (1.5707963267948966, -1.5707963267948966, 1.5707963267948966)

an_matr = np.array([[-1/sqrt(2), 1j/sqrt(2)], [1j/sqrt(2), -1/sqrt(2)]]
euler_angles_1q(an_matr)                                                                                                      
Out[14]: (1.5707963267948966, 4.71238898038469, 1.5707963267948966

Thanks to the Qiskit slack channel for this hint. For those interested, here there is the source code of the euler_angles_1q function.

$\endgroup$
3
$\begingroup$

Mathematica

With help from Mathematica SE, I managed to put this together (assuming Z is our 2 × 2 unitary):

U = {{Cos[\[Theta]/
     2], -E^(I \[Lambda]) Sin[\[Theta]/
      2]}, {E^(I \[Phi]) Sin[\[Theta]/2], 
   E^(I (\[Lambda] + \[Phi])) Cos[\[Theta]/2]}};
FullSimplify[
 Reduce[Z == U && 0 <= \[Phi] < 2 Pi && 0 <= \[Theta] <= Pi && 
   0 <= \[Lambda] < 2 Pi, {\[Theta], \[Phi], \[Lambda]}]]

Note that you'll need to define Z beforehand. Say, if $Z=\begin{pmatrix}-\frac{1}{\sqrt 2} & \frac{i}{\sqrt 2} \\ \frac{i}{\sqrt 2} & -\frac{1}{\sqrt 2} \end{pmatrix}$, the corresponding code is:

Z = {{-1/Sqrt[2], I/Sqrt[2]}, {I/Sqrt[2], -1/Sqrt[2]}};
Z = Z/Sqrt[Det[Z]];
Z = Simplify[Z/Exp[I Arg[Z[[1, 1]]]]];
U = {{Cos[\[Theta]/
     2], -E^(I \[Lambda]) Sin[\[Theta]/
      2]}, {E^(I \[Phi]) Sin[\[Theta]/2], 
   E^(I (\[Lambda] + \[Phi])) Cos[\[Theta]/2]}};
FullSimplify[
 Reduce[Z == U && 0 <= \[Phi] < 2 Pi && 0 <= \[Theta] <= Pi && 
   0 <= \[Lambda] < 2 Pi, {\[Theta], \[Phi], \[Lambda]}]]

and the solution is:

2 \[Theta] == \[Pi] && 2 \[Phi] == 3 \[Pi] && 2 \[Lambda] == \[Pi]

Note that the matrix $U(\pi/2,3\pi/2,\pi/2)$ differs by a phase factor from $Z$. This is because of the transformation due to

Z = Z/Sqrt[Det[Z]];
Z = Simplify[Z/Exp[I Arg[Z[[1, 1]]]]];

which is meant to deal with those cases where $Z_{11}$ exceeds the range of $\cos(\frac{\theta}{2})$. I've discussed about this here. Remember that $0\leq \theta \leq \pi$ and $0 \leq \phi <2\pi$ according to the documentation.


P.S: You can run this code on Mathematica Cloud now cf. Wolfram Releases the Wolfram Engine for Developers!!

$\endgroup$
2
  • $\begingroup$ what about taking the traces $\mathrm{Tr}(U\sigma_i)$ for the different Pauli matrices $\sigma_i$ to get the components of the matrix and then just applying $\arccos$ etc where necessary? (I'm asking in case you already considered that but it didn't suit you for some reason) $\endgroup$
    – glS
    Commented May 26, 2019 at 9:55
  • $\begingroup$ I didn't think about that before. Anyway, the traces you mention don't really look "nice". Say $\mathrm{Tr}(U\sigma_1) = -e^{i\lambda}\sin(\frac{\theta}{2})+e^{i\phi}\sin(\frac{\theta}{2})$. There is more than one variable involved in each such trace; a simple arcsin/arccos wouldn't work...at least the way I'm seeing it. $\endgroup$ Commented May 26, 2019 at 10:25
2
$\begingroup$

Note that the function euler_angles_1q is now deprecated. It has been superseded by the 'qiskit.quantum_info.OneQubitEulerDecomposer' class which provides the same functionality. See https://qiskit.org/documentation/stable/0.19/release_notes.html

$\endgroup$

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.