Source code for pyqit.ansatzes.hardware_efficient

import pennylane as qml
from skbase.utils.dependencies import _check_soft_dependencies

from pyqit.ansatzes.base import BaseAnsatz


[docs] class RealAmplitudesAnsatz(BaseAnsatz): """Qiskit's `RealAmplitudes`: RY layers separated by CX entanglers. The hardware-efficient ansatz of Kandala et al. 2017 (Nature) as Qiskit's circuit library builds it, and the default ansatz of Qiskit ML's `VQC`. The circuit is Qiskit's own, converted through the `pennylane-qiskit` plugin, so it needs the `qiskit` extra and Python 3.11 or newer. The weights are Qiskit's flat parameter vector, `weights`, of shape `(n_qubits * (n_layers + 1),)`. With `skip_final_rotation_layer` it is `(n_qubits * n_layers,)`. Parameters ---------- n_qubits : int n_layers : int, default 3 Qiskit's `reps`: the number of entangling blocks. Rotation layers number `n_layers + 1` unless `skip_final_rotation_layer`. entanglement : str, default "reverse_linear" Any entanglement Qiskit accepts, e.g. `"linear"`, `"full"`, `"circular"`. skip_final_rotation_layer : bool, default False References ---------- Kandala et al., "Hardware-efficient variational quantum eigensolver for small molecules and quantum magnets", Nature 549, 242 (2017). Examples -------- >>> from pyqit.ansatzes import RealAmplitudesAnsatz >>> from pyqit.core import ZZFeatureMap >>> from pyqit.models import VQCClassifier >>> model = VQCClassifier( ... n_qubits=2, ansatz=RealAmplitudesAnsatz, encoder=ZZFeatureMap ... ) """ _tags = {"python_dependencies": "pennylane-qiskit"} _qiskit_circuit = "real_amplitudes" def __init__( self, n_qubits: int, n_layers: int = 3, entanglement: str = "reverse_linear", skip_final_rotation_layer: bool = False, ): self.entanglement = entanglement self.skip_final_rotation_layer = skip_final_rotation_layer super().__init__(n_qubits, n_layers) if not _check_soft_dependencies("pennylane-qiskit", severity="none"): raise ImportError( f"{type(self).__name__} wraps Qiskit's circuit through the " "pennylane-qiskit plugin, which is not installed. Install it with " "`pip install pyqit[qiskit]`" ) from qiskit.circuit import library self.circuit = getattr(library, self._qiskit_circuit)( n_qubits, entanglement=entanglement, reps=n_layers, skip_final_rotation_layer=skip_final_rotation_layer, ) self._template = qml.from_qiskit(self.circuit)
[docs] def build_circuit(self, weights): """Apply the circuit. Expects `weights["weights"]` as a flat vector in the order of `circuit.parameters`.""" self._template(weights["weights"])
[docs] def get_weight_shapes(self) -> dict: """Return `{"weights": (n_params,)}`, Qiskit's flat parameter vector.""" return {"weights": (len(self.circuit.parameters),)}
[docs] @classmethod def get_test_params(cls): """List constructor kwargs used to parametrize this class in the test suite.""" return [ {"n_qubits": 3, "n_layers": 2}, {"n_qubits": 2, "n_layers": 1, "entanglement": "circular"}, ]
[docs] class EfficientSU2Ansatz(RealAmplitudesAnsatz): """Qiskit's `EfficientSU2`: RY and RZ layers separated by CX entanglers. `RealAmplitudesAnsatz` with an RZ layer after every RY layer, Qiskit's default `su2_gates`. Same parameters and the same reference. The second rotation doubles the weight vector to `(2 * n_qubits * (n_layers + 1),)`. """ _qiskit_circuit = "efficient_su2"