Skip to content
Merged
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
10 changes: 7 additions & 3 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ jobs:
python -m pip install --upgrade pip
python -m venv venv_minimal
source venv_minimal/bin/activate
pip install toml
pip install toml autoray==0.7.2
python3 install_lowest_dependencies.py
- name: Test with pytest
run: |
source venv_minimal/bin/activate
pip install pytest
pytest tests/
- name: Install example dependencies
run: |
source venv_minimal/bin/activate
python3 install_lowest_dependencies.py --examples
- name: Test examples
run: |
source venv_minimal/bin/activate
Expand All @@ -49,7 +53,7 @@ jobs:
python -m pip install --upgrade pip
python -m venv venv_qiskit_0_46
source venv_qiskit_0_46/bin/activate
pip install .[examples] qiskit==0.46.3 qiskit-ibm-runtime==0.20.0
pip install .[examples] qiskit==0.46.3 qiskit-ibm-runtime==0.20.0 autoray==0.7.2
- name: Test with pytest
run: |
source venv_qiskit_0_46/bin/activate
Expand Down Expand Up @@ -78,7 +82,7 @@ jobs:
python -m pip install --upgrade pip
python -m venv venv_qiskit_1
source venv_qiskit_1/bin/activate
pip install .[examples] qiskit==1.1.2 qiskit-ibm-runtime==0.27.1
pip install .[examples] qiskit==1.1.2 qiskit-ibm-runtime==0.27.1 autoray==0.7.2
- name: Test with pytest
run: |
source venv_qiskit_1/bin/activate
Expand Down
16 changes: 10 additions & 6 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ license: Apache-2.0
repository-code: https://github.com/sQUlearn/squlearn
preferred-citation:
type: article
status: preprint
title: "sQUlearn - A Python Library for Quantum Machine Learning"
title: "sQUlearn: A Python Library for Quantum Machine Learning"
authors:
- family-names: Kreplin
given-names: David A.
Expand All @@ -35,7 +34,12 @@ preferred-citation:
given-names: Marco
orcid: https://orcid.org/0000-0002-1276-5655
affiliation: Fraunhofer Institute for Manufacturing Engineering and Automation IPA
year: 2023
month: 11
doi: 10.48550/arXiv.2311.08990
url: https://arxiv.org/abs/2311.08990
journal: "IEEE Software"
start: 65
end: 72
issue: 5
volume: 42
year: 2025
month: 1
doi: 10.1109/MS.2025.3527736
url: https://ieeexplore.ieee.org/document/10841386
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

sQUlearn is a user-friendly, NISQ-ready Python library for quantum machine learning (QML), designed for seamless integration with classical machine learning tools like scikit-learn. The library's dual-layer architecture serves both QML researchers and practitioners, enabling efficient prototyping, experimentation, and pipelining. sQUlearn provides a comprehensive tool set that includes both quantum kernel methods and quantum neural networks, along with features like customizable data encoding strategies, automated execution handling, and specialized kernel regularization techniques. By focusing on NISQ-compatibility and end-to-end automation, sQUlearn aims to bridge the gap between current quantum computing capabilities and practical machine learning applications.

sQUlearn offers scikit-learn compatible high-level interfaces for various kernel methods, QNNs and quantum reservoir computing. They build on top of the low-level interfaces of the QNN engine and the quantum kernel engine. The executor is used to run experiments on simulated and real backends of the Qiskit or PennyLane frameworks.
sQUlearn offers scikit-learn compatible high-level interfaces for various kernel methods, QNNs and quantum reservoir computing. They build on top of the low-level interfaces of the QNN engine and the quantum kernel engine. The executor is used to run experiments on simulated and real backends of the PennyLane, Qiskit and Qulacs frameworks.

<p align="center">
<img width=600px alt="sQUlearn schematic" src="https://raw.githubusercontent.com/sQUlearn/squlearn/main/docs/_static/schematic.png" />
Expand Down Expand Up @@ -49,7 +49,7 @@ sQUlearn is released under the [Apache License 2.0](https://github.com/sQUlearn/
## Cite sQUlearn
If you use sQUlearn in your work, please cite our paper:

> Kreplin, D. A., Willmann, M., Schnabel, J., Rapp, F., Hagelüken, M., & Roth, M. (2023). sQUlearn - A Python Library for Quantum Machine Learning. [https://doi.org/10.48550/arXiv.2311.08990](https://doi.org/10.48550/arXiv.2311.08990)
> Kreplin, D. A., Willmann, M., Schnabel, J., Rapp, F., Hagelüken, M., & Roth, M. (2025). sQUlearn: A Python Library for Quantum Machine Learning. *IEEE Software, 42*(5), 65–72. [https://doi.org/10.1109/MS.2025.3527736](https://doi.org/10.1109/MS.2025.3527736)

## Contact
This project is maintained by the quantum computing group at the Fraunhofer Institute for Manufacturing Engineering and Automation IPA.
Expand Down
Binary file modified docs/_static/schematic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/_static/util/executor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ def setup(app):
# intersphinx
intersphinx_mapping = {
"pennylane": ("https://docs.pennylane.ai/en/stable/", None),
"qiskit": ("https://docs.quantum.ibm.com/api/qiskit/", None),
"qiskit": ("https://quantum.cloud.ibm.com/docs/api/qiskit/", None),
"qiskit-aer": ("https://qiskit.github.io/qiskit-aer/", None),
"qiskit-ibm-runtime": ("https://docs.quantum.ibm.com/api/qiskit-ibm-runtime/", None),
"qiskit-ibm-runtime": ("https://quantum.cloud.ibm.com/docs/api/qiskit-ibm-runtime/", None),
"scipy": ("https://docs.scipy.org/doc/scipy/", None),
"sklearn": ("https://scikit-learn.org/stable/", None),
}
Expand Down
29 changes: 15 additions & 14 deletions docs/install/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@ Prerequisites
sQUlearn requires a recent python3 (>=3.9) installation.
Additionally the following python packages are necessary: ::

bayesian-optimization>=1.4.3,<2
dill>=0.3.4
mapomatic>=0.10.0
networkx>=3.0
numpy>=1.20
pennylane>=0.34.0
qiskit>=0.45.0
qiskit-aer>=0.12.0
qiskit-algorithms>=0.3.0
qiskit-ibm-runtime>=0.18.0
qiskit-machine-learning>=0.7.0
scipy>=1.8.0
scikit-learn>=1.2.0,<1.4.2
tqdm>=4.1.0
bayesian-optimization>=1.4.3,<2,
dill>=0.3.4,
mapomatic>=0.10.0,
networkx>=3.0,
numpy>=1.20,
pennylane>=0.34.0,
qiskit>=0.45.0,<2,
qiskit-aer>=0.12.0,
qiskit-algorithms>=0.3.0,
qiskit-ibm-runtime>=0.18.0,
qiskit-machine-learning>=0.7.0,
scipy>=1.8.0,
scikit-learn>=1.2.0,
tqdm>=4.1.0,
qulacs>=0.6.0,

The packages are automatically installed when installing sQUlearn with pip.

Expand Down
23 changes: 15 additions & 8 deletions docs/modules/classes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -199,11 +199,12 @@ QNN Core
:template: class.rst

qnn.lowlevel_qnn.LowLevelQNN
qnn.lowlevel_qnn.lowlevel_qnn_qiskit.LowLevelQNNQiskit
qnn.lowlevel_qnn.lowlevel_qnn_qiskit.Expec
qnn.lowlevel_qnn.lowlevel_qnn_pennylane.LowLevelQNNPennyLane
qnn.lowlevel_qnn.lowlevel_qnn_qiskit.LowLevelQNNQiskit
qnn.lowlevel_qnn.lowlevel_qnn_qulacs.LowLevelQNNQulacs
qnn.lowlevel_qnn.lowlevel_qnn_base.LowLevelQNNBase
qnn.loss.SquaredLoss
qnn.loss.CrossEntropyLoss
qnn.loss.VarianceLoss
qnn.loss.ODELoss
qnn.loss.ParameterRegularizationLoss
Expand Down Expand Up @@ -274,6 +275,18 @@ PennyLane interface

util.pennylane.PennyLaneCircuit

Qulacs interface
------------------------------------

.. currentmodule:: squlearn

.. autosummary::
:nosignatures:
:toctree: generated/
:template: class.rst

util.qulacs.QulacsCircuit


Base Classes
------------------------------------
Expand All @@ -293,9 +306,3 @@ Base Classes
qnn.base_qnn.BaseQNN
qnn.loss.qnn_loss_base.QNNLossBase
qrc.base_qrc.BaseQRC






39 changes: 22 additions & 17 deletions docs/user_guide/encoding_circuits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ each gate is applied to all qubits.
The package facilitate a fully automated pruning algorithm to remove redundant parameters and
enables the automatic differentiation of arbitrary derivative.

The following functions and classes are are accessible via :class:`squlearn.encoding_circuit`.
The following functions and classes are accessible via :class:`squlearn.encoding_circuit`.

Implemented Quantum Encoding Circuits
--------------------------------------
Expand Down Expand Up @@ -47,8 +47,8 @@ Feel free to contribute to sQUlearn by adding your own encoding circuits in a Pu
.. jupyter-execute::

from squlearn.encoding_circuit import HubregtsenEncodingCircuit
pqc = HubregtsenEncodingCircuit(num_qubits=4, num_features=2, num_layers=2)
pqc.draw(output="mpl")
pqc = HubregtsenEncodingCircuit(num_qubits=4, num_layers=2)
pqc.draw(output="mpl", num_features=2)


Combining Quantum Encoding Circuits
Expand All @@ -67,11 +67,11 @@ equal to the sum of the parameters in the two original encoding circuits.
.. jupyter-execute::

from squlearn.encoding_circuit import HubregtsenEncodingCircuit, ChebyshevPQC
fm1 = HubregtsenEncodingCircuit(num_qubits=4, num_features=2, num_layers=1, closed=False)
fm2 = ChebyshevPQC(num_qubits=4, num_features=3, num_layers=1)
fm1 = HubregtsenEncodingCircuit(num_qubits=4, num_layers=1, closed=False)
fm2 = ChebyshevPQC(num_qubits=4, num_layers=1)
# Combining both encoding circuits
fm3 = fm1 + fm2
fm3.draw(output="mpl")
fm3.draw(output="mpl", num_features=2)


Wrapping Qiskit Encoding Circuits
Expand Down Expand Up @@ -108,14 +108,14 @@ the :class:`LayeredEncodingCircuit` class.

from squlearn.encoding_circuit import LayeredEncodingCircuit
from squlearn.encoding_circuit.layered_encoding_circuit import Layer
encoding_circuit = LayeredEncodingCircuit(num_qubits=4,num_features=2)
encoding_circuit = LayeredEncodingCircuit(num_qubits=4)
encoding_circuit.H()
layer = Layer(encoding_circuit)
layer.Rz("x")
layer.Ry("p")
layer.cx_entangling("NN")
encoding_circuit.add_layer(layer,num_layers=3)
encoding_circuit.draw(output="mpl")
encoding_circuit.add_layer(layer, num_layers=3)
encoding_circuit.draw(output="mpl", num_features=2)


**Example: Create your custom layered encoding circuit from a string**
Expand All @@ -124,9 +124,9 @@ the :class:`LayeredEncodingCircuit` class.

from squlearn.encoding_circuit import LayeredEncodingCircuit
encoding_circuit = LayeredEncodingCircuit.from_string(
"Ry(p)-3[Rx(p,x;=y*np.arccos(x),{y,x})-crz(p)]-Ry(p)", num_qubits=4, num_features=1, num_layers=2
"Ry(p)-3[Rx(p,x;=y*np.arccos(x),{y,x})-crz(p)]-Ry(p)", num_qubits=4, num_layers=2
)
encoding_circuit.draw(output="mpl")
encoding_circuit.draw(output="mpl", num_features=1)


Pruning of Quantum Encoding Circuits
Expand All @@ -152,6 +152,7 @@ sQUlearn features a fully automated pruning algorithm which can be used by calli
from squlearn.encoding_circuit import LayeredEncodingCircuit, automated_pruning
from squlearn.util import Executor
encoding_circuit = LayeredEncodingCircuit.from_string("Rz(p)-Ry(p)-Z-Ry(p)-Rz(p)", num_qubits=2, num_features=0)
encoding_circuit._build_layered_pqc(0)
pruned_encoding_circuit = automated_pruning(encoding_circuit, Executor())
pruned_encoding_circuit.draw(output="mpl")

Expand Down Expand Up @@ -184,8 +185,8 @@ is utilized for the arithmetic operations of the derivatives.
.. jupyter-execute::

from squlearn.encoding_circuit import HubregtsenEncodingCircuit, EncodingCircuitDerivatives
fm = HubregtsenEncodingCircuit(num_qubits=2, num_features=2, num_layers=2)
fm_deriv = EncodingCircuitDerivatives(fm)
fm = HubregtsenEncodingCircuit(num_qubits=2, num_layers=2)
fm_deriv = EncodingCircuitDerivatives(fm, num_features=2)
# From String (gradient of the parameter vector)
grad_from_string = fm_deriv.get_derivative("dp")
# From Tuple (second order derivative of the parameter vector; equal to the Hessian)
Expand All @@ -202,8 +203,7 @@ To transpile a quantum encoding circuit, you can leverage the functionality prov
:class:`TranspiledEncodingCircuit` class. By utilizing this class, you can input an existing
quantum encoding circuit and have its circuit transpiled according to the specified backend and
transpiler settings, which are the same settings used in Qiskit.
The transpiled encoding circuit is internally employed in the QNN program and projected kernels,
where it is employed internally.
The transpiled encoding circuit is internally employed in the QNN program and projected kernels.

**Example: Transpile a existing Encoding Circuit to a fake backend**

Expand All @@ -212,6 +212,11 @@ where it is employed internally.
from squlearn.encoding_circuit import TranspiledEncodingCircuit,ChebyshevRx
from qiskit_ibm_runtime.fake_provider import FakeManilaV2

fm = TranspiledEncodingCircuit(ChebyshevRx(3,1),backend=FakeManilaV2(),initial_layout=[0,1,4])
fm.draw(output="mpl")
fm = TranspiledEncodingCircuit(
ChebyshevRx(3,1),
backend=FakeManilaV2(),
num_features=1,
initial_layout=[0,1,4]
)
fm.draw(output="mpl", num_features=1)

15 changes: 10 additions & 5 deletions docs/user_guide/executor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The :class:`Executor <squlearn.Executor>` class is the central component of sQUl
for running all quantum jobs.
Both high- and low-level methods utilize the :class:`Executor <squlearn.Executor>` class to execute circuits or to run other
quantum jobs.
The class provides a high-level interface to the simulators of PennyLane and Qiskit,
The class provides a high-level interface to the simulators of PennyLane, Qiskit and Qulacs,
as well as manages access to real QC hardware as for example IBM Quantum.
It features a variety of comfort features, such as result caching,
automatic restarts of failed jobs, logging of all actions, and Qiskit Session handling.
Expand Down Expand Up @@ -93,7 +93,8 @@ execution environment:

- A string specifying the local simulator backend: Qiskit's :class:`AerSimulator <qiskit_aer.AerSimulator>` is available by providing ``"qiskit"``,
``"statevector_simulator"`` and ``"qasm_simulator"``; PennyLane's :class:`DefaultQubit <pennylane.devices.default_qubit.DefaultQubit>` simulator can be initialized by
``"pennylane"`` or ``"default.qubit"``. Note that with Qiskit version 1.2, the sampler routines will always performe shots for the ``"statevector_simulator"`` keyword.
``"pennylane"`` or ``"default.qubit"``. The Qulacs statevector simulator can be used with the keyword ``"qulacs"``.
Note that with Qiskit version 1.2, the sampler routines will always performe shots for the ``"statevector_simulator"`` keyword.

.. jupyter-execute::

Expand All @@ -113,6 +114,9 @@ execution environment:
# Initialize the Executor with the PennyLane shot-based simulator
executor = Executor("default.qubit", shots=1234)

# Initialize the Executor with the Qulacs statevector simulator
executor = Executor("qulacs")

- A Qiskit :class:`Backend <qiskit.providers.Backend>`, e.g. a :class:`AerProvider <qiskit_aer.AerProvider>` backend or a :mod:`fake_provider <qiskit_ibm_runtime.fake_provider>` backend. This allows also the utilization
of other quantum computing backends, as long as they provide a Qiskit :class:`Backend <qiskit.providers.Backend>` class.

Expand Down Expand Up @@ -370,7 +374,7 @@ We set up a small :class:`QNNRegressor <squlearn.qnn.QNNRegressor>` example and
backends = [FakeBelemV2(), FakeAthensV2(), FakeManilaV2()]
executor = Executor(backends, shots=10000)
qnn = QNNRegressor(
ChebyshevPQC(2, 1),
ChebyshevPQC(2),
SummedPaulis(2),
executor,
SquaredLoss(),
Expand All @@ -392,15 +396,15 @@ the mode is switched to ``"speed"``. The :class:`Executor <squlearn.Executor>` i
from squlearn import Executor
from qiskit_ibm_runtime import QiskitRuntimeService
from squlearn.encoding_circuit import ChebyshevRx
from squlearn.kernel import FidelityKernel, QKRR
from squlearn.kernel.lowlevel_kernel import FidelityKernel, QKRR

# Executor is initialized with a service, and considers all available backends
# (except simulators)
service = QiskitRuntimeService(channel="ibm_quantum", token="INSERT_YOUR_TOKEN_HERE")
executor = Executor(service, auto_backend_mode="speed")

# Create a QKRR model with a FidelityKernel and the ChebyshevRx encoding circuit
qkrr = QKRR(FidelityKernel(ChebyshevRx(4,1),executor))
qkrr = QKRR(FidelityKernel(ChebyshevRx(4),executor))

# Backend is automatically selected based on the smallest queue
# All the following functions will be executed on the selected backend
Expand Down Expand Up @@ -455,6 +459,7 @@ circuits that need to be transpiled.
* `Qsikit Primitives <https://docs.quantum.ibm.com/api/qiskit/primitives>`_
* `Mapomatic: Automatic mapping of compiled circuits to low-noise sub-graphs <https://github.com/qiskit-community/mapomatic>`_
* `PennyLane Devices <https://docs.pennylane.ai/en/stable/code/api/pennylane.device.html>`_
* `Qulacs <http://docs.qulacs.org/en/latest>`_

.. rubric:: References

Expand Down
6 changes: 3 additions & 3 deletions docs/user_guide/kernel_methods.rst
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ In sQUlearn a FQK (instance) can be defined as shown by the following example:
from squlearn.util import Executor
from squlearn.encoding_circuit import ChebyshevPQC
from squlearn.kernel import FidelityKernel
enc_circ = ChebyshevPQC(num_qubits=4, num_features=1, num_layers=2)
enc_circ = ChebyshevPQC(num_qubits=4, num_layers=2)
fqk_instance = FidelityKernel(
encoding_circuit=enc_circ,
executor=Executor()
Expand Down Expand Up @@ -211,7 +211,7 @@ the following example:
from squlearn.util import Executor
from squlearn.encoding_circuit import ChebyshevPQC
from squlearn.kernel import ProjectedQuantumKernel
enc_circ = ChebyshevPQC(num_qubits=4, num_features= 1, num_layers=2)
enc_circ = ChebyshevPQC(num_qubits=4, num_layers=2)
pqk_instance = ProjectedQuantumKernel(
encoding_circuit=enc_circ,
executor=Executor(),
Expand Down Expand Up @@ -255,7 +255,7 @@ training and test data and shows how to optimize kernels.
from squlearn.kernel.loss import TargetAlignment

# set up the encoding circuit
encoding_circuit = ChebyshevPQC(num_qubits=4, num_features=1, num_layers=2)
encoding_circuit = ChebyshevPQC(num_qubits=4, num_layers=2)

# set up the quantum kernel
pqk_instance = ProjectedQuantumKernel(encoding_circuit, Executor())
Expand Down
7 changes: 6 additions & 1 deletion docs/user_guide/observables.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,12 @@ The map can be for example obtained in the transpiled encoding circuit.
from squlearn.encoding_circuit import ChebyshevRx,TranspiledEncodingCircuit
from squlearn.observables import SummedPaulis
from qiskit_ibm_runtime.fake_provider import FakeManilaV2
fm = TranspiledEncodingCircuit(ChebyshevRx(3,1),backend=FakeManilaV2(),initial_layout=[0,1,4])
fm = TranspiledEncodingCircuit(
ChebyshevRx(3,1),
backend=FakeManilaV2(),
num_features=1,
initial_layout=[0,1,4]
)
ob = SummedPaulis(num_qubits=3, op_str="Z")
print("Observable before mapping:\n",ob,"\n\n")
ob.set_map(fm.qubit_map, fm.num_physical_qubits)
Expand Down
Loading