Covariance Matrices#

qnetti.qubit_covariance_matrix_fn(prep_node, meas_wires=None, dev_kwargs={}, qnode_kwargs={})[source]#

Generates a function that evaluates the covariance matrix for local qubit measurements.

Each local qubit is measured in the \(z\)-basis and is preced by an arbitrary qubit rotation as defined in PennyLane, qml.Rot(). Using the joint probability distribution \(\{P(x_i)\}_i\) constructed from the quantum circuit evaluation, we can evaluate the covariance matrix of an \(n\)-qubit system as

\[\begin{split}\text{Cov}(\{P(x_i)\}_{i}) = \begin{pmatrix} \text{Var}(x_1) & \text{Cov}(x_1,x_2) & \dots & \text{Cov}(x_1, x_n) \\ \text{Cov}(x_2, x_1) & \text{Var}(x_2) & \dots & \text{Cov}(x_2, x_n) \\ \vdots & & \ddots & \vdots \\ \text{Cov}(x_n, x_1) & \dots & \text{Cov}(x_n, x_{n-1} & \text{Var}(x_1, x_n) \\ \end{pmatrix}\end{split}\]

where for two random variables \(x_i\) and \(x_j\), the covariance is define \(\text{Cov}(x_i,x_j) = \langle (x_i - \langle x_i \rangle) (x_j - \langle x_j \rangle) \rangle\) and the variance is defined \(\text{Var}(x_i) = \text{Cov}(x_i, x_i)\). Note that the covariance matrix is symmetric because \(\text{Cov}(x_i, x_j) = \text{Cov}(x_j, x_i)\).

Parameters:
  • prep_node (qnetvo.PrepareNode) – A network node that prepares the quantum state to evaluate.

  • meas_wires (list[int]) – The wires to measure when evaluating the covariance matrix. If meas_wires are not specified, all wires in the prepare node are considered. This can be used to ignore ancillary qubits.

  • dev_kwargs (dict) – Keyword arguments passed to the PennyLane device constructor.

  • qnode_kwargs (dict) – Keyword arguments passed to the PennyLane qnode constructor.

Returns:

A function, covariance_matrix(meas_settings) that takes as input a list[float] of length 3 * num_wires.

Return type:

function

qnetti.qubit_covariance_cost_fn(prep_node, meas_wires=None, dev_kwargs={}, qnode_kwargs={})[source]#

Constructs a cost function that, when minimized, yields the maximal distance between the covariance matrix of the prep_node and the origin.

That is, \(\text{Cost}(\Theta) = -\text{Tr}[\text{Cov}(\{P(x_i|\vec{\theta}_i)\}_i)^T \text{Cov}(\{P(x_i)\}_i)^T]\) where the meas_settings are \(\Theta = (\vec{\theta}_i\in\mathbb{R}^3)_{i=1}^n\).

Parameters:
  • prep_node (qnetvo.PrepareNode) – A network node that prepares the quantum state to evaluate.

  • meas_wires (list[int]) – The wires to measure when evaluating the covariance matrix. If meas_wires are not specified, all wires in the prepare node are considered. This can be used to ignore ancillary qubits.

  • qnode_kwargs (dict) – Keyword arguments passed to the PennyLane qnode constructor.

  • dev_kwargs (dict) – Keyword arguments passed to the PennyLane device constructor.

Returns:

A function evaluated as cost(meas_settings) that takes as input a list[float] of length 3 * num_wires.

Return type:

function

qnetti.optimize_covariance_matrix(prep_node, meas_wires=None, dev_kwargs={}, qnode_kwargs={}, **opt_kwargs)[source]#

Optimizes the arbitrary qubit measurements to maximize the distance between the covariance matrix and the origin.

The optimization is performed using the qnetti.optimize() method where the cost function is constructed using the qubit_covariance_cost_fn() method.

Parameters:
  • prep_node (qnetvo.PrepareNode) – A network node that prepares the quantum state to evaluate.

  • meas_wires (list[int]) – The wires to measure when evaluating the covariance matrix. If meas_wires are not specified, all wires in the prepare node are considered. This can be used to ignore ancillary qubits.

  • dev_kwargs (dict) – Keyword arguments passed to the PennyLane device constructor.

  • qnode_kwargs (dict) – Keyword arguments passed to the PennyLane qnode constructor.

  • step_size (float) – The step to take in the direction of steepest descent. Default step_size=0.1.

  • num_steps (int) – The number of iterations of gradient descent to perform. Default num_steps=20.

  • verbose (bool) – If True, the iteration step and cost will be printed every 5 iterations.

Returns:

The first element of the returned tuple is the optimal covariance matrix while the second element is the dictionary returned from the qnetti.optimize() method.

Return type:

tuple[matrix, dict]