polarity(X, Y, kernel, assume_normalized_kernel=False, rescale_class_labels=True, normalize=False)[source]

Polarity of a given kernel function.

For a dataset with feature vectors \(\{x_i\}\) and associated labels \(\{y_i\}\), the polarity of the kernel function \(k\) is given by

\[\operatorname{P}(k) = \sum_{i,j=1}^n y_i y_j k(x_i, x_j)\]

If the dataset is unbalanced, that is if the numbers of datapoints in the two classes \(n_+\) and \(n_-\) differ, rescale_class_labels=True will apply a rescaling according to \(\tilde{y}_i = \frac{y_i}{n_{y_i}}\). This is activated by default and only results in a prefactor that depends on the size of the dataset for balanced datasets.

The keyword argument assume_normalized_kernel is passed to square_kernel_matrix(), for the computation frobenius_inner_product() is used.

  • X (list[datapoint]) – List of datapoints.

  • Y (list[float]) – List of class labels of datapoints, assumed to be either -1 or 1.

  • kernel ((datapoint, datapoint) -> float) – Kernel function that maps datapoints to kernel value.

  • assume_normalized_kernel (bool, optional) – Assume that the kernel is normalized, i.e. the kernel evaluates to 1 when both arguments are the same datapoint.

  • rescale_class_labels (bool, optional) – Rescale the class labels. This is important to take care of unbalanced datasets.

  • normalize (bool) – If True, rescale the polarity to the target_alignment.


The kernel polarity.

Return type



Consider a simple kernel function based on AngleEmbedding:

dev = qml.device('default.qubit')
def circuit(x1, x2):
    qml.templates.AngleEmbedding(x1, wires=dev.wires)
    qml.adjoint(qml.templates.AngleEmbedding)(x2, wires=dev.wires)
    return qml.probs(wires=dev.wires)

kernel = lambda x1, x2: circuit(x1, x2)[0]

We can then compute the polarity on a set of 4 (random) feature vectors X with labels Y via

>>> X = np.random.random((4, 2))
>>> Y = np.array([-1, -1, 1, 1])
>>> qml.kernels.polarity(X, Y, kernel)
tensor(0.04361349, requires_grad=True)