Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
32 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
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
2 changes: 1 addition & 1 deletion docs/lowercase_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

""" Implements a Lower Case Filter for Sphinx spelling """
"""Implements a Lower Case Filter for Sphinx spelling"""

from enchant import tokenize

Expand Down
16 changes: 3 additions & 13 deletions qiskit_machine_learning/algorithm_job.py
Original file line number Diff line number Diff line change
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()
4 changes: 2 additions & 2 deletions qiskit_machine_learning/algorithms/classifiers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

""" Classifiers Package """
"""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"]
11 changes: 5 additions & 6 deletions qiskit_machine_learning/algorithms/classifiers/vqc.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,18 @@
"""An implementation of variational quantum classifier."""

from __future__ import annotations

from typing import Callable

import numpy as np

from qiskit import QuantumCircuit
from qiskit.primitives import BaseSampler
from qiskit.primitives import BaseSamplerV2
from qiskit.transpiler.passmanager import BasePassManager

from ...neural_networks import SamplerQNN
from ...optimizers import Optimizer, OptimizerResult, Minimizer
from ...optimizers import Minimizer, Optimizer, OptimizerResult
from ...utils import derive_num_qubits_feature_map_ansatz
from ...utils.loss_functions import Loss

from .neural_network_classifier import NeuralNetworkClassifier


Expand Down Expand Up @@ -58,7 +57,7 @@ def __init__(
initial_point: np.ndarray | None = None,
callback: Callable[[np.ndarray, float], None] | None = None,
*,
sampler: BaseSampler | None = None,
sampler: BaseSamplerV2 | None = None, # change: BaseSampler is migrated to BaseSamplerV2
interpret: Callable[[int], int | tuple[int, ...]] | None = None,
output_shape: int | None = None,
pass_manager: BasePassManager | None = None,
Expand Down Expand Up @@ -108,7 +107,7 @@ def __init__(
"""

num_qubits, feature_map, ansatz = derive_num_qubits_feature_map_ansatz(
num_qubits, feature_map, ansatz, use_methods=True
num_qubits, feature_map, ansatz
)

if output_shape is None:
Expand Down
2 changes: 1 addition & 1 deletion qiskit_machine_learning/algorithms/inference/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

""" Inference Package """
"""Inference Package"""


from .qbayesian import QBayesian
Expand Down
71 changes: 26 additions & 45 deletions qiskit_machine_learning/algorithms/inference/qbayesian.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,18 @@
from __future__ import annotations

import copy
from typing import Tuple, Dict, Set, List
from typing import Dict, List, Set, Tuple

from qiskit import QuantumCircuit, ClassicalRegister
from qiskit.quantum_info import Statevector
from qiskit import ClassicalRegister, QuantumCircuit
from qiskit.circuit import Qubit
from qiskit.circuit.library import grover_operator
from qiskit.primitives import BaseSampler, Sampler, BaseSamplerV2, BaseSamplerV1
from qiskit.transpiler.passmanager import BasePassManager
from qiskit.primitives import (
BaseSamplerV2,
StatevectorSampler,
)
from qiskit.quantum_info import Statevector
from qiskit.result import QuasiDistribution

from ...utils.deprecation import issue_deprecation_msg
from qiskit.transpiler.passmanager import BasePassManager


class QBayesian:
Expand Down Expand Up @@ -67,7 +68,7 @@ def __init__(
*,
limit: int = 10,
threshold: float = 0.9,
sampler: BaseSampler | BaseSamplerV2 | None = None,
sampler: BaseSamplerV2 | None = None,
pass_manager: BasePassManager | None = None,
):
"""
Expand Down Expand Up @@ -96,15 +97,7 @@ def __init__(
self._limit = limit
self._threshold = threshold
if sampler is None:
sampler = Sampler()

if isinstance(sampler, BaseSamplerV1):
issue_deprecation_msg(
msg="V1 Primitives are deprecated",
version="0.8.0",
remedy="Use V2 primitives for continued compatibility and support.",
period="4 months",
)
sampler = StatevectorSampler()

self._sampler = sampler

Expand Down Expand Up @@ -167,34 +160,22 @@ def _run_circuit(self, circuit: QuantumCircuit) -> Dict[str, float]:
"""Run the quantum circuit with the sampler."""
counts = {}

if isinstance(self._sampler, BaseSampler):
# Sample from circuit
job = self._sampler.run(circuit)
result = job.result()

# Get the counts of quantum state results
counts = result.quasi_dists[0].nearest_probability_distribution().binary_probabilities()

elif isinstance(self._sampler, BaseSamplerV2):
# Sample from circuit
if self._pass_manager is not None:
circuit = self._pass_manager.run(circuit)
job = self._sampler.run([circuit])
result = job.result()

bit_array = list(result[0].data.values())[0]
bitstring_counts = bit_array.get_counts()
# Sample from circuit
if self._pass_manager is not None:
circuit = self._pass_manager.run(circuit)
job = self._sampler.run([circuit])
result = job.result()

# Normalize the counts to probabilities
total_shots = sum(bitstring_counts.values())
probabilities = {k: v / total_shots for k, v in bitstring_counts.items()}
# Convert to quasi-probabilities
quasi_dist = QuasiDistribution(probabilities)
binary_prob = quasi_dist.nearest_probability_distribution().binary_probabilities()
counts = {k: v for k, v in binary_prob.items() if int(k) < 2**self.num_virtual_qubits}
bit_array = list(result[0].data.values())[0]
bitstring_counts = bit_array.get_counts()

# counts = QuasiDistribution(probabilities)
# counts = {k: v for k, v in counts.items()}
# Normalize the counts to probabilities
total_shots = sum(bitstring_counts.values())
probabilities = {k: v / total_shots for k, v in bitstring_counts.items()}
# Convert to quasi-probabilities
quasi_dist = QuasiDistribution(probabilities)
binary_prob = quasi_dist.nearest_probability_distribution().binary_probabilities()
counts = {k: v for k, v in binary_prob.items() if int(k) < 2**self.num_virtual_qubits}

return counts

Expand Down Expand Up @@ -412,12 +393,12 @@ def limit(self, limit: int):
self._limit = limit

@property
def sampler(self) -> BaseSampler | BaseSamplerV2:
def sampler(self) -> BaseSamplerV2:
"""Returns the sampler primitive used to compute the samples."""
return self._sampler

@sampler.setter
def sampler(self, sampler: BaseSampler | BaseSamplerV2):
def sampler(self, sampler: BaseSamplerV2):
"""Set the sampler primitive used to compute the samples."""
self._sampler = sampler

Expand Down
4 changes: 2 additions & 2 deletions qiskit_machine_learning/algorithms/regressors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

""" Regressors Package"""
"""Regressors Package"""

from .qsvr import QSVR
from .neural_network_regressor import NeuralNetworkRegressor
from .qsvr import QSVR
from .vqr import VQR

__all__ = ["QSVR", "VQR", "NeuralNetworkRegressor"]
10 changes: 5 additions & 5 deletions qiskit_machine_learning/algorithms/regressors/vqr.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@

import numpy as np
from qiskit import QuantumCircuit
from qiskit.primitives import BaseEstimator
from qiskit.primitives import BaseEstimatorV2
from qiskit.quantum_info.operators.base_operator import BaseOperator
from qiskit.transpiler.passmanager import BasePassManager

from .neural_network_regressor import NeuralNetworkRegressor
from ...neural_networks import EstimatorQNN
from ...optimizers import Optimizer, Minimizer
from ...optimizers import Minimizer, Optimizer
from ...utils import derive_num_qubits_feature_map_ansatz
from ...utils.loss_functions import Loss
from .neural_network_regressor import NeuralNetworkRegressor


class VQR(NeuralNetworkRegressor):
Expand All @@ -43,7 +43,7 @@ def __init__(
initial_point: np.ndarray | None = None,
callback: Callable[[np.ndarray, float], None] | None = None,
*,
estimator: BaseEstimator | None = None,
estimator: BaseEstimatorV2 | None = None,
pass_manager: BasePassManager | None = None,
) -> None:
r"""
Expand Down Expand Up @@ -94,7 +94,7 @@ def __init__(
self._estimator = estimator

num_qubits, feature_map, ansatz = derive_num_qubits_feature_map_ansatz(
num_qubits, feature_map, ansatz, use_methods=True
num_qubits, feature_map, ansatz
)

# construct circuit
Expand Down
7 changes: 4 additions & 3 deletions qiskit_machine_learning/circuit/library/qnn_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@

"""The QNN circuit."""
from __future__ import annotations

from typing import List

from qiskit.circuit import QuantumRegister, QuantumCircuit
from qiskit.circuit.parametertable import ParameterView
from qiskit.circuit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library import BlueprintCircuit
from qiskit.circuit.parametertable import ParameterView

from qiskit_machine_learning import QiskitMachineLearningError

Expand Down Expand Up @@ -119,7 +120,7 @@ def qnn_circuit(
"""
# Check if circuit is constructed with valid configuration and set properties accordingly.
num_qubits, feature_map, ansatz = derive_num_qubits_feature_map_ansatz(
num_qubits, feature_map, ansatz, use_methods=True
num_qubits, feature_map, ansatz
)
qc = QuantumCircuit(num_qubits)
qc.compose(feature_map, inplace=True)
Expand Down
2 changes: 1 addition & 1 deletion qiskit_machine_learning/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

""" Machine Learning Exception """
"""Machine Learning Exception"""

from qiskit.exceptions import QiskitError

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,34 +21,31 @@
from copy import copy

import numpy as np

from qiskit.circuit import Parameter, ParameterExpression, QuantumCircuit
from qiskit.primitives import BaseEstimator, BaseEstimatorV1
from qiskit.primitives.base import BaseEstimatorV2
from qiskit.primitives.utils import _circuit_key
from qiskit.primitives import BaseEstimatorV2
from qiskit.providers import Options
from qiskit.quantum_info.operators.base_operator import BaseOperator
from qiskit.transpiler.passes import TranslateParameterizedGates
from qiskit.transpiler.passmanager import BasePassManager
from qiskit_aer.primitives.sampler import _circuit_key

from .estimator_gradient_result import EstimatorGradientResult
from ...algorithm_job import AlgorithmJob
from ..utils import (
DerivativeType,
GradientCircuit,
_assign_unique_parameters,
_make_gradient_parameters,
_make_gradient_parameter_values,
_make_gradient_parameters,
)
from ...utils.deprecation import issue_deprecation_msg
from ...algorithm_job import AlgorithmJob
from .estimator_gradient_result import EstimatorGradientResult


class BaseEstimatorGradient(ABC):
"""Base class for an ``EstimatorGradient`` to compute the gradients of the expectation value."""

def __init__(
self,
estimator: BaseEstimator | BaseEstimatorV2,
estimator: BaseEstimatorV2,
options: Options | None = None,
derivative_type: DerivativeType = DerivativeType.REAL,
pass_manager: BasePassManager | None = None,
Expand All @@ -73,14 +70,7 @@ def __init__(
pass_manager: The pass manager to transpile the circuits if necessary.
Defaults to ``None``, as some primitives do not need transpiled circuits.
"""
if isinstance(estimator, BaseEstimatorV1):
issue_deprecation_msg(
msg="V1 Primitives are deprecated",
version="0.8.0",
remedy="Use V2 primitives for continued compatibility and support.",
period="4 months",
)
self._estimator: BaseEstimator = estimator
self._estimator: BaseEstimatorV2 = estimator
self._pass_manager = pass_manager
self._default_options = Options()
if options is not None:
Expand Down
Loading
Loading