wigner_transform

Graph.wigner_transform(density_matrix, position, momentum, offset=0, *, name=None)

Transform a density matrix into a Wigner function (or a batch of them).

Parameters
  • density_matrix (Tensor or np.ndarray) – The density matrix \(\rho\) in the Fock basis. Must be of shape (..., D, D).

  • position (list or tuple or np.ndarray) – The dimensionless position vector \(q\). Must be a 1D array of shape (L,).

  • momentum (list or tuple or np.ndarray) – The dimensionless momentum vector \(p\). Must be a 1D array of shape (K,).

  • offset (int, optional) – The lowest Fock state. Defaults to 0.

  • name (str, optional) – The name of the node.

Returns

The Wigner function with shape (..., L, K).

Return type

Tensor

Warning

This function currently does not support calculating the gradient with respect to its inputs. Therefore, it cannot be used in a graph for a calculate_optimization or calculate_stochastic_optimization call, which will raise a RuntimeError. Please use gradient-free optimization if you want to perform an optimization task with this function. You can learn more about it in the How to optimize controls using gradient-free optimization user guide.

See also

coherent_state

Create a coherent state (or a batch of them).

fock_state

Create a Fock state (or a batch of them).

Notes

The Wigner transform is defined as:

\[W(q,p) = \frac{1}{2\pi} \int_{-\infty}^{\infty} \mathrm{e}^{\mathrm{i}sp} \langle q - s/2| \rho | q + s/2 \rangle \mathrm{d}s .\]

For more information about the Wigner transform, see Wigner function on Wikipedia.

Examples

Create a Wigner function.

>>> graph.wigner_transform(np.array([[1]]), [-1, 0, 1], np.zeros(1), name="wigner")
<Tensor: name="wigner", operation_name="wigner_transform", shape=(3, 1)>
>>> result = qctrl.functions.calculate_graph(graph=graph, output_node_names=["wigner"])
>>> result.output["wigner"]["value"]
array([[ 0.11709966+0.j],
       [ 0.31830989+0.j],
       [ 0.11709966+0.j]])

Create a batch of Wigner function.

>>> graph.wigner_transform(
        np.array([[[1, 0], [0, 0]], [[0, 0], [0, 1]]]),
        np.array([-1, 0, 1]),
        np.zeros(1),
        name="wigner_batch",
    )
<Tensor: name="wigner_batch", operation_name="wigner_transform", shape=(2, 3, 1)>
>>> result = qctrl.functions.calculate_graph(
...     graph=graph, output_node_names=["wigner_batch"]
... )
>>> result.output["wigner_batch"]["value"]
array([[[ 0.11709966+0.j],
        [ 0.31830989+0.j],
        [ 0.11709966+0.j]],
       [[ 0.11709966+0.j],
        [-0.31830989+0.j],
        [ 0.11709966+0.j]]])