phase_of_matter_data

phase_of_matter_data(training_size, test_size, n, *, model='heisenberg', one_hot=True, include_sample_total=False, class_labels=None, formatting='ndarray', seed=None, backend=None)[source]

Generate a quantum Phase of Matter classification dataset.

For each sample, coupling parameters are drawn uniformly from the interior of a known phase region, the corresponding Hamiltonian is built as a SparsePauliOp, and its ground state is computed via sparse exact diagonalization. The ground-state vector forms the feature, and the phase name forms the label.

Four spin-chain Hamiltonians are supported (see the reference for the exact definitions and phase diagrams):

  • "heisenberg" — Bond-alternating XXX Heisenberg model (eq. 6). Phases: trivial, topological.

  • "haldane" — Haldane chain (eq. 7). Phases: antiferromagnetic, paramagnetic, spt.

  • "annni" — Axial Next-Nearest-Neighbor Ising model (eq. 8). Phases: ferromagnetic, paramagnetic, floating, antiphase.

  • "cluster" — Cluster Hamiltonian with periodic boundary (eq. 9). Phases: haldane, ferromagnetic, antiferromagnetic, trivial.

Parameters:
  • training_size (int) – Total number of training samples (balanced across classes).

  • test_size (int) – Total number of test samples (balanced across classes).

  • n (int) – Number of lattice sites (qubits). Must be ≥ 4. The feature dimension is \(2^n\); practical limit for exact diagonalization is n 16.

  • model (str) – Hamiltonian to use. One of "heisenberg", "haldane", "annni", "cluster".

  • one_hot (bool) – If True (default), labels are one-hot encoded numpy arrays. If False, string phase names are returned.

  • include_sample_total (bool) – If True, a fifth element is appended to the return tuple with the number of ground states computed per class.

  • class_labels (list | None) – Optional list of custom label names that replace the model’s default phase names. Length must equal the number of phases for the chosen model.

  • formatting (str) – "ndarray" (default) returns features as a complex numpy array of shape (num_samples, 2**n). "statevector" returns a list of Statevector objects.

  • seed (int | None) – Integer seed for the parameter-sampling random number generator, enabling reproducible datasets.

  • backend (object) –

    When None (default), exact diagonalization via scipy.sparse.linalg.eigsh is used – the recommended path for reliable phase labels. When any non-None value is passed, a VQE-based approximation is used instead.

    Warning

    The VQE pathway is for hardware-experiment workflows only. VQE approximations near phase boundaries may produce incorrect labels. Use backend=None for dataset generation.

    The current VQE implementation uses StatevectorEstimator from qiskit.primitives unconditionally, regardless of the backend object passed. The backend argument is accepted for API consistency and is reserved for future hardware integration.

Returns:

A tuple (training_features, training_labels, test_features, test_labels) where:

  • training_features / test_features — shape (n_samples, 2**n) complex ndarray, or list of Statevector when formatting="statevector".

  • training_labels / test_labels — shape (n_samples, n_classes) one-hot ndarray when one_hot=True, or list of strings when one_hot=False.

If include_sample_total=True, a fifth element — a numpy array of shape (n_classes,) containing the number of ground states computed per class — is appended.

Raises:
  • ValueError – If model is not one of the supported strings.

  • ValueError – If formatting is not "ndarray" or "statevector".

  • ValueError – If n < 4.

  • ValueError – If class_labels is provided but has the wrong length.

Return type:

tuple[ndarray | list[Statevector], ndarray, ndarray | list[Statevector], ndarray] | tuple[ndarray | list[Statevector], ndarray, ndarray | list[Statevector], ndarray, ndarray]

References

[1] Bermejo et al., “Quantum Convolutional Neural Networks are (Effectively) Classically Simulatable”, arXiv:2408.12739 (2024).

Examples

>>> x_tr, y_tr, x_te, y_te = phase_of_matter_data(  
...     10, 5, 4, model="heisenberg", seed=0
... )
>>> x_tr.shape  
(10, 16)
>>> y_tr.shape  
(10, 2)