• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

qiskit-community / qiskit-machine-learning / 15525613486

06 Jun 2025 05:24PM UTC coverage: 90.865% (+0.04%) from 90.821%
15525613486

push

github

web-flow
Deprecate BlueprintCircuit based circuit usage (#945)

* Deprecate BlueprintCircuit based circuit usage

* Add greek letter pi (π)

* Update qiskit_machine_learning/circuit/library/raw_feature_vector.py

Co-authored-by: Edoardo Altamura <38359901+edoaltamura@users.noreply.github.com>

* Update qiskit_machine_learning/kernels/base_kernel.py

Co-authored-by: Edoardo Altamura <38359901+edoaltamura@users.noreply.github.com>

---------

Co-authored-by: Edoardo Altamura <38359901+edoaltamura@users.noreply.github.com>

45 of 46 new or added lines in 8 files covered. (97.83%)

35 existing lines in 5 files now uncovered.

4526 of 4981 relevant lines covered (90.87%)

0.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.0
/qiskit_machine_learning/kernels/base_kernel.py
1
# This code is part of a Qiskit project.
2
#
3
# (C) Copyright IBM 2022, 2025.
4
#
5
# This code is licensed under the Apache License, Version 2.0. You may
6
# obtain a copy of this license in the LICENSE.txt file in the root directory
7
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8
#
9
# Any modifications or derivative works of this code must retain this
10
# copyright notice, and modified files need to carry a notice indicating
11
# that they have been altered from the originals.
12

13
"""Base kernel"""
14

15
from __future__ import annotations
1✔
16

17
from abc import abstractmethod, ABC
1✔
18

19
import numpy as np
1✔
20
from qiskit import QuantumCircuit
1✔
21
from qiskit.circuit.library import ZZFeatureMap
1✔
22

23
from ..utils.deprecation import issue_deprecation_msg
1✔
24

25

26
class BaseKernel(ABC):
1✔
27
    r"""
28
    An abstract definition of the quantum kernel interface.
29

30
    The general task of machine learning is to find and study patterns in data. For many
31
    algorithms, the datapoints are better understood in a higher dimensional feature space,
32
    through the use of a kernel function:
33

34
    .. math::
35

36
        K(x, y) = \langle f(x), f(y)\rangle.
37

38
    Here K is the kernel function, x, y are n dimensional inputs. f is a map from n-dimension
39
    to m-dimension space. :math:`\langle x, y \rangle` denotes the dot product.
40
    Usually m is much larger than n.
41

42
    The quantum kernel algorithm calculates a kernel matrix, given datapoints x and y and feature
43
    map f, all of n dimension. This kernel matrix can then be used in classical machine learning
44
    algorithms such as support vector classification, spectral clustering or ridge regression.
45
    """
46

47
    def __init__(self, *, feature_map: QuantumCircuit = None, enforce_psd: bool = True) -> None:
1✔
48
        """
49
        Args:
50
            feature_map: Parameterized circuit to be used as the feature map. If ``None`` is given,
51
                :class:`~qiskit.circuit.library.ZZFeatureMap` is used with two qubits. If there's
52
                a mismatch in the number of qubits of the feature map and the number of features
53
                in the dataset, then the kernel will try to adjust the feature map to reflect the
54
                number of features.
55
            enforce_psd: Project to closest positive semidefinite matrix if ``x = y``.
56
                Default ``True``.
57
        """
58
        if feature_map is None:
1✔
59
            # Note: when removing None it should be done in all the derived classes as well
60
            # along with an appropriate update to the docstring in each case
61
            issue_deprecation_msg(
1✔
62
                msg="Passing None as a feature_map is deprecated",
63
                version="0.9.0",
64
                remedy="Pass a feature map with the required number of qubits to match "
65
                "the features. Adjusting the number of qubits after instantiation will be "
66
                "removed from Qiskit as circuits based on BlueprintCircuit, "
67
                "like ZZFeatureMap to which this defaults, which could do this, "
68
                "have been deprecated.",
69
                period="4 months",
70
            )
71
            feature_map = ZZFeatureMap(2)
1✔
72

73
        self._num_features = feature_map.num_parameters
1✔
74
        self._feature_map = feature_map
1✔
75
        self._enforce_psd = enforce_psd
1✔
76

77
    @abstractmethod
1✔
78
    def evaluate(self, x_vec: np.ndarray, y_vec: np.ndarray | None = None) -> np.ndarray:
1✔
79
        r"""
80
        Construct kernel matrix for given data.
81

82
        If y_vec is None, self inner product is calculated.
83

84
        Args:
85
            x_vec: 1D or 2D array of datapoints, NxD, where N is the number of datapoints,
86
                D is the feature dimension
87
            y_vec: 1D or 2D array of datapoints, MxD, where M is the number of datapoints,
88
                D is the feature dimension
89

90
        Returns:
91
            2D matrix, NxM
92
        """
UNCOV
93
        raise NotImplementedError()
×
94

95
    @property
1✔
96
    def feature_map(self) -> QuantumCircuit:
1✔
97
        """Returns the feature map of this kernel."""
98
        return self._feature_map
1✔
99

100
    @property
1✔
101
    def num_features(self) -> int:
1✔
102
        """Returns the number of features in this kernel."""
103
        return self._num_features
1✔
104

105
    @property
1✔
106
    def enforce_psd(self) -> bool:
1✔
107
        """
108
        Returns ``True`` if the kernel matrix is required to project to the closest positive
109
        semidefinite matrix.
110
        """
111
        return self._enforce_psd
1✔
112

113
    def _validate_input(
1✔
114
        self, x_vec: np.ndarray, y_vec: np.ndarray | None
115
    ) -> tuple[np.ndarray, np.ndarray | None]:
116
        x_vec = np.asarray(x_vec)
1✔
117

118
        if x_vec.ndim > 2:
1✔
119
            raise ValueError("x_vec must be a 1D or 2D array")
1✔
120

121
        if x_vec.ndim == 1:
1✔
122
            x_vec = np.reshape(x_vec, (-1, len(x_vec)))
1✔
123

124
        if x_vec.shape[1] != self._num_features:
1✔
125
            # before raising an error we try to adjust the feature map
126
            # to the required number of qubit.
127
            try:
1✔
128
                self._feature_map.num_qubits = x_vec.shape[1]
1✔
129
            except AttributeError as a_e:
1✔
130
                raise ValueError(
1✔
131
                    f"x_vec and class feature map have incompatible dimensions.\n"
132
                    f"x_vec has {x_vec.shape[1]} dimensions, "
133
                    f"but feature map has {self._feature_map.num_parameters}."
134
                ) from a_e
135

136
        if y_vec is not None:
1✔
137
            y_vec = np.asarray(y_vec)
1✔
138

139
            if y_vec.ndim == 1:
1✔
140
                y_vec = np.reshape(y_vec, (-1, len(y_vec)))
1✔
141

142
            if y_vec.ndim > 2:
1✔
143
                raise ValueError("y_vec must be a 1D or 2D array")
1✔
144

145
            if y_vec.shape[1] != x_vec.shape[1]:
1✔
146
                raise ValueError(
1✔
147
                    "x_vec and y_vec have incompatible dimensions.\n"
148
                    f"x_vec has {x_vec.shape[1]} dimensions, but y_vec has {y_vec.shape[1]}."
149
                )
150

151
        return x_vec, y_vec
1✔
152

153
    def _make_psd(self, kernel_matrix: np.ndarray) -> np.ndarray:
1✔
154
        r"""
155
        Find the closest positive semi-definite approximation to a symmetric kernel matrix.
156
        The (symmetric) matrix should always be positive semi-definite by construction,
157
        but this can be violated in case of noise, such as sampling noise.
158

159
        Args:
160
            kernel_matrix: Symmetric 2D array of the kernel entries.
161

162
        Returns:
163
            The closest positive semi-definite matrix.
164
        """
165
        w, v = np.linalg.eig(kernel_matrix)
1✔
166
        m = v @ np.diag(np.maximum(0, w)) @ v.transpose()
1✔
167
        return m.real
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc