Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
a32645d
Auto Commit
Siddharthgolecha Aug 6, 2025
58a92c3
Auto Commit tests
Siddharthgolecha Aug 6, 2025
31a48a5
Making lint, style changes with some migration fixes
Siddharthgolecha Aug 7, 2025
6ff8bf9
Merge branch 'main' into migrate-to-2.0
Siddharthgolecha Aug 7, 2025
4b2122c
Merge branch 'main' into migrate-to-2.0
OkuyanBoga Sep 3, 2025
37799be
Fix copyright
edoaltamura Sep 3, 2025
0278edc
Fix copyright
edoaltamura Sep 3, 2025
9683908
Fix copyright
edoaltamura Sep 3, 2025
58edda6
Fix copyright
edoaltamura Sep 3, 2025
6b85ef1
Fix copyright
edoaltamura Sep 3, 2025
0a03287
Fix copyright
edoaltamura Sep 3, 2025
08e15f5
'QuantumCircuit' objects implement '__hash__' deterministically
edoaltamura Sep 3, 2025
34fb82c
Fix lint
edoaltamura Sep 3, 2025
379f3e4
Merge branch 'main' into migrate-to-2.0
OkuyanBoga Sep 3, 2025
5e903ea
Lower scipy version requirement
edoaltamura Sep 3, 2025
b9be5bc
Merge branch 'qiskit-community:main' into migrate-to-2.0
Siddharthgolecha Sep 8, 2025
5449cdd
Relax scipy version
edoaltamura Sep 15, 2025
34d77d9
Fix mypy
edoaltamura Sep 15, 2025
5ae415f
Update `qiskit.primitives.StatevectorSampler`
edoaltamura Sep 15, 2025
4c79bdb
Update `qiskit.primitives.StatevectorSampler`
edoaltamura Sep 15, 2025
92554a5
Fix adjust_num_qubits.py
edoaltamura Sep 15, 2025
460d0bb
Fix mypy and lint
edoaltamura Sep 15, 2025
01c3bc2
Partially update type hinting
edoaltamura Sep 15, 2025
b8125c9
Update copyright and spelling
edoaltamura Sep 15, 2025
2759bb7
Implement circuit hashing.
edoaltamura Oct 6, 2025
4552959
Fix make checks.
edoaltamura Oct 6, 2025
0621e3f
Fix various numerical tests.
edoaltamura Oct 6, 2025
1a20e69
Fix neural networks tests. Options are outstanding.
edoaltamura Oct 6, 2025
aea918c
Fix neural networks tests + CI checks.
edoaltamura Oct 6, 2025
710427b
Fix copyright
edoaltamura Oct 6, 2025
9bb7e10
Fix for samplerv2 related unittests
OkuyanBoga Nov 3, 2025
fa5fa69
Fixed unit tests for SamplerV2
OkuyanBoga Nov 3, 2025
fe4736b
Merge branch 'main' into migrate-to-2.0
edoaltamura Nov 11, 2025
f2c0e95
Patch mismatching parameter in the gradients lincomb (to be revisited).
edoaltamura Nov 11, 2025
681aae8
Updated type hinting. Mypy/Lint tests to be fixed.
edoaltamura Nov 11, 2025
0e5326e
Updated type hinting (pt2). Mypy/Lint tests to be fixed.
edoaltamura Nov 11, 2025
9b86831
Updated copyright
edoaltamura Nov 11, 2025
88472f4
Merge branch 'main' into migrate-to-2.0
edoaltamura Nov 24, 2025
3b8cfb1
Merge branch 'main' into migrate-to-2.0
edoaltamura Nov 25, 2025
c685d09
Fixed kernel tests for >2.0
OkuyanBoga Dec 17, 2025
0223a6f
Merge branch 'main' into migrate-to-2.0
OkuyanBoga Dec 17, 2025
d70fc4a
Fixed v1 to v2 arg issue for test_spsa.
OkuyanBoga Dec 17, 2025
4a47f18
Fix None feature-map case. Update lint, copyright, spelling, and form…
edoaltamura Dec 17, 2025
82f33a4
Silence some mypy checks in primitives.
edoaltamura Dec 17, 2025
6af0551
Consolidate feature map requirements in fidelity base kernel with doc…
edoaltamura Dec 18, 2025
ae0b8bf
Deprecated RawFeatureVector
OkuyanBoga Dec 18, 2025
b7b050c
Deprecated QNNCircuit
OkuyanBoga Dec 18, 2025
e798982
Format with black
edoaltamura Dec 18, 2025
5206322
Attempt to fix html docs
edoaltamura Dec 18, 2025
d1f7177
Fix exception handling
OkuyanBoga Dec 18, 2025
8a23e74
Merge branch 'migrate-to-2.0' of github.com:Siddharthgolecha/qiskit-m…
OkuyanBoga Dec 18, 2025
d8ef82c
Update QMLSampler docs
edoaltamura Dec 18, 2025
e2b2ed5
Add primitives in API docs
edoaltamura Dec 18, 2025
40583e3
Format with black
edoaltamura Dec 18, 2025
278ef27
Fix headers
edoaltamura Dec 18, 2025
a592d05
Update 'QNNCircuit'->'qnn_circuit' in descriptions
edoaltamura Dec 18, 2025
f6ea5c8
Set exact primitives on TorchConnector tests
edoaltamura Dec 18, 2025
48da2bd
Set exact primitives on TorchConnector tests
edoaltamura Dec 18, 2025
be40488
Fix formatting
edoaltamura Dec 18, 2025
96ebcc8
Relaxation of hybrid_batch_gradient test due to stochasticity from es…
OkuyanBoga Dec 19, 2025
a5f5089
Merge branch 'main' into migrate-to-2.0
OkuyanBoga Dec 19, 2025
df4c3a5
Merge branch 'main' into migrate-to-2.0
edoaltamura Dec 19, 2025
434f4f9
Added QMLEstimator
OkuyanBoga Dec 19, 2025
144213a
Add tests for QML Primitives
OkuyanBoga Dec 19, 2025
6b62fee
Fix formatting
edoaltamura Dec 20, 2025
7f81828
Add docstrings and formatting
edoaltamura Dec 20, 2025
db02ca9
Fix spell
edoaltamura Dec 20, 2025
e66e6c9
Fix mypy
edoaltamura Dec 20, 2025
a9bff7d
Consolidate QMLEstimator as Estimator in unit tests
edoaltamura Dec 20, 2025
2e9c00e
Fix mypy issue by strong typing and casting QMLSampler aux classes
edoaltamura Dec 21, 2025
3847e3f
Add documentation about QML primitives
edoaltamura Dec 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion .pylintdict
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ cerezo
chernoff
choi
chuang
cinds
circ
ClassicalRegister
clbit
clbits
clopper
Expand All @@ -79,7 +82,9 @@ codebase
codec
coeffs
colin
coles
combinatorial
computable
concha
config
configs
Expand Down Expand Up @@ -130,6 +135,7 @@ doi
dok
dp
dt
dtype
eda
edaspy
Expand All @@ -147,6 +153,7 @@ eigenvectors
einstein
einsum
elif
encodings
endian
entangler
enum
Expand All @@ -161,6 +168,7 @@ evolutions
evolutionsynthesis
evolver
evolvers
ExactProbArray
excitations
exponentials
exponentiated
Expand Down Expand Up @@ -245,6 +253,7 @@ inlier
inplace
instantiation
instantiations
integrations
interatomic
interdependencies
ints
Expand Down Expand Up @@ -290,6 +299,7 @@ len
leq
lin
linalg
loc
loglik
loglikelihood
lov
Expand Down Expand Up @@ -336,6 +346,7 @@ msg
multiclass
multinomial
multioutput
multipartite
mxd
mypy
nabla
Expand All @@ -358,6 +369,7 @@ nfevs
nft
nielsen
njev
nlocal
nlopt
nn
noancilla
Expand Down Expand Up @@ -427,6 +439,7 @@ preprint
preprocess
preprocesses
priori
probs
proj
ps
pvqd
Expand All @@ -451,8 +464,10 @@ qgans
qgt
qgt's
qgts
qinds
qiskit
qiskit's
qml
qn
qnn
qnspsa
Expand Down Expand Up @@ -495,7 +510,10 @@ RuntimeError
rx
ry
rz
qpy
samplerqnn
SamplerPub
SamplerPubLike
sanjiv
sashank
satisfiability
Expand All @@ -512,7 +530,7 @@ scipy
sdg
seealso
semidefinite
sep
sep
seperate
seperable
serializable
Expand Down Expand Up @@ -606,6 +624,7 @@ unscaled
unsymmetric
utf
utils
uuid
varadarajan
variational
vatan
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ The Qiskit Machine Learning framework aims to be:
### Kernel-based methods

The [`FidelityQuantumKernel`](https://qiskit-community.github.io/qiskit-machine-learning/stubs/qiskit_machine_learning.kernels.QuantumKernel.html#qiskit_machine_learning.kernels.FidelityQuantumKernel)
class uses the [`Fidelity`](https://qiskit-community.github.io/qiskit-machine-learning/stubs/qiskit_machine_learning.state_fidelities.BaseStateFidelity.html))
class uses the [`Fidelity`](https://qiskit-community.github.io/qiskit-machine-learning/stubs/qiskit_machine_learning.state_fidelities.BaseStateFidelity.html)
algorithm. It computes kernel matrices for datasets and can be combined with a Quantum Support Vector Classifier ([`QSVC`](https://qiskit-community.github.io/qiskit-machine-learning/stubs/qiskit_machine_learning.algorithms.QSVC.html#qiskit_machine_learning.algorithms.QSVC))
or a Quantum Support Vector Regressor ([`QSVR`](https://qiskit-community.github.io/qiskit-machine-learning/stubs/qiskit_machine_learning.algorithms.QSVR.html#qiskit_machine_learning.algorithms.QSVR))
to solve classification or regression problems respectively. It is also compatible with classical kernel-based machine learning algorithms.
Expand Down
188 changes: 188 additions & 0 deletions docs/apidocs/qiskit_machine_learning.primitives.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
.. _qiskit-machine-learning-primitives:

.. automodule:: qiskit_machine_learning.primitives
:no-members:
:no-inherited-members:
:no-special-members:


Qiskit Machine Learning (here QML for short) are thin wrappers around Qiskit's
Statevector primitives (V2). In addition to these, they provide an *exact* mode of
execution, which computes the full statevector, rather than randomly sampling it. This
mimics the behavior of early V1 statevector primitives, providing a familiar
Qiskit *V2 primitives* interface (PUB-based execution) for reliable and reproducible prototyping
of small problem instances.

QML primitives are built to satisfy the following needs:

* Provide a stable, QML-centric API for internal components (QNNs, kernels, gradients);
* Offer a fully deterministic **exact** simulation for unit tests and reference results;
* Optionally emulate **shot noise** in local simulation by delegating to Qiskit's statevector
primitives.

Why introduce these wrappers?
-----------------------------

Qiskit's V2 primitives ecosystem standardizes execution around Primitive Unified Blocs (PUBs) and
structured result objects. This infrastructure does not provide a direct way to compute the full
statevector result without shot noise, which some unit tests and prototyping tasks benefit from.
QML primitives address this needs by allowing the exact simulation mode directly, or acting as a
light wrapper around Qiskit Statevector (V2) primitives when sampling with shot noise.

Execution modes
---------------

Exact mode (deterministic)
^^^^^^^^^^^^^^^^^^^^^^^^^^

In *exact mode*, QML computes results analytically from a statevector representation.
This is primarily intended for tests and reference calculations:

* Deterministic outputs (no sampling stochasticity);
* Fast for small circuits, but the cost scales exponentially with the number of qubits;
* Ideal for verifying gradients / batching logic.

Statevector primitive fallback (optional shot noise)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When exact mode is disabled (or not applicable), QML delegates to Qiskit's Statevector primitives.
This supports local statevector simulation and can emulate shot noise when shots are requested.


Examples of exact simulation and with shot noise
------------------------------------------------

.. code-block:: python

# QMLEstimator example
from qiskit.circuit import QuantumCircuit, Parameter
from qiskit_machine_learning.primitives import QMLEstimator

require_exact: bool = True

# Build circuit + observable...
# For exact methods, circuits should be small (10-20 qubits or less) because of the
# exponential computational cost.

if require_exact:
# Setting precision to 0 triggers the `exact` mode, performing the calculation with
# the estimator routines implemented in Qiskit Machine Learning
est = QMLEstimator(default_precision=0)
else:
# Setting precision to a float greater than 0 triggers the `shot-noise` mode, invoking
# StatevectorEstimator directly from `qiskit.primitives`.
est = QMLEstimator(default_precision=0.1)

result = est.run([(qc, [obs], [theta_values])]).result()

# ======================================================

# QMLSampler example
from qiskit_machine_learning.primitives import QMLSampler

if require_exact:
# Setting `shots=None` triggers the `exact` mode, performing the calculation with
# the sampler routines implemented in Qiskit Machine Learning
sampler = QMLSampler(shots=None)
else:
# Setting a finite integer number of shots, instead, invokes StatevectorSampler from Qiskit
sampler = QMLSampler(shots=10_000)

result = sampler.run([(qc, [param_values])]).result()


Executing workloads on IBM quantum hardware
-------------------------------------------

QML primitives do not support hardware execution, as they are intended for classical simulation
of small circuit prototypes. To run workloads on IBM quantum computers, use the primitives
provided in the ``qiskit-ibm-runtime`` library.

Here, we provide an example usage of kernel alignment (based on the
`08_quantum_kernel_trainer.ipynb <docs/tutorials/08_quantum_kernel_trainer.ipynb>`_ tutorial)
using the Qiskit IBM Runtime primitives.


.. code-block:: bash

pip install qiskit-ibm-runtime

.. code-block:: python

import numpy as np
from sklearn import metrics

from qiskit import QuantumCircuit
from qiskit.circuit import ParameterVector
from qiskit.circuit.library import zz_feature_map
from qiskit_machine_learning.optimizers import SPSA
from qiskit_machine_learning.kernels import TrainableFidelityQuantumKernel
from qiskit_machine_learning.kernels.algorithms import QuantumKernelTrainer
from qiskit_machine_learning.algorithms import QSVC
from qiskit_machine_learning.datasets import ad_hoc_data

from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService, Session, SamplerV2 as Sampler

# 1. Dataset (same as tutorial)
adhoc_dimension = 2
X_train, y_train, X_test, y_test, _ = ad_hoc_data(
training_size=12,
test_size=6,
n=adhoc_dimension,
gap=0.3,
plot_data=False,
one_hot=False,
include_sample_total=True,
)

# 2. Trainable feature map (same idea)
training_params = ParameterVector("θ", 1)
fm0 = QuantumCircuit(2)
fm0.ry(training_params[0], 0)
fm0.ry(training_params[0], 1)
fm1 = zz_feature_map(2)
feature_map = fm0.compose(fm1)

# 3. Choose least-busy QPU + open a Runtime Session
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False, min_num_qubits=2)

# Create a transpiler pass manager targeting the backend ISA
pm = generate_preset_pass_manager(backend=backend, optimization_level=3)

with Session(service=service, backend=backend) as session:
sampler = Sampler(mode=session) # V2 primitive in session mode

# Compute-uncompute fidelity uses the Sampler primitive
fidelity = ComputeUncompute(sampler=sampler, shots=1024, transpiler=pm)

# Trainable fidelity quantum kernel + trainer
qkernel = TrainableFidelityQuantumKernel(
fidelity=fidelity,
feature_map=feature_map,
training_parameters=training_params,
)

optimizer = SPSA(maxiter=6, learning_rate=0.05, perturbation=0.05)

qkt = QuantumKernelTrainer(
quantum_kernel=qkernel,
loss="svc_loss",
optimizer=optimizer,
initial_point=[np.pi / 2],
)

# 4. Kernel alignment (training)
qka_result = qkt.fit(X_train, y_train)
trained_kernel = qka_result.quantum_kernel

# 5. Fit a model using the kernel
qsvc = QSVC(quantum_kernel=trained_kernel)
qsvc.fit(X_train, y_train)
y_pred = qsvc.predict(X_test)

print("Backend:", backend.name)
print("Optimal kernel params:", qka_result.optimal_parameters)
print("Balanced accuracy:", metrics.balanced_accuracy_score(y_true=y_test, y_pred=y_pred))

Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,10 @@
"### Classification with a `SamplerQNN`\n",
"\n",
"Next we show how a `SamplerQNN` can be used for classification within a `NeuralNetworkClassifier`. In this context, the `SamplerQNN` is expected to return $d$-dimensional probability vector as output, where $d$ denotes the number of classes. \n",
"The underlying `Sampler` primitive returns quasi-distributions of bit strings and we just need to define a mapping from the measured bitstrings to the different classes. For binary classification we use the parity mapping. Again we can use the `QNNCircuit` class to set up a parameterized quantum circuit from a feature map and ansatz of our choice. Please note that, once again, we are setting the `StatevectorSampler` instance from `qiskit.primitives` to the QNN and relying on `statevector`."
"The underlying `Sampler` primitive returns quasi-distributions of bit strings and we just need to\n",
" define a mapping from the measured bitstrings to the different classes. For binary \n",
" classification we use the parity mapping. Again we can use the `qnn_circuit` function to set up a \n",
" parameterized quantum circuit from a feature map and ansatz of our choice. Please note that, once again, we are setting the `StatevectorSampler` instance from `qiskit.primitives` to the QNN and relying on `statevector`."
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/10_effective_dimension.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
"source": [
"### 3.1 Define QNN\n",
"\n",
"The first step to create a `SamplerQNN` is to define a parametrized feature map and ansatz. In this toy example, we will use 3 qubits and the `QNNCircuit` class to simplify the composition of a feature map and an ansatz circuit. The resulting circuit is then used in the `SamplerQNN` class."
"The first step to create a `SamplerQNN` is to define a parametrized feature map and ansatz. In this toy example, we will use 3 qubits and the `qnn_circuit` function to simplify the composition of a feature map and an ansatz circuit. The resulting circuit is then used in the `SamplerQNN` class."
]
},
{
Expand Down
3 changes: 2 additions & 1 deletion qiskit_machine_learning/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of a Qiskit project.
#
# (C) Copyright IBM 2019, 2024.
# (C) Copyright IBM 2019, 2025.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand Down Expand Up @@ -41,6 +41,7 @@
kernels
neural_networks
optimizers
primitives
state_fidelities
utils

Expand Down
18 changes: 4 additions & 14 deletions qiskit_machine_learning/algorithm_job.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of a Qiskit project.
#
# (C) Copyright IBM 2022, 2024.
# (C) Copyright IBM 2022, 2025.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand Down Expand Up @@ -29,17 +29,7 @@ def submit(self) -> None:
"""
Submit the job for execution.

For V1 primitives, Qiskit ``PrimitiveJob`` subclassed JobV1 and defined ``submit()``.
``PrimitiveJob`` was updated for V2 primitives, no longer subclasses ``JobV1``, and
now has a private ``_submit()`` method, with ``submit()`` being deprecated as of
Qiskit version 0.46. This maintains the ``submit()`` for ``AlgorithmJob`` here as
it's called in many places for such a job. An alternative could be to make
0.46 the required minimum version and alter all algorithm's call sites to use
``_submit()`` and make this an empty class again as it once was. For now this
way maintains compatibility with the current min version of 0.44.
Since the library has been migrated to Qiskit v2.1, it is no longer necessary to
keep the :meth:``JobV1.submit()`` for the exception handling.
"""
# TODO: Considering changing this in the future - see above docstring.
try:
super()._submit()
except AttributeError:
super().submit() # pylint: disable=no-member
super()._submit()
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
"""Classifiers Package"""

from .neural_network_classifier import NeuralNetworkClassifier
from .qsvc import QSVC
from .pegasos_qsvc import PegasosQSVC
from .qsvc import QSVC
from .vqc import VQC

__all__ = ["NeuralNetworkClassifier", "QSVC", "PegasosQSVC", "VQC"]
Loading
Loading