displacement_operator

Graph.displacement_operator(alpha, dimension, offset=0, *, name=None)

Create a displacement operator (or a batch of them).

Parameters
  • alpha (number or list[number] or np.ndarray) – A number \(\alpha\) that characterizes the displacement operator. You can also pass a list or 1D array of numbers to generate a batch of displacement operators.

  • dimension (int) – The size of the truncated Fock space. By default, the Fock space is truncated as [0, dimension). If non-zero offset is passed, the space is then truncated at [offset, dimension + offset).

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

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

Returns

A tensor representing the displacement operator. The shape is 2D if there is no batch in alpha, otherwise 3D where the first axis is the batch dimension.

Return type

Tensor

See also

annihilation_operator()

Create an annihilation operator in the truncated Fock space.

coherent_state()

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

creation_operator()

Create a creation operator in the truncated Fock space.

fock_state()

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

number_operator()

Create a number operator in the truncated Fock space.

squeeze_operator()

Create a squeeze operator (or a batch of them) in the truncated Fock space.

Notes

The displacement operator is defined as:

\[D(\alpha) = \exp(\alpha \hat{a}^\dagger - \alpha^\ast \hat{a})\]

where \(\hat{a}\) and \(\hat{a}^\dagger\) are the annihilation and creation operators respectively.

This operation uses truncated annihilation/creation operators to calculate the displacement operator. As such, for a nonzero offset, generating a coherent state by applying the displacement operator to a Fock state will not generate the same result as directly using the coherent_state operation, which uses a full operator and then truncates the resulting state. As the energy levels increase, however, the two coherent states will increasingly agree.

For more information about the displacement operator, see Displacement operator on Wikipedia.

Examples

Create a displacement operator.

>>> graph.displacement_operator(1j, 2, name="displacement")
<Tensor: name="displacement", operation_name="displacement_operator", shape=(2, 2)>
>>> result = qctrl.functions.calculate_graph(graph=graph, output_node_names=["displacement"])
>>> result.output["displacement"]["value"]
array([[ 5.40302306e-01+0.00000000e+00j, -1.03050475e-16+8.41470985e-01j],
       [ 5.55111512e-17+8.41470985e-01j,  5.40302306e-01+6.61679489e-17j]])

Create a batch of displacement operators.

>>> graph.displacement_operator([1j, 3], 2, name="displacement_batch")
<Tensor: name="displacement_batch", operation_name="displacement_operator", shape=(2, 2, 2)>
>>> result = qctrl.functions.calculate_graph(
...     graph=graph, output_node_names=["displacement_batch"]
... )
>>> result.output["displacement_batch"]["value"]
array([[[ 5.40302306e-01+0.00000000e+00j, -1.11022302e-16+8.41470985e-01j],
        [ 5.55111512e-17+8.41470985e-01j, 5.40302306e-01+1.11022302e-16j]],
       [[-9.89992497e-01+0.00000000e+00j, -1.41120008e-01+0.00000000e+00j],
        [ 1.41120008e-01+0.00000000e+00j, -9.89992497e-01+0.00000000e+00j]]])