QuadP

class hybridlane.ops.qumode.QuadP(wires)

Bases: pennylane.QuadP, hybridlane.ops.mixins.Spectral, hybridlane.ops.mixins.FockRepresentation

Momentum operator \(\hat{p}\)

The continuous-variable momentum operator is defined by its action on momentum “eigenstates” \(\ket{p}\) as

\[\hat{p} \ket{p} = p \ket{p}.\]

Details:

  • Number of wires: 1

  • Wire arguments: [qumode]

  • Number of parameters: 0

  • Number of dimensions per parameter: None

It has a representation in the Fock basis defined in standard units with \(\hbar = 1\)

>>> P.compute_fock_matrix((5,))
array([[0.+0.j    , 0.+0.7071j, 0.+0.j    , 0.+0.j    , 0.+0.j    ],
       [0.-0.7071j, 0.+0.j    , 0.+1.j    , 0.+0.j    , 0.+0.j    ],
       [0.+0.j    , 0.-1.j    , 0.+0.j    , 0.+1.2247j, 0.+0.j    ],
       [0.+0.j    , 0.+0.j    , 0.-1.2247j, 0.+0.j    , 0.+1.4142j],
       [0.+0.j    , 0.+0.j    , 0.+0.j    , 0.-1.4142j, 0.+0.j    ]])
property natural_basis
static compute_diagonalizing_gates(wires)

Sequence of gates that diagonalize the operator in the computational basis (static method).

Given the eigendecomposition \(O = U \Sigma U^{\dagger}\) where \(\Sigma\) is a diagonal matrix containing the eigenvalues, the sequence of diagonalizing gates implements the unitary \(U^{\dagger}\).

The diagonalizing gates rotate the state into the eigenbasis of the operator.

See also

diagonalizing_gates().

Parameters:
  • params (list) – trainable parameters of the operator, as stored in the parameters attribute

  • wires (Iterable[Any], Wires) – wires that the operator acts on

  • hyperparams (dict) – non-trainable hyperparameters of the operator, as stored in the hyperparameters attribute

Returns:

list of diagonalizing gates

Return type:

list[.Operator]

static compute_decomposition(*params, wires=None, **hyperparameters)

Representation of the operator as a product of other operators (static method).

\[O = O_1 O_2 \dots O_n.\]

Note

Operations making up the decomposition should be queued within the compute_decomposition method.

See also

decomposition().

Parameters:
  • *params (list) – trainable parameters of the operator, as stored in the parameters attribute

  • wires (Iterable[Any], Wires) – wires that the operator acts on

  • **hyperparams (dict) – non-trainable hyperparameters of the operator, as stored in the hyperparameters attribute

  • hyperparameters (dict[str, Any])

Returns:

decomposition of the operator

Return type:

list[Operator]

__repr__()

Constructor-call-like representation.

static compute_fock_matrix(wire_dims)

Computes the Fock matrix representation of the gate

This method should be implemented by any gate to define its representation in the Fock basis. It should return a dense matrix of shape (d, d), where \(d = \prod_i \text{wire\_dims}_i\) is the total dimension of the Hilbert space of the gate.

Details:

The wire_dims argument provides the dimension of each wire in the canonical wire order, the same order as self.wires.

An example using the CR gate, which has wire types [qubit, qumode], using dimension 2 for the qubit and a dimension of 3 for the qumode:

>>> hl.CR.compute_fock_matrix((2, 3), 0.5)
array([[1.    +0.j    , 0.    +0.j    , 0.    +0.j    , 0.    +0.j    ,
        0.    +0.j    , 0.    +0.j    ],
       [0.    +0.j    , 0.9689-0.2474j, 0.    +0.j    , 0.    +0.j    ,
        0.    +0.j    , 0.    +0.j    ],
       [0.    +0.j    , 0.    +0.j    , 0.8776-0.4794j, 0.    +0.j    ,
        0.    +0.j    , 0.    +0.j    ],
       [0.    +0.j    , 0.    +0.j    , 0.    +0.j    , 1.    -0.j    ,
        0.    -0.j    , 0.    -0.j    ],
       [0.    +0.j    , 0.    +0.j    , 0.    +0.j    , 0.    -0.j    ,
        0.9689+0.2474j, 0.    -0.j    ],
       [0.    +0.j    , 0.    +0.j    , 0.    +0.j    , 0.    -0.j    ,
        0.    -0.j    , 0.8776+0.4794j]])

If parameters are tensors of a deep learning framework, the returned matrix should also be of the same framework so that it can be used in differentiable computations. If the gate is nonparametric, this should return a NumPy ndarray.

Using the same example as above with a JAX array as a parameter, the resulting matrix is a differentiable JAX Array:

>>> hl.CR.compute_fock_matrix((2, 3), jnp.array(0.5))
Array([[1.    +0.j    , 0.    +0.j    , 0.    +0.j    , 0.    +0.j    ,
        0.    +0.j    , 0.    +0.j    ],
       [0.    +0.j    , 0.9689-0.2474j, 0.    +0.j    , 0.    +0.j    ,
        0.    +0.j    , 0.    +0.j    ],
       [0.    +0.j    , 0.    +0.j    , 0.8776-0.4794j, 0.    +0.j    ,
        0.    +0.j    , 0.    +0.j    ],
       [0.    +0.j    , 0.    +0.j    , 0.    +0.j    , 1.    -0.j    ,
        0.    -0.j    , 0.    -0.j    ],
       [0.    +0.j    , 0.    +0.j    , 0.    +0.j    , 0.    -0.j    ,
        0.9689+0.2474j, 0.    -0.j    ],
       [0.    +0.j    , 0.    +0.j    , 0.    +0.j    , 0.    -0.j    ,
        0.    -0.j    , 0.8776+0.4794j]], dtype=complex128)
Parameters:
  • wire_dims (tuple[int, Ellipsis]) – The dimension of each wire in the order of self.wires

  • *params – The parameters of the gate

  • **hyperparams – The hyperparameters of the gate

Returns:

The Fock dense matrix representation of the gate, matching the interface of the parameters.

Return type:

numpy.ndarray