Encoders#

Encoders map classical data to quantum states.

AngleFeatureMap#

class AngleFeatureMap(rotation='Y', n_qubits=None)[source]

Bases: FeatureMap

Angle encoding of classical data into quantum rotations.

Each feature \(x_i\) is encoded as a rotation angle on a separate qubit via \(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 \(\mathbf{x} = (x_1, \dots, x_n)\), the encoded state is:

\[|\phi(\mathbf{x})\rangle = \bigotimes_{i=1}^{n} R_{\text{axis}}(x_i) |0\rangle\]

where \(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_))
encode(x, wires)[source]

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.

AmplitudeFeatureMap#

class AmplitudeFeatureMap(n_qubits=None, normalize=True)[source]

Bases: FeatureMap

Amplitude encoding of a classical vector into quantum amplitudes.

Maps a classical feature vector \(\mathbf{x}\) to the amplitudes of a quantum state \(|\phi(\mathbf{x})\rangle\). Requires \(n_{\text{qubits}}\) such that \(2^{n_{\text{qubits}}} \ge n_{\text{features}}\).

This implements the state preparation method from Möttönen et al. (2004) “Quantum circuit for preparing arbitrary states” (arXiv:quant-ph/0407010). PennyLane’s qml.AmplitudeEmbedding() template uses this algorithm.

Mathematically, for a normalized feature vector \(\mathbf{x} = (x_1, \dots, x_d)\) with \(\|\mathbf{x}\| = 1\), the encoded state is:

\[|\phi(\mathbf{x})\rangle = \sum_{i=1}^{d} x_i |i-1\rangle\]

where \(d = 2^{n_{\text{qubits}}}\). If the input dimension is not a power of 2, it is padded with zeros to the next power of 2.

Parameters:
  • n_qubits (int, optional) – Number of qubits to use. If None, the smallest power of 2 that can accommodate the feature dimension is used.

  • normalize (bool, default=True) – Whether to normalize the input vector before encoding.

n_features_

The original number of features (set after fit).

Type:

int

Examples

>>> feature_map = AmplitudeFeatureMap()
>>> feature_map.fit(X_train)  # determines n_qubits_ based on n_features
>>> # X_train.shape[1] must be <= 2**n_qubits
fit(X)[source]

Determine the number of qubits needed.

For amplitude encoding, we need \(2^{n_{\text{qubits}}} \ge n_{\text{features}}\). If n_qubits is not specified, choose the smallest that works.

encode(x, wires)[source]

Apply amplitude encoding to the given wires.

Pads or truncates the input to match \(2^{\text{len(wires)}}\).

Note: normalize=False is passed to qml.AmplitudeEmbedding because normalization is handled manually above (using self.normalize) to support the zero-vector edge case.

PauliFeatureMap#

class PauliFeatureMap(n_qubits=None, reps=2, entanglement='full', alpha=2.0, data_map_func=None)[source]

Bases: FeatureMap

Pauli-based feature map from Havlíček et al. (2019).

This feature map implements the quantum kernel approach from the landmark paper:

  • Havlíček et al. (2019), “Supervised learning with quantum-inspired kernel” (arXiv:1904.01567, Nature 567, 209-212).

The Pauli feature map applies Pauli rotations in a layered structure with entangling gates, creating a rich non-linear embedding.

Mathematically, for an input vector \(\mathbf{x}\) and qubits, the encoding circuit applies:

\[U_\phi(\mathbf{x}) = \exp\left(i \sum_{S \subseteq [n], |S| \geq 2} \phi_S(\mathbf{x}) \prod_{i \in S} Z_i\right) \prod_{j=1}^n \exp\left(i x_j Z_j\right)\]

where \(\phi_S\) are functions of the input features.

The implemented circuit is a Z/ZZ feature map with repeated layers:

  1. Hadamard gates prepare a superposition.

  2. Single-qubit RZ rotations encode individual features.

  3. Two-qubit MultiRZ rotations encode pairwise feature interactions.

Parameters:
  • n_qubits (int, optional) – Number of qubits.

  • reps (int, default=2) – Number of feature-map repetitions.

  • entanglement ({"full", "linear", "circular", "none"}, default="full") – Which two-qubit feature interactions to include.

  • alpha (float, default=2.0) – Global multiplier for all encoded angles.

  • data_map_func (callable, optional) – Function called as data_map_func(left, right) for pairwise interaction angles. Defaults to (pi - left) * (pi - right).

n_features_

Number of features seen during fit.

Type:

int

Examples

>>> feature_map = PauliFeatureMap(n_qubits=2, reps=1)
>>> feature_map.fit(X_train)
>>> feature_map.encode(X_train[0], wires=range(feature_map.n_qubits_))
encode(x, wires)[source]

Apply Pauli-Z feature-map encoding to the given wires.

Extra input features are truncated. Missing features are padded with zero so custom wire counts remain usable in sklearn pipelines.

fit(X)[source]

Determine qubit count and record the observed feature dimension.