qml.labs.dla.khaneja_glaser_involution¶
- khaneja_glaser_involution(op, wire=None)[source]¶
Khaneja-Glaser involution, which is a type-
AIII()
Cartan involution with p=q.- Parameters
op (Union[np.ndarray, PauliSentence, Operator]) – Input operator
wire (int) – Qubit wire on which to perform Khaneja-Glaser decomposition
- Returns
Whether
op
should go to the even or odd subspace of the decomposition- Return type
bool
See also
See Khaneja and Glaser (2000) for reference.
Example
Let us first perform a single Khaneja-Glaser decomposition of \(\mathfrak{g} = \mathfrak{su}(8)\), i.e. the Lie algebra of all Pauli words on 3 qubits.
>>> g = list(qml.pauli.pauli_group(3)) # u(8) >>> g = g[1:] # remove identity >>> g = [op.pauli_rep for op in g]
We perform the first iteration on the first qubit. We use
cartan_decomp()
.>>> from functools import partial >>> from pennylane.labs.dla import cartan_decomp, khaneja_glaser_involution >>> k0, m0 = cartan_decomp(g, partial(khaneja_glaser_involution, wire=0)) >>> print(f"First iteration, AIII: {len(k0)}, {len(m0)}") First iteration, AIII: 31, 32 >>> assert qml.labs.dla.check_cartan_decomp(k0, m0) # check Cartan commutation relations
We see that we split the 63-dimensional algebra \(\mathfrak{su}(8)\) into a 31-dimensional and a 32-dimensional subspace, and
check_cartan_decomp()
verified that they satisfy the commutation relations of a Cartan decomposition.To expand on this example, we continue process recursively on the \(\mathfrak{k}_0\) subalgebra. Before we can apply the Khaneja-Glaser (type AIII) decomposition a second time, we need to a) remove the \(\mathfrak{u}(1)\) center from \(\mathfrak{k}_0=\mathfrak{su}(4)\oplus\mathfrak{su}(4)\oplus\mathfrak{u}(1)\) to make it semisimple and b) perform a different Cartan decomposition, which is sometimes termed class B.
>>> center_k0 = qml.center(k0, pauli=True) # Compute center of k0 >>> k0_semi = [op for op in k0 if op not in center_k0] # Remove center from k0 >>> print(f"Removed operators {center_k0}, new length: {len(k0_semi)}") Removed operators [1.0 * Z(0)], new length: 30
>>> from pennylane.labs.dla import ClassB >>> k1, m1 = cartan_decomp(k0_semi, partial(ClassB, wire=0)) >>> assert qml.labs.dla.check_cartan_decomp(k1, m1) >>> print(f"First iteration, class B: {len(k1)}, {len(m1)}") First iteration, class B: 15, 15
Now we arrived at the subalgebra \(\mathfrak{k}_1=\mathfrak{su}(4)\) and can perform the next iteration of the recursive decomposition.
>>> k2, m2 = cartan_decomp(k1, partial(khaneja_glaser_involution, wire=1)) >>> assert qml.labs.dla.check_cartan_decomp(k2, m2) >>> print(f"Second iteration, AIII: {len(k2)}, {len(m2)}") Second iteration, AIII: 7, 8
We can follow up on this by removing the center from \(\mathfrak{k}_1\) again, and applying a final class B decomposition:
>>> center_k2 = qml.center(k2, pauli=True) >>> k2_semi = [op for op in k2 if op not in center_k2] >>> print(f"Removed operators {center_k2}, new length: {len(k2_semi)}") Removed operators [1.0 * Z(1)], new length: 6
>>> k3, m3 = cartan_decomp(k2_semi, partial(ClassB, wire=1)) >>> assert qml.labs.dla.check_cartan_decomp(k3, m3) >>> print(f"Second iteration, class B: {len(k3)}, {len(m3)}") Second iteration, class B: 3, 3
This concludes our example of the Khaneja-Glaser recursive decomposition, as we arrived at easy to implement single-qubit operations.