Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration with qiskit-symb #313

Merged
merged 41 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
1a4dbad
add support for qiskit-symb
gcattan Sep 17, 2024
2c2aa34
temp fix (as per Simone suggestion)
gcattan Sep 18, 2024
55aa1f4
fix feature map
gcattan Sep 25, 2024
5d916e5
solution with threads
gcattan Sep 25, 2024
26d972c
working solution with a dumping statevector
gcattan Sep 25, 2024
443864d
add param_prefix to gen_x_featuremap
gcattan Sep 25, 2024
57e1e37
param prefix for all feature maps
gcattan Sep 25, 2024
f8a378e
clean SymFidelityStatevectorKernel
gcattan Sep 25, 2024
57fe9b1
add documentation
gcattan Sep 26, 2024
086a580
add some common feature maps
gcattan Sep 26, 2024
da13991
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 26, 2024
0600c8b
edge case for pegasos implementation
gcattan Sep 27, 2024
bdb799d
flake8
gcattan Sep 27, 2024
5440d47
fix typo
gcattan Sep 27, 2024
0a6d6ed
add qiskit-symb as an optional dependency
gcattan Sep 29, 2024
44d875a
fix no bare exception
gcattan Sep 29, 2024
ba0877a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 29, 2024
9a649fd
Update deploy_ghpages.yml
gcattan Sep 29, 2024
567c6f1
Update pyriemann_qiskit/utils/hyper_params_factory.py
gcattan Sep 30, 2024
10a385e
Update pyriemann_qiskit/utils/hyper_params_factory.py
gcattan Sep 30, 2024
e3f101b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 30, 2024
783d6e2
Update pyriemann_qiskit/utils/quantum_provider.py
gcattan Sep 30, 2024
25007ee
Update pyriemann_qiskit/utils/quantum_provider.py
gcattan Sep 30, 2024
c83c93b
Update pyriemann_qiskit/utils/hyper_params_factory.py
gcattan Sep 30, 2024
087a490
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 30, 2024
aec2678
correct workflow file
gcattan Sep 30, 2024
3ec4e13
tentative to fix error in workflow
gcattan Sep 30, 2024
9a9103e
fix workflow: wrong directory
gcattan Sep 30, 2024
0475525
simplify workflow file
gcattan Sep 30, 2024
37c876c
revert changes to workflow back.
gcattan Sep 30, 2024
ec94c95
create missing cache `symb_statevectors` inside doc
gcattan Sep 30, 2024
f08a599
second version (not passed as a prebuilt command)
gcattan Sep 30, 2024
1244195
add debug trace
gcattan Sep 30, 2024
de4bd0f
joblib result assignation read-only when started from within another …
gcattan Oct 1, 2024
29a90b9
simplify workflow
gcattan Oct 1, 2024
7b2663a
disable multithreading for financial data too
gcattan Oct 1, 2024
d20b3fb
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2024
47f1054
fix version of symengine for serialization
gcattan Oct 1, 2024
661a728
improve simulation time for plot_financial_data
gcattan Oct 1, 2024
bf43d2e
Missing flag to deactivate qiskit_symb
gcattan Oct 1, 2024
56227cb
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2024
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
7 changes: 6 additions & 1 deletion .github/workflows/deploy_ghpages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ jobs:
with:
path: ~/.cache/pip
key: deploy_ghpages.yml
- name: Copy feature maps
run: |
cp -a ./symb_statevectors/. ./examples/ERP/symb_statevectors
cp -a ./symb_statevectors/. ./examples/MI/symb_statevectors
cp -a ./symb_statevectors/. ./examples/other_datasets/symb_statevectors
cp -a ./symb_statevectors/. ./examples/toys_dataset/symb_statevectors
- name: Generate HTML docs
env:
FIREBASE_CERTIFICATE: ${{ secrets.FIREBASE_CERTIFICATE }}
Expand All @@ -33,7 +39,6 @@ jobs:
python -m pip install --upgrade pip
apt-get -y install --fix-missing git-core
apt-get -y install build-essential
pip install -r doc/requirements.txt
- name: Upload generated HTML as artifact
uses: actions/upload-artifact@v4
with:
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,21 @@ To check the installation, open a python shell and type:
import pyriemann_qiskit
```

To enable Qiskit GPU optimization when using quantum simulation, run:
To enable Qiskit GPU optimization (for Linux) when using quantum simulation, run:

```
pip install .[optim_linux]
```

To use symbolic quantum simulation, run:

```
pip install .[optim]
```

Which will enable [qiskit-symb](https://github.com/SimoneGasperini/qiskit-symb)
integration.

Note, Qiskit only provide binaries for Linux. For other platforms, or if you want to
enable specific NVIDIA optimization for quantum, you need to build the binary
[yourself](https://github.com/Qiskit/qiskit-aer/blob/main/CONTRIBUTING.md#building-with-gpu-support).
Expand Down
2 changes: 2 additions & 0 deletions doc/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ moabb==1.1.0
pyriemann==0.6
docplex>=2.21.207
firebase_admin==6.5.0
qiskit-symb
symengine==0.11.0
5 changes: 4 additions & 1 deletion examples/ERP/plot_classify_P300_bi.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@
# the non-qunatum SVM version used in qiskit
# On a real Quantum computer (n_components = qubits)
dim_red=PCA(n_components=5),
# params={'q_account_token': '<IBM Quantum TOKEN>'}
params={
"n_jobs": 1, # Number of jobs for the simulator
# 'q_account_token': '<IBM Quantum TOKEN>'
},
)

# Here we provide a pipeline for comparison:
Expand Down
11 changes: 10 additions & 1 deletion examples/other_datasets/plot_financial_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
from sklearn.metrics import balanced_accuracy_score

from pyriemann_qiskit.classification import QuanticSVM
from pyriemann_qiskit.utils.hyper_params_factory import gen_zz_feature_map
from pyriemann_qiskit.utils.preprocessing import NdRobustScaler

print(__doc__)
Expand Down Expand Up @@ -370,7 +371,15 @@ def transform(self, X):
# for the quantum SVM as for the classical one.
gs.best_estimator_.steps[-1] = (
"quanticsvm",
QuanticSVM(quantum=True, C=best_C, gamma=best_gamma, seed=42),
QuanticSVM(
quantum=True,
C=best_C,
gamma=best_gamma,
gen_feature_map=gen_zz_feature_map(),
seed=42,
n_jobs=1,
use_qiskit_symb=False,
),
)
train_pred_qsvm = gs.best_estimator_.fit(X_train, y_train).predict(X_train)
train_score_qsvm = balanced_accuracy_score(y_train, train_pred_qsvm)
Expand Down
25 changes: 21 additions & 4 deletions pyriemann_qiskit/classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class QuanticClassifierBase(BaseEstimator, ClassifierMixin):
If true, will output all intermediate results and logs.
shots : int, default=1024
Number of repetitions of each circuit, for sampling.
gen_feature_map : Callable[int, QuantumCircuit | FeatureMap], \
gen_feature_map : Callable[[int, str], QuantumCircuit | FeatureMap], \
default=Callable[int, ZZFeatureMap]
Function generating a feature map to encode data into a quantum state.
seed : int | None, default=None
Expand Down Expand Up @@ -326,6 +326,9 @@ class QuanticSVM(QuanticClassifierBase):
Predict is now using predict_proba with a softmax, when using QSVC.
.. versionchanged:: 0.3.0
Add use_fidelity_state_vector_kernel parameter
.. versionchanged:: 0.4.0
Add n_jobs and use_qiskit_symb parameter
for SymbFidelityStatevectorKernel

Parameters
----------
Expand Down Expand Up @@ -357,17 +360,24 @@ class QuanticSVM(QuanticClassifierBase):
If true, will output all intermediate results and logs.
shots : int, default=1024
Number of repetitions of each circuit, for sampling.
gen_feature_map : Callable[int, QuantumCircuit | FeatureMap], \
gen_feature_map : Callable[[int, str], QuantumCircuit | FeatureMap], \
default=Callable[int, ZZFeatureMap]
Function generating a feature map to encode data into a quantum state.
seed : int | None, default=None
Random seed for the simulation
use_fidelity_state_vector_kernel: boolean (default=True)
use_fidelity_state_vector_kernel: boolean, default=True
if True, use a FidelitystatevectorKernel for simulation.
use_qiskit_symb: boolean, default=True
This flag is used only if qiskit-symb is installed, and pegasos is False.
If True and the number of qubits < 9, then qiskit_symb is used.
n_jobs: boolean
The number of jobs for the qiskit-symb fidelity state vector
(if applicable)

See Also
--------
QuanticClassifierBase
SymbFidelityStatevectorKernel

References
----------
Expand Down Expand Up @@ -405,6 +415,8 @@ def __init__(
gen_feature_map=gen_zz_feature_map(),
seed=None,
use_fidelity_state_vector_kernel=True,
use_qiskit_symb=True,
n_jobs=4,
):
QuanticClassifierBase.__init__(
self, quantum, q_account_token, verbose, shots, gen_feature_map, seed
Expand All @@ -414,14 +426,19 @@ def __init__(
self.max_iter = max_iter
self.pegasos = pegasos
self.use_fidelity_state_vector_kernel = use_fidelity_state_vector_kernel
self.n_jobs = n_jobs
self.use_qiskit_symb = use_qiskit_symb

def _init_algo(self, n_features):
self._log("SVM initiating algorithm")
if self.quantum:
quantum_kernel = get_quantum_kernel(
self._feature_map,
self.gen_feature_map,
self._quantum_instance,
self.use_fidelity_state_vector_kernel,
self.use_qiskit_symb and not self.pegasos,
self.n_jobs,
)
if self.pegasos:
self._log("[Warning] `gamma` is not supported by PegasosQSVC")
Expand Down Expand Up @@ -496,7 +513,7 @@ class QuanticVQC(QuanticClassifierBase):
If true, will output all intermediate results and logs
shots : int, default=1024
Number of repetitions of each circuit, for sampling
gen_feature_map : Callable[int, QuantumCircuit | FeatureMap], \
gen_feature_map : Callable[[int, str], QuantumCircuit | FeatureMap], \
default=Callable[int, ZZFeatureMap]
Function generating a feature map to encode data into a quantum state.
seed : int | None, default=None
Expand Down
2 changes: 1 addition & 1 deletion pyriemann_qiskit/pipelines.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ class QuantumMDMVotingClassifier(BasePipeline):
If true, will output all intermediate results and logs.
shots : int (default:1024)
Number of repetitions of each circuit, for sampling.
gen_feature_map : Callable[int, QuantumCircuit | FeatureMap] \
gen_feature_map : Callable[[int, str], QuantumCircuit | FeatureMap] \
(default : Callable[int, ZZFeatureMap])
Function generating a feature map to encode data into a quantum state.

Expand Down
47 changes: 36 additions & 11 deletions pyriemann_qiskit/utils/hyper_params_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ def gen_x_feature_map(reps=2):

Returns
-------
ret : XFeatureMap
An instance of XFeatureMap.
ret : Callable[[int, str], XFeatureMap]
A callable that takes into arguments:

- the number of features
- the prefix string for the parameters
And returns an instance of XFeatureMap.

Raises
------
Expand All @@ -41,16 +45,18 @@ def gen_x_feature_map(reps=2):
Notes
-----
.. versionadded:: 0.2.0
.. versionchanged:: 0.4.0
Possibility to specify parameter prefix.
"""
if reps < 1:
raise ValueError(f"Parameter reps must be superior or equal to 1 (Got {reps})")

return lambda n_features: PauliFeatureMap(
return lambda n_features, param_prefix="x": PauliFeatureMap(
feature_dimension=n_features,
paulis=["X"],
reps=reps,
data_map_func=None,
parameter_prefix="x",
parameter_prefix=param_prefix,
insert_barriers=False,
name="XFeatureMap",
)
Expand All @@ -70,8 +76,12 @@ def gen_z_feature_map(reps=2):

Returns
-------
ret : ZFeatureMap
An instance of ZFeatureMap.
ret : Callable[[int, str], ZFeatureMap]
A callable that takes into arguments:

- the number of features
- the prefix string for the parameters
And returns an instance of ZFeatureMap.

Raises
------
Expand All @@ -86,11 +96,17 @@ def gen_z_feature_map(reps=2):
Notes
-----
.. versionadded:: 0.2.0
.. versionchanged:: 0.4.0
Possibility to specify parameter prefix.
"""
if reps < 1:
raise ValueError(f"Parameter reps must be superior or equal to 1 (Got {reps})")

return lambda n_features: ZFeatureMap(feature_dimension=n_features, reps=reps)
return lambda n_features, param_prefix="x": ZFeatureMap(
feature_dimension=n_features,
reps=reps,
parameter_prefix=param_prefix,
)


def gen_zz_feature_map(reps=2, entanglement="linear"):
Expand All @@ -114,8 +130,12 @@ def gen_zz_feature_map(reps=2, entanglement="linear"):

Returns
-------
ret : ZZFeatureMap
An instance of ZZFeatureMap.
ret : Callable[[int, str], ZZFeatureMap]
A callable that takes into arguments:

- the number of features
- the prefix string for the parameters
And returns an instance of ZZFeatureMap.

Raises
------
Expand All @@ -132,12 +152,17 @@ def gen_zz_feature_map(reps=2, entanglement="linear"):
Notes
-----
.. versionadded:: 0.0.1
.. versionchanged:: 0.4.0
Possibility to specify parameter prefix.
"""
if reps < 1:
raise ValueError(f"Parameter reps must be superior or equal to 1 (Got {reps})")

return lambda n_features: ZZFeatureMap(
feature_dimension=n_features, reps=reps, entanglement=entanglement
return lambda n_features, param_prefix="x": ZZFeatureMap(
feature_dimension=n_features,
reps=reps,
entanglement=entanglement,
parameter_prefix=param_prefix,
)


Expand Down
Loading
Loading