Source code for psipose.feature_maps.angle

"""Angle encoding: each feature becomes a rotation angle."""

import pennylane as qml

from .base import FeatureMap


[docs] class AngleFeatureMap(FeatureMap): """Angle encoding of classical data into quantum rotations. Each feature :math:`x_i` is encoded as a rotation angle on a separate qubit via :math:`R_{\\text{axis}}(x_i)`. By default, uses Y rotations. Supports X, Y, or Z rotations. This follows the angle encoding approach from: - Farhi & Neven (2018), "Classification with Quantum Neural Networks on Near Term Processors" (arXiv:1802.06002). Uses parametrized rotation gates to encode classical data into quantum states. - Schuld, Bocharov, Svore & Wiebe (2018), "Circuit-centric quantum classifiers" (arXiv:1804.00633). Encodes features as rotation angles in variational quantum circuits. Mathematically, for a feature vector :math:`\\mathbf{x} = (x_1, \\dots, x_n)`, the encoded state is: .. math:: |\\phi(\\mathbf{x})\\rangle = \\bigotimes_{i=1}^{n} R_{\\text{axis}}(x_i) |0\\rangle where :math:`R_{\\text{axis}} \\in \\{R_X, R_Y, R_Z\\}`. Parameters ---------- rotation : {"X", "Y", "Z"}, default="Y" Which rotation gate to use for encoding. n_qubits : int, optional Number of qubits to use. If None, uses one qubit per feature (or the minimum of n_features and 10). Examples -------- >>> feature_map = AngleFeatureMap(rotation="Y") >>> feature_map.fit(X_train) # determines n_qubits_ >>> circuit = feature_map.encode(x_sample, wires=range(feature_map.n_qubits_)) """ def __init__(self, rotation="Y", n_qubits=None): super().__init__(n_qubits) if rotation not in {"X", "Y", "Z"}: raise ValueError(f'rotation must be one of "X", "Y", "Z", got {rotation}') self.rotation = rotation
[docs] def encode(self, x, wires): """Apply angle encoding to the given wires. Only encodes as many features as there are wires. If x has more features than wires, the excess features are truncated. """ for i, wire in enumerate(wires): if i >= len(x): break feature = x[i] if self.rotation == "X": qml.RX(feature, wires=wire) elif self.rotation == "Y": qml.RY(feature, wires=wire) else: # Z qml.RZ(feature, wires=wire)