A qubit is a list [a, b] of two complex numbers with |a|^2+|b|^2=1. A single-qubit gate is a 2\times 2 unitary matrix U (its conjugate transpose times itself is the identity, U^\dagger U = I), and it changes a state by matrix-vector multiplication: new = U @ state. In this path a matrix is a Python list of rows, so m[row][col] is one entry.
The simulator you are building needs a drawer of named gates. These are the standard ones, with i the imaginary unit (1j in Python):
Write gate_drawer(names) that returns a dictionary mapping each requested name to its matrix. The names are lower-case: "i", "x", "y", "z", "h", "s", "t". An empty list gives an empty dictionary.
Two matrices that differ only by one common factor e^{i\phi} (a global phase) act the same on every qubit, so each matrix is accepted up to a global phase: [[1j, 0], [0, -1]] counts as S, because it is i\cdot S. Every other difference counts: H without the \frac{1}{\sqrt2} is not H.
You can check your work with Run: for each matrix, the conjugate transpose times the matrix should print as the identity.
Examples
Input: names = ["x", "s"]
Output: {"x": [[0, 1], [1, 0]], "s": [[1, 0], [0, 1j]]}
Input: names = ["h", "t"]
Output: {"h": [[0.7071067811865475, 0.7071067811865475], [0.7071067811865475, -0.7071067811865475]],
"t": [[1, 0], [0, (0.7071067811865476+0.7071067811865475j)]]}
Input: names = []
Output: {}
Constraints
- the names are distinct; entries are compared with a tolerance of
1e-6
Goals
- Write the standard single-qubit gates as 2x2 matrices of complex numbers
- Store a matrix as a list of rows, m[row][col]
- Use the exact normalisation 1/sqrt(2) and the phase e^{i pi/4}