Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
3 changes: 2 additions & 1 deletion .pylintdict
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ nfevs
nft
nielsen
njev
nlocal
nlopt
nn
noancilla
Expand Down Expand Up @@ -511,7 +512,7 @@ scipy
sdg
seealso
semidefinite
sep
sep
seperate
seperable
serializable
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"]
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
77 changes: 29 additions & 48 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, Set

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,40 +160,28 @@ 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

def __power_grover(
self, grover_op: QuantumCircuit, evidence: Dict[str, int], k: int
) -> Tuple[QuantumCircuit, Set[Tuple[Qubit, int]]]:
) -> tuple[QuantumCircuit, Set[tuple[Qubit, int]]]:
"""
Applies the Grover operator to the quantum circuit 2^k times, measures the evidence qubits,
and returns a tuple containing the updated quantum circuit and a set of the measured
Expand Down Expand Up @@ -246,7 +227,7 @@ def __power_grover(
}
return qc, e_meas

def _format_samples(self, samples: Dict[str, float], evidence: List[str]) -> Dict[str, float]:
def _format_samples(self, samples: Dict[str, float], evidence: list[str]) -> Dict[str, float]:
"""Transforms samples keys back to their variables names."""
f_samples: Dict[str, float] = {}
for smpl_key, smpl_val in samples.items():
Expand Down Expand Up @@ -295,7 +276,7 @@ def rejection_sampling(
grover_op = self._get_grover_op(evidence)
# Amplitude amplification
true_e = {(self._label2qubit[e_key], e_val) for e_key, e_val in evidence.items()}
meas_e: Set[Tuple[str, int]] = set()
meas_e: Set[tuple[str, int]] = set()
best_qc, best_inter = QuantumCircuit(), -1
self._converged = False
k = -1
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

"""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
9 changes: 4 additions & 5 deletions qiskit_machine_learning/circuit/library/qnn_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@

"""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 +118,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 Expand Up @@ -274,7 +273,7 @@ def num_qubits(self, num_qubits: int) -> None:
if self.num_qubits != num_qubits:
# invalidate the circuit
self._invalidate()
self.qregs: List[QuantumRegister] = []
self.qregs: list[QuantumRegister] = []
if num_qubits is not None and num_qubits > 0:
self.qregs = [QuantumRegister(num_qubits, name="q")]
(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

"""The raw feature vector circuit."""

from typing import Optional, List
from typing import Optional
import numpy as np
from qiskit.exceptions import QiskitError
from qiskit.circuit import (
Expand Down Expand Up @@ -201,7 +201,7 @@ def num_qubits(self, num_qubits: int) -> None:
if self.num_qubits != num_qubits:
# invalidate the circuit
self._invalidate()
self.qregs: List[QuantumRegister] = []
self.qregs: list[QuantumRegister] = []
if num_qubits is not None and num_qubits > 0:
self.qregs = [QuantumRegister(num_qubits, name="q")]

Expand Down
Loading
Loading