qml.matrix¶
-
matrix
(op, *, wire_order=None)[source]¶ The matrix representation of an operation or quantum circuit.
- Parameters
op (Operator, pennylane.QNode, QuantumTape, or Callable) – An operator, quantum node, tape, or function that applies quantum operations.
wire_order (Sequence[Any], optional) – Order of the wires in the quantum circuit. Defaults to the order in which the wires appear in the quantum function.
- Returns
Function which accepts the same arguments as the QNode or quantum function. When called, this function will return the unitary matrix in the appropriate autodiff framework (Autograd, TensorFlow, PyTorch, JAX) given its parameters.
- Return type
tensor_like or function
Example
Given an instantiated operator,
qml.matrix
returns the matrix representation:>>> op = qml.RX(0.54, wires=0) >>> qml.matrix(op) [[0.9637709+0.j 0. -0.26673144j] [0. -0.26673144j 0.9637709+0.j ]]
It can also be used in a functional form:
>>> x = torch.tensor(0.6, requires_grad=True) >>> matrix_fn = qml.matrix(qml.RX) >>> matrix_fn(x, wires=0) tensor([[0.9553+0.0000j, 0.0000-0.2955j], [0.0000-0.2955j, 0.9553+0.0000j]], grad_fn=<AddBackward0>)
In its functional form, it is fully differentiable with respect to gate arguments:
>>> loss = torch.real(torch.trace(matrix_fn(x, wires=0))) >>> loss.backward() >>> x.grad tensor(-0.5910)
This operator transform can also be applied to QNodes, tapes, and quantum functions that contain multiple operations; see Usage Details below for more details.
Usage Details
qml.matrix
can also be used with QNodes, tapes, or quantum functions that contain multiple operations.Consider the following quantum function:
def circuit(theta): qml.RX(theta, wires=1) qml.PauliZ(wires=0)
We can use
qml.matrix
to generate a new function that returns the unitary matrix corresponding to the functioncircuit
:>>> matrix_fn = qml.matrix(circuit) >>> theta = np.pi / 4 >>> matrix_fn(theta) array([[ 0.92387953+0.j, 0.+0.j , 0.-0.38268343j, 0.+0.j], [ 0.+0.j, -0.92387953+0.j, 0.+0.j, 0. +0.38268343j], [ 0. -0.38268343j, 0.+0.j, 0.92387953+0.j, 0.+0.j], [ 0.+0.j, 0.+0.38268343j, 0.+0.j, -0.92387953+0.j]])
Note that since
wire_order
was not specified, the default order[1, 0]
forcircuit
was used, and the unitary matrix corresponds to the operation \(R_X(\theta)\otimes Z\). To obtain the matrix for \(Z\otimes R_X(\theta)\), specifywire_order=[0, 1]
in the function call:>>> matrix = qml.matrix(circuit, wire_order=[0, 1])
You can also get the unitary matrix for operations on a subspace of a larger Hilbert space. For example, with the same function
circuit
andwire_order=["a", 0, "b", 1]
you obtain the \(16\times 16\) matrix for the operation \(I\otimes Z\otimes I\otimes R_X(\theta)\).This unitary matrix can also be used in differentiable calculations. For example, consider the following cost function:
def circuit(theta): qml.RX(theta, wires=1) qml.PauliZ(wires=0) qml.CNOT(wires=[0, 1]) def cost(theta): matrix = qml.matrix(circuit)(theta) return np.real(np.trace(matrix))
Since this cost function returns a real scalar as a function of
theta
, we can differentiate it:>>> theta = np.array(0.3, requires_grad=True) >>> cost(theta) 1.9775421558720845 >>> qml.grad(cost)(theta) -0.14943813247359922