Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 3 additions & 12 deletions qiskit_machine_learning/algorithms/classifiers/vqc.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ class VQC(NeuralNetworkClassifier):
# pylint: disable=too-many-positional-arguments
def __init__(
self,
num_qubits: int | None = None,
feature_map: QuantumCircuit | None = None,
ansatz: QuantumCircuit | None = None,
loss: str | Loss = "cross_entropy",
Expand All @@ -65,11 +64,6 @@ def __init__(
) -> None:
"""
Args:
num_qubits: The number of qubits for the underlying QNN.
If ``None`` is given, the number of qubits is derived from the
feature map or ansatz. If neither of those is given, raises an exception.
The number of qubits in the feature map and ansatz are adjusted to this
number if required and possible (such adjustment is deprecated).
feature_map: The (parametrized) circuit to be used as a feature map for the underlying
QNN. If ``None`` is given, the :meth:`~qiskit.circuit.library.zz_feature_map`
is used if the number of qubits is larger than 1. For a single qubit
Expand Down Expand Up @@ -102,14 +96,11 @@ def __init__(
output_shape: The output shape for the underlying neural network, generally equals to
number of classes. Defaults to binary classification, 2.
Raises:
QiskitMachineLearningError: Needs at least one out of ``num_qubits``, ``feature_map`` or
``ansatz`` to be given. Or the number of qubits in the feature map and/or ansatz
can't be adjusted to ``num_qubits``.
QiskitMachineLearningError: At least one of ``feature_map`` or ``ansatz`` must be
given, or the number of qubits in the feature map and ansatz must match.
"""

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

if output_shape is None:
self.output_shape = 2
Expand Down
15 changes: 3 additions & 12 deletions qiskit_machine_learning/algorithms/regressors/vqr.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class VQR(NeuralNetworkRegressor):
# pylint: disable=too-many-positional-arguments
def __init__(
self,
num_qubits: int | None = None,
feature_map: QuantumCircuit | None = None,
ansatz: QuantumCircuit | None = None,
observable: BaseOperator | None = None,
Expand All @@ -50,11 +49,6 @@ def __init__(
) -> None:
r"""
Args:
num_qubits: The number of qubits for the underlying QNN.
If ``None`` then the number of qubits is derived from the
feature map or ansatz, but if neither of these are given an error is raised.
The number of qubits in the feature map and ansatz are adjusted to this
number if required and possible (such adjustment is deprecated).
feature_map: The (parametrized) circuit to be used as a feature map for the underlying
QNN. If ``None`` the :meth:`~qiskit.circuit.library.zz_feature_map`
is used if the number of qubits is larger than 1. For a single qubit regression
Expand Down Expand Up @@ -82,9 +76,8 @@ def __init__(
pass_manager: The pass manager to transpile the circuits, if necessary.
Defaults to ``None``, as some primitives do not need transpiled circuits.
Raises:
QiskitMachineLearningError: Needs at least one out of ``num_qubits``, ``feature_map`` or
``ansatz`` to be given. Or the number of qubits in the feature map and/or ansatz
can't be adjusted to ``num_qubits``.
QiskitMachineLearningError: At least one of ``feature_map`` or ``ansatz`` must be
given, or the number of qubits in the feature map and ansatz must match.
ValueError: if the type of the observable is not compatible with ``estimator``.
"""
if observable is not None and not isinstance(observable, BaseOperator):
Expand All @@ -95,9 +88,7 @@ def __init__(

self._estimator = estimator

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

# construct circuit
self._feature_map = feature_map
Expand Down
49 changes: 15 additions & 34 deletions qiskit_machine_learning/circuit/library/qnn_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@


def qnn_circuit(
num_qubits: int | None = None,
feature_map: QuantumCircuit | None = None,
ansatz: QuantumCircuit | None = None,
):
Expand All @@ -31,12 +30,11 @@ def qnn_circuit(
use for inputs and weights as needed for a neural network, such as
:class:`~qiskit-machine-learning.neural_networks.SamplerQNN`.

If only the number of qubits is provided the :meth:`~qiskit.circuit.library.real_amplitudes`
ansatz and the :meth:`~qiskit.circuit.library.zz_feature_map` feature map are used. If the
number of qubits is 1 the :meth:`~qiskit.circuit.library.z_feature_map` is used. If only a
feature map is provided, the :meth:`~qiskit.circuit.library.real_amplitudes` ansatz with the
corresponding number of qubits is used. If only an ansatz is provided the
If only a feature map is provided, the :meth:`~qiskit.circuit.library.real_amplitudes`
ansatz with the corresponding number of qubits is used. If only an ansatz is provided the
:meth:`~qiskit.circuit.library.zz_feature_map` with the corresponding number of qubits is used.
For a single qubit, :meth:`~qiskit.circuit.library.z_feature_map` is used as the default feature
map.

At least one parameter has to be provided. If a feature map and an ansatz is provided, the
number of qubits must be the same.
Expand All @@ -45,8 +43,9 @@ def qnn_circuit(

.. code-block:: python

from qiskit.circuit.library import zz_feature_map
from qiskit_machine_learning.circuit.library import qnn_circuit
qnn_qc, fm_params, anz_params = qnn_circuit(2)
qnn_qc, fm_params, anz_params = qnn_circuit(feature_map=zz_feature_map(2))
qnn_qc.draw(fold=60)
# ┌───┐┌─────────────┐ »
# q_0: ┤ H ├┤ P(2.0*x[0]) ├──■──»
Expand Down Expand Up @@ -81,42 +80,24 @@ def qnn_circuit(
# ParameterVectorElement(θ[4]), ParameterVectorElement(θ[5]),
# ParameterVectorElement(θ[6]), ParameterVectorElement(θ[7])])

Although all arguments to qnn_circuit default to None at least one must be provided,
to determine the number of qubits from.

If more than one is passed:

1) If num_qubits is provided the feature map and/or ansatz circuits supplied must be the
same number of qubits.

2) If num_qubits is not provided the feature_map and ansatz must be set to the same number
of qubits.

Args:
num_qubits: Number of qubits, a positive integer. Optional if feature_map or ansatz is
provided, otherwise required. If not provided num_qubits defaults from the
sizes of feature_map and/or ansatz.
feature_map: A feature map. Optional if num_qubits or ansatz is provided, otherwise
required. If not provided defaults to
:meth:`~qiskit.circuit.library.zz_feature_map` or
:meth:`~qiskit.circuit.library.z_feature_map` if num_qubits is determined
to be 1.
ansatz: An ansatz. Optional if num_qubits or feature_map is provided, otherwise
required. If not provided defaults to
:meth:`~qiskit.circuit.library.real_amplitudes`.
feature_map: A feature map. At least one of ``feature_map`` or ``ansatz`` must be
provided. If not provided defaults to
:meth:`~qiskit.circuit.library.zz_feature_map` or
:meth:`~qiskit.circuit.library.z_feature_map` for a single qubit.
ansatz: An ansatz. At least one of ``feature_map`` or ``ansatz`` must be provided.
If not provided defaults to :meth:`~qiskit.circuit.library.real_amplitudes`.

Returns:
The composed feature map and ansatz circuit, the feature map parameters and the
ansatz parameters.

Raises:
QiskitMachineLearningError: If a valid number of qubits cannot be derived from the \
provided input arguments.
provided input arguments, or if ``feature_map`` and ``ansatz`` have different numbers of \
qubits.
"""
# 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
)
num_qubits, feature_map, ansatz = derive_num_qubits_feature_map_ansatz(feature_map, ansatz)
qc = QuantumCircuit(num_qubits)
qc.compose(feature_map, inplace=True)
qc.compose(ansatz, inplace=True)
Expand Down
22 changes: 8 additions & 14 deletions qiskit_machine_learning/kernels/base_kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,8 @@ def __init__(self, *, feature_map: QuantumCircuit = None, enforce_psd: bool = Tr
"""
Args:
feature_map: Parameterized circuit to be used as the feature map. This is required: if
``None`` is given, a :class:`~QiskitMachineLearningError` is raised. If there's
a mismatch in the number of qubits of the feature map and the number of features
in the dataset, then the kernel will try to adjust the feature map to reflect the
number of features.
``None`` is given, a :class:`~QiskitMachineLearningError` is raised. The number of
features in the input data must match the number of qubits in the feature map.
enforce_psd: Project to the closest positive semidefinite matrix if ``x = y``.
Default ``True``.
"""
Expand Down Expand Up @@ -111,16 +109,12 @@ def _validate_input(
x_vec = np.reshape(x_vec, (-1, len(x_vec)))

if x_vec.shape[1] != self._num_features:
# before raising an error we try to adjust the feature map
# to the required number of qubit.
try:
self._feature_map.num_qubits = x_vec.shape[1]
except AttributeError as a_e:
raise ValueError(
f"x_vec and class feature map have incompatible dimensions.\n"
f"x_vec has {x_vec.shape[1]} dimensions, "
f"but feature map has {self._num_features}."
) from a_e
raise ValueError(
f"x_vec and feature map have incompatible dimensions.\n"
f"x_vec has {x_vec.shape[1]} features, but the feature map expects "
f"{self._num_features} parameters. "
"Construct the feature map with a matching feature dimension."
)

if y_vec is not None:
y_vec = np.asarray(y_vec)
Expand Down
2 changes: 1 addition & 1 deletion qiskit_machine_learning/neural_networks/estimator_qnn.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class EstimatorQNN(NeuralNetwork):
# Using the qnn_circuit:
# Create a parametrized 2 qubit circuit composed of the default zz_feature_map feature map
# and real_amplitudes ansatz.
qnn_qc, fm_params, anz_params = qnn_circuit(num_qubits)
qnn_qc, fm_params, anz_params = qnn_circuit(feature_map=zz_feature_map(num_qubits))

qnn = EstimatorQNN(
circuit=qnn_qc,
Expand Down
2 changes: 1 addition & 1 deletion qiskit_machine_learning/neural_networks/sampler_qnn.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def parity(x):

# Example 1: Using the qnn_circuit
# qnn_circuit automatically combines a feature map and an ansatz into a single circuit
qnn_qc, fm_params, anz_params = qnn_circuit(num_qubits)
qnn_qc, fm_params, anz_params = qnn_circuit(feature_map=zz_feature_map(num_qubits))

qnn = SamplerQNN(
circuit=qnn_qc,
Expand Down
Loading
Loading