From 1a4dbad813a05fb2132b2d1c7050fa6762341b0c Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Tue, 17 Sep 2024 22:34:24 +0200 Subject: [PATCH 01/41] add support for qiskit-symb --- doc/requirements.txt | 1 + pyriemann_qiskit/utils/quantum_provider.py | 56 ++++++++++++++++++---- requirements.txt | 1 + setup.py | 3 +- 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/doc/requirements.txt b/doc/requirements.txt index 26d6c462..bb52688e 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -23,3 +23,4 @@ moabb==1.1.0 pyriemann==0.6 docplex>=2.21.207 firebase_admin==6.5.0 +qiskit-symb diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index 10e1fe9f..ceb2c9eb 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -2,6 +2,7 @@ providers and simulators.""" import logging +import numpy as np from qiskit_aer import AerSimulator from qiskit_aer.quantum_info import AerStatevector @@ -11,6 +12,24 @@ FidelityStatevectorKernel, FidelityQuantumKernel, ) +from qiskit_symb.quantum_info import Statevector + + +class SymbFidelityStatevectorKernel: + def __init__(self, circuit): + self.circuit = circuit + self.function = Statevector(circuit).to_lambda() + + def evaluate(self, x_vec, y_vec=None): + if y_vec is None: + y_vec = x_vec + shape = (len(x_vec), len(y_vec)) + kernel_matrix = np.empty(shape=shape) + for i, x in enumerate(x_vec): + for j, y in enumerate(y_vec): + fidelity = abs(self.function(*x, *y)[0, 0]) ** 2 + kernel_matrix[i, j] = fidelity + return kernel_matrix def get_provider(): @@ -99,6 +118,8 @@ def get_quantum_kernel(feature_map, quantum_instance, use_fidelity_state_vector_ Return an instance of FidelityQuantumKernel or FidelityStatevectorKernel (in the case of a simulation). + For simulation with a small number of qubits (< 9), qiskit-symb is used. + Parameters ---------- feature_map: QuantumCircuit | FeatureMap @@ -116,26 +137,41 @@ def get_quantum_kernel(feature_map, quantum_instance, use_fidelity_state_vector_ Notes ----- .. versionadded:: 0.3.0 + .. versionchanged:: 0.4.0 + Add support for qiskit-symb """ if use_fidelity_state_vector_kernel and isinstance( quantum_instance._backend, AerSimulator ): - logging.log( + + # For simulation: + if feature_map.num_qubits <= 9: + # With a small number of qubits, let's use qiskit-symb + # See: + # https://medium.com/qiskit/qiskit-symb-a-qiskit-ecosystem-package-for-symbolic-quantum-computation-b6b4407fa705 + kernel = SymbFidelityStatevectorKernel(circuit=feature_map) + logging.log( + logging.WARN, + """FidelityQuantumKernel skipped because of time. + As the number of qubits is low, + we will use qiskit-symb.""", + ) + else: + # For a larger number of qubits, + # we will not use FidelityQuantumKernel as it is slow. See + # https://github.com/qiskit-community/qiskit-machine-learning/issues/547#issuecomment-1486527297 + kernel = FidelityStatevectorKernel( + feature_map=feature_map, + statevector_type=AerStatevector, + shots=quantum_instance.options["shots"], + ) + logging.log( logging.WARN, """FidelityQuantumKernel skipped because of time. Using FidelityStatevectorKernel with AerStatevector. Seed cannot be set with FidelityStatevectorKernel. Increase the number of shots to diminish the noise.""", ) - - # if this is a simulation, - # we will not use FidelityQuantumKernel as it is slow. See - # https://github.com/qiskit-community/qiskit-machine-learning/issues/547#issuecomment-1486527297 - kernel = FidelityStatevectorKernel( - feature_map=feature_map, - statevector_type=AerStatevector, - shots=quantum_instance.options["shots"], - ) else: kernel = FidelityQuantumKernel( feature_map=feature_map, fidelity=ComputeUncompute(quantum_instance) diff --git a/requirements.txt b/requirements.txt index e5486b47..176d064d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,3 +14,4 @@ docplex>=2.21.207 firebase_admin==6.5.0 tqdm pandas +qiskit-symb diff --git a/setup.py b/setup.py index e636d7f0..6e0c0017 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,8 @@ 'firebase_admin==6.5.0', 'scikit-learn==1.5.1', 'tqdm', - 'pandas' + 'pandas', + 'qiskit-symb' ], extras_require={'docs': [ 'sphinx-gallery', From 2c2aa345844c35abc948309d46ddcab216a9613a Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Wed, 18 Sep 2024 08:51:25 +0200 Subject: [PATCH 02/41] temp fix (as per Simone suggestion) --- pyriemann_qiskit/utils/quantum_provider.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index ceb2c9eb..9f6ce2ef 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -149,7 +149,12 @@ def get_quantum_kernel(feature_map, quantum_instance, use_fidelity_state_vector_ # With a small number of qubits, let's use qiskit-symb # See: # https://medium.com/qiskit/qiskit-symb-a-qiskit-ecosystem-package-for-symbolic-quantum-computation-b6b4407fa705 - kernel = SymbFidelityStatevectorKernel(circuit=feature_map) + circuit = feature_map.compose(feature_map.inverse()).decompose() + from qiskit.circuit.library import ZZFeatureMap + fm1 = ZZFeatureMap(feature_dimension=feature_map.num_qubits, parameter_prefix="a") + fm2 = ZZFeatureMap(feature_dimension=feature_map.num_qubits, parameter_prefix="b") + circuit = fm1.compose(fm2.inverse()).decompose() + kernel = SymbFidelityStatevectorKernel(circuit=circuit) logging.log( logging.WARN, """FidelityQuantumKernel skipped because of time. From 55aa1f45a11924534d7233fa51ea14532aeb30fd Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Wed, 25 Sep 2024 13:23:23 +0200 Subject: [PATCH 03/41] fix feature map --- pyriemann_qiskit/utils/quantum_provider.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index 9f6ce2ef..58605b0c 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -12,6 +12,7 @@ FidelityStatevectorKernel, FidelityQuantumKernel, ) +from qiskit.circuit import Parameter from qiskit_symb.quantum_info import Statevector @@ -145,15 +146,24 @@ def get_quantum_kernel(feature_map, quantum_instance, use_fidelity_state_vector_ ): # For simulation: + print(feature_map.num_qubits) if feature_map.num_qubits <= 9: # With a small number of qubits, let's use qiskit-symb # See: # https://medium.com/qiskit/qiskit-symb-a-qiskit-ecosystem-package-for-symbolic-quantum-computation-b6b4407fa705 circuit = feature_map.compose(feature_map.inverse()).decompose() from qiskit.circuit.library import ZZFeatureMap - fm1 = ZZFeatureMap(feature_dimension=feature_map.num_qubits, parameter_prefix="a") - fm2 = ZZFeatureMap(feature_dimension=feature_map.num_qubits, parameter_prefix="b") - circuit = fm1.compose(fm2.inverse()).decompose() + # fm1 = ZZFeatureMap(feature_dimension=feature_map.num_qubits, parameter_prefix="a") + # fm2 = ZZFeatureMap(feature_dimension=feature_map.num_qubits, parameter_prefix="b") + + original_parameters = feature_map.ordered_parameters + num_param = len(original_parameters) + parameters_2 = [Parameter(f"b{i}") for i in range(num_param)] + feature_map.ordered_parameters = parameters_2 + fm2 = feature_map.inverse() + feature_map.ordered_parameters = original_parameters + circuit = feature_map.compose(fm2.inverse()).decompose() + print(circuit.num_qubits) kernel = SymbFidelityStatevectorKernel(circuit=circuit) logging.log( logging.WARN, From 5d916e5d785ff8bcff7344ec68b35c97aa4b863a Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Wed, 25 Sep 2024 16:35:11 +0200 Subject: [PATCH 04/41] solution with threads --- pyriemann_qiskit/utils/quantum_provider.py | 82 ++++++++++++++++------ 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index 58605b0c..a8568508 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -16,6 +16,9 @@ from qiskit_symb.quantum_info import Statevector +import numpy as np +import joblib + class SymbFidelityStatevectorKernel: def __init__(self, circuit): self.circuit = circuit @@ -24,15 +27,41 @@ def __init__(self, circuit): def evaluate(self, x_vec, y_vec=None): if y_vec is None: y_vec = x_vec - shape = (len(x_vec), len(y_vec)) - kernel_matrix = np.empty(shape=shape) - for i, x in enumerate(x_vec): - for j, y in enumerate(y_vec): - fidelity = abs(self.function(*x, *y)[0, 0]) ** 2 - kernel_matrix[i, j] = fidelity + + x_vec_len = len(x_vec) + y_vec_len = len(y_vec) + + is_sim = x_vec_len == y_vec_len and (x_vec == y_vec).all() + + + kernel_matrix = np.zeros((x_vec_len, y_vec_len)) + + n_thread = 4 + chunck = x_vec_len // n_thread + + def compute_fidelity_partial_matrix(i_thread): + + # for i, x in enumerate(x_vec[i_thread * chunck: (i_thread + 1) * chunck]): + for i in range(i_thread * chunck, (i_thread + 1) * chunck): + x = x_vec[i] + for j in range(i if is_sim else y_vec_len): + y = y_vec[j] + # for j, y in enumerate(y_vec[:i+1] if is_sim else y_vec): + fidelity = abs(self.function(*x, *y)[0, 0]) ** 2 + kernel_matrix[i, j] = fidelity + if is_sim: + kernel_matrix[j, i] = fidelity + return kernel_matrix + + results = joblib.Parallel( n_jobs = n_thread )( joblib.delayed( compute_fidelity_partial_matrix )( i_thread ) + for i_thread in range(n_thread) + ) + for result in results: + kernel_matrix += result return kernel_matrix + def get_provider(): """Return an IBM quantum provider. @@ -152,24 +181,37 @@ def get_quantum_kernel(feature_map, quantum_instance, use_fidelity_state_vector_ # See: # https://medium.com/qiskit/qiskit-symb-a-qiskit-ecosystem-package-for-symbolic-quantum-computation-b6b4407fa705 circuit = feature_map.compose(feature_map.inverse()).decompose() - from qiskit.circuit.library import ZZFeatureMap - # fm1 = ZZFeatureMap(feature_dimension=feature_map.num_qubits, parameter_prefix="a") - # fm2 = ZZFeatureMap(feature_dimension=feature_map.num_qubits, parameter_prefix="b") - - original_parameters = feature_map.ordered_parameters - num_param = len(original_parameters) - parameters_2 = [Parameter(f"b{i}") for i in range(num_param)] - feature_map.ordered_parameters = parameters_2 - fm2 = feature_map.inverse() - feature_map.ordered_parameters = original_parameters - circuit = feature_map.compose(fm2.inverse()).decompose() + from qiskit.circuit.library import PauliFeatureMap + + fm1 = PauliFeatureMap( + feature_dimension=feature_map.num_qubits, + paulis=["X"], + data_map_func=None, + parameter_prefix="a", + insert_barriers=False, + name="xfm", + ) + + fm2 = PauliFeatureMap( + feature_dimension=feature_map.num_qubits, + paulis=["X"], + data_map_func=None, + parameter_prefix="b", + insert_barriers=False, + name="xfm", + ) + # original_parameters = feature_map.ordered_parameters + # num_param = len(original_parameters) + # parameters_2 = [Parameter(f"b{i}") for i in range(num_param)] + # feature_map.ordered_parameters = parameters_2 + # fm2 = feature_map.inverse() + # feature_map.ordered_parameters = original_parameters + circuit = fm1.compose(fm2.inverse()).decompose() print(circuit.num_qubits) kernel = SymbFidelityStatevectorKernel(circuit=circuit) logging.log( logging.WARN, - """FidelityQuantumKernel skipped because of time. - As the number of qubits is low, - we will use qiskit-symb.""", + """Using SymbFidelityStatevectorKernel""", ) else: # For a larger number of qubits, From 26d972c42401574efe37a93d23b355ec4eec78c9 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Wed, 25 Sep 2024 17:43:02 +0200 Subject: [PATCH 05/41] working solution with a dumping statevector --- XFeatureMap-2 | Bin 0 -> 11115 bytes pyriemann_qiskit/utils/quantum_provider.py | 26 +++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 XFeatureMap-2 diff --git a/XFeatureMap-2 b/XFeatureMap-2 new file mode 100644 index 0000000000000000000000000000000000000000..967e11321b9aeccd203c1b50185e94761657848c GIT binary patch literal 11115 zcmb_iZ)_CD75CX^1GWM4$He>zP?S(W!f3 z(EGw{)%Ni=@&>sl!x#UHe^$;9FJR!ovRd7lE_tPDCA7ZaT@HgGiKAAXb1-8)2dZ<3 zch?6?#w)&a0HKa#$?m8l{m z`)076yL7x!nfB39ui(r&WvAlX_0t9CRIOUU?ZVcTbQnst|%w zg2+lK%8uKOG%#lw8uqczckY$~;qHvK$iG{1$6en&>`MWp1R~n};R5b}Jdp~-Adz=5kqe7T9#r zNm9v3WV7MKsME4p?z;2Hb=9B&=}FRET%iz}A~Y)&{xnz1h*K1duzdWX@l+nq#WhwGxdIf=p5k+oPeKDq~oDsiNdt#7MZ2LC3%k#0&z6Wx@aEOTzi?0J5LIj6# zEwEuHMkTeg^I#Ca8&!nSC?s-#Ly_?1A?kt+GfkcjazTTc17> zrOwHs2_tOBzRpJmoK-G8XwzH|XLa+@jJ2EC+?}uxJw`uSEQIl_ZZnm5T6&91!QW|w z*$LYu*2oE|v>}Ln6M#P|0Os8S_oavXB8nk9Bjs))GUHU`iu)CE~cR(`f5iOBY!~ zqLz*(3dH>m{SpzMFKDM0Yi`ABaQeIiCA=>h;`7ARm3SQT+~!9Nh&Gv{!jy4 zQvjlElf@A${!%0OwL*{t!fg%kt^yE>EYs1%(zBKu<^;C)h_|~Kj=vaPAwr(%n019A zYaH(ejeVQMo|55$26$QlusGudoM){x^a+k?)Ke0*sHr&CAZaScdzdmK8dj=^Z{T!~4H(fTM;1e8J43JHnwY)C+pxCTp7|MDS|^t_Sq`#! z>qG6r+;;D}Y+BdG={8#-A0iFy2gq~oET=o)@qjLT1)zeuw~?*TZf^sI1f#x-(TbJt z)nMbKub4!w2`kl{G~JeK9Co22Y#GFQ4)4lrW}V>%Uou6DmBaKt(8WgKh+q{=UO)Ma~{xZ>8M_ef?f-j-FG(RI*<(f*MnZDmX(%x^iyt-&*v3k~OLr&4*;iks@59!^R@*dw6NjFz{vywC7^@am)K zkKmF<`~!(tWIAG9Ysf0%6c$1)-Zxsudq)F&r~pJ8r}tGD(&BnTiYq0<`!s;70E8l0 zQRkjDY?u?cr3u`Z1bC*S-s4&83|Zq0-_+ROlGsz?eOm+EQ2;E?xJP@|BZfY~1C9D) ziCWZD9P5Z7uZUH(a9%5x?<>WUEE4#M2DqUBL|Z3;LK$vp1n(#WNgym}fcF)EP!u*v zAe4oLE-lA{QjSyFdy@tjRRFD(;Ter!uR@S?8IEdz83iB|Wh^s9{#%O--tA4ue)wwlZhYpa#J7zUr= zhf4VApBZ+_2am3t!UH!RowupmbNpf$ta(1ZdeENZ2ZH#?6pEFOC-t!NL?bd|d_>8c zDdW+XLu30ngbvxPwsP=SoK;%g@PJGY4B&2#m4^{By)aIu4~~#o0#!0g;T1B=;Ll|G z;R7-Q(1W9~H3&mwmcz4TR=`VSR>BD~L*SEH1#>utS*zhZnKkfZGHc;FnPK=7nRW0! znMWXp>9a;)1)23wC9?ruA+r&#kl6&+$UF+aC$ky;LS_s68%={9*797t=7iAKhpXNJ zYpXkmXRi99Y(hU?Z4_ZG8ukPX(>H##Q4E$$*6g}n_QIDjubcUqvBGqzKHVt!1$N8v zow_(Jw(bBuOjnMu^JCBRqeoGy>0}W8-*%91G)j0tD?c$YKE`k1(W;(O#SdQ_T5|v0 z`)8iJcV&40^`*a=sITyf!4_;sr-G-DoWg9WScrd3&eiQ&jgDOP(I>67*;XK1Ki2S4>FYSshJcS*H^0z>kpV zRweL!lP1yMsRTPDB_w)O2|Ns@NepxV1)0W1ok*#H0l literal 0 HcmV?d00001 diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index a8568508..86294262 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -18,11 +18,25 @@ import numpy as np import joblib +import asyncio +import pickle class SymbFidelityStatevectorKernel: + def __init__(self, circuit): self.circuit = circuit - self.function = Statevector(circuit).to_lambda() + print(self.circuit) + if isinstance(self.circuit, str): + file = open(self.circuit,'rb') + sv = pickle.load(file) + else: + sv = Statevector(self.circuit) + print("Statevector created") + # file = open("binary.dat",'wb') + # pickle.dump(sv, file) + self.function = sv.to_lambda() + print("lambdify ok") + self.n = 0 def evaluate(self, x_vec, y_vec=None): if y_vec is None: @@ -31,12 +45,16 @@ def evaluate(self, x_vec, y_vec=None): x_vec_len = len(x_vec) y_vec_len = len(y_vec) + + is_sim = x_vec_len == y_vec_len and (x_vec == y_vec).all() + print(x_vec_len, y_vec_len, is_sim, self.n) + self.n = self.n+1 kernel_matrix = np.zeros((x_vec_len, y_vec_len)) - n_thread = 4 + n_thread = 1 chunck = x_vec_len // n_thread def compute_fidelity_partial_matrix(i_thread): @@ -53,6 +71,7 @@ def compute_fidelity_partial_matrix(i_thread): kernel_matrix[j, i] = fidelity return kernel_matrix + return compute_fidelity_partial_matrix(0) results = joblib.Parallel( n_jobs = n_thread )( joblib.delayed( compute_fidelity_partial_matrix )( i_thread ) for i_thread in range(n_thread) ) @@ -208,6 +227,9 @@ def get_quantum_kernel(feature_map, quantum_instance, use_fidelity_state_vector_ # feature_map.ordered_parameters = original_parameters circuit = fm1.compose(fm2.inverse()).decompose() print(circuit.num_qubits) + key = f"{feature_map.name}-{feature_map.reps}" + import os + circuit = key if os.path.isfile(key) else circuit kernel = SymbFidelityStatevectorKernel(circuit=circuit) logging.log( logging.WARN, From 443864d84b22b066e2af03bd5a2aa62589a7264a Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Wed, 25 Sep 2024 17:59:35 +0200 Subject: [PATCH 06/41] add param_prefix to gen_x_featuremap --- pyriemann_qiskit/classification.py | 1 + .../utils/hyper_params_factory.py | 4 +- pyriemann_qiskit/utils/quantum_provider.py | 47 ++++++++++--------- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/pyriemann_qiskit/classification.py b/pyriemann_qiskit/classification.py index 683d036b..553f9d7c 100644 --- a/pyriemann_qiskit/classification.py +++ b/pyriemann_qiskit/classification.py @@ -420,6 +420,7 @@ def _init_algo(self, n_features): if self.quantum: quantum_kernel = get_quantum_kernel( self._feature_map, + self.gen_feature_map, self._quantum_instance, self.use_fidelity_state_vector_kernel, ) diff --git a/pyriemann_qiskit/utils/hyper_params_factory.py b/pyriemann_qiskit/utils/hyper_params_factory.py index a07f09d4..dc38f618 100644 --- a/pyriemann_qiskit/utils/hyper_params_factory.py +++ b/pyriemann_qiskit/utils/hyper_params_factory.py @@ -45,12 +45,12 @@ def gen_x_feature_map(reps=2): 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", ) diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index 86294262..d2c7876c 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -12,7 +12,7 @@ FidelityStatevectorKernel, FidelityQuantumKernel, ) -from qiskit.circuit import Parameter +from qiskit.circuit import Parameter, ParameterVector from qiskit_symb.quantum_info import Statevector @@ -161,7 +161,7 @@ def get_device(provider, min_qubits): ) -def get_quantum_kernel(feature_map, quantum_instance, use_fidelity_state_vector_kernel): +def get_quantum_kernel(feature_map, gen_feature_map, quantum_instance, use_fidelity_state_vector_kernel): """Get a quantum kernel Return an instance of FidelityQuantumKernel or @@ -202,34 +202,35 @@ def get_quantum_kernel(feature_map, quantum_instance, use_fidelity_state_vector_ circuit = feature_map.compose(feature_map.inverse()).decompose() from qiskit.circuit.library import PauliFeatureMap - fm1 = PauliFeatureMap( - feature_dimension=feature_map.num_qubits, - paulis=["X"], - data_map_func=None, - parameter_prefix="a", - insert_barriers=False, - name="xfm", - ) - - fm2 = PauliFeatureMap( - feature_dimension=feature_map.num_qubits, - paulis=["X"], - data_map_func=None, - parameter_prefix="b", - insert_barriers=False, - name="xfm", - ) + # fm1 = PauliFeatureMap( + # feature_dimension=feature_map.num_qubits, + # paulis=["X"], + # data_map_func=None, + # parameter_prefix="a", + # insert_barriers=False, + # name="xfm", + # ) + + # fm2 = PauliFeatureMap( + # feature_dimension=feature_map.num_qubits, + # paulis=["X"], + # data_map_func=None, + # parameter_prefix="b", + # insert_barriers=False, + # name="xfm", + # ) # original_parameters = feature_map.ordered_parameters # num_param = len(original_parameters) - # parameters_2 = [Parameter(f"b{i}") for i in range(num_param)] + # parameters_2 = ParameterVector("b") # feature_map.ordered_parameters = parameters_2 # fm2 = feature_map.inverse() - # feature_map.ordered_parameters = original_parameters - circuit = fm1.compose(fm2.inverse()).decompose() + # feature_map.ordered_parameters =ParameterVector("a") + fm2 = gen_feature_map(feature_map.num_qubits, "b") + circuit = feature_map.compose(fm2.inverse()).decompose() print(circuit.num_qubits) key = f"{feature_map.name}-{feature_map.reps}" import os - circuit = key if os.path.isfile(key) else circuit + # circuit = key if os.path.isfile(key) else circuit kernel = SymbFidelityStatevectorKernel(circuit=circuit) logging.log( logging.WARN, From 57e1e37bca76eaa5f450aacb923fbf57464ab540 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Wed, 25 Sep 2024 18:04:43 +0200 Subject: [PATCH 07/41] param prefix for all feature maps --- .../utils/hyper_params_factory.py | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/pyriemann_qiskit/utils/hyper_params_factory.py b/pyriemann_qiskit/utils/hyper_params_factory.py index dc38f618..5fda16af 100644 --- a/pyriemann_qiskit/utils/hyper_params_factory.py +++ b/pyriemann_qiskit/utils/hyper_params_factory.py @@ -25,8 +25,11 @@ 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 ------ @@ -41,6 +44,8 @@ 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})") @@ -70,8 +75,11 @@ 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 ------ @@ -86,11 +94,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"): @@ -114,8 +128,11 @@ 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 ------ @@ -132,12 +149,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, + param_prefix=param_prefix ) From f8a378ecc09545ee9fdd86d0e997452136cbe4ad Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Wed, 25 Sep 2024 20:00:47 +0200 Subject: [PATCH 08/41] clean SymFidelityStatevectorKernel --- pyriemann_qiskit/utils/quantum_provider.py | 92 ++++++------------ .../XFeatureMap-2 | Bin 11115 -> 11121 bytes 2 files changed, 30 insertions(+), 62 deletions(-) rename XFeatureMap-2 => symb_statevectors/XFeatureMap-2 (84%) diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index d2c7876c..440b3309 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -18,25 +18,31 @@ import numpy as np import joblib -import asyncio +import os import pickle class SymbFidelityStatevectorKernel: - def __init__(self, circuit): - self.circuit = circuit - print(self.circuit) - if isinstance(self.circuit, str): - file = open(self.circuit,'rb') + def __init__(self, feature_map, gen_feature_map, n_jobs=1): + + self.n_jobs = n_jobs if n_jobs >= 1 else 1 + cached_file = os.path.join("symb_statevectors", f"{feature_map.name}-{feature_map.reps}") + + if os.path.isfile(cached_file) : + print("Loading symbolic Statevector from cache") + file = open(cached_file,'rb') sv = pickle.load(file) else: + print("Computing symbolic Statevector") + fm2 = gen_feature_map(feature_map.num_qubits, "b") + self.circuit = feature_map.compose(fm2.inverse()).decompose() sv = Statevector(self.circuit) - print("Statevector created") - # file = open("binary.dat",'wb') - # pickle.dump(sv, file) + print(f"Dumping to {cached_file}") + file = open(cached_file, 'wb') + pickle.dump(sv, file) + self.function = sv.to_lambda() - print("lambdify ok") - self.n = 0 + def evaluate(self, x_vec, y_vec=None): if y_vec is None: @@ -45,39 +51,34 @@ def evaluate(self, x_vec, y_vec=None): x_vec_len = len(x_vec) y_vec_len = len(y_vec) - - is_sim = x_vec_len == y_vec_len and (x_vec == y_vec).all() - print(x_vec_len, y_vec_len, is_sim, self.n) - self.n = self.n+1 - kernel_matrix = np.zeros((x_vec_len, y_vec_len)) - n_thread = 1 - chunck = x_vec_len // n_thread + chunck = x_vec_len // self.n_jobs def compute_fidelity_partial_matrix(i_thread): - - # for i, x in enumerate(x_vec[i_thread * chunck: (i_thread + 1) * chunck]): for i in range(i_thread * chunck, (i_thread + 1) * chunck): x = x_vec[i] for j in range(i if is_sim else y_vec_len): y = y_vec[j] - # for j, y in enumerate(y_vec[:i+1] if is_sim else y_vec): fidelity = abs(self.function(*x, *y)[0, 0]) ** 2 kernel_matrix[i, j] = fidelity if is_sim: kernel_matrix[j, i] = fidelity return kernel_matrix - return compute_fidelity_partial_matrix(0) - results = joblib.Parallel( n_jobs = n_thread )( joblib.delayed( compute_fidelity_partial_matrix )( i_thread ) - for i_thread in range(n_thread) - ) - for result in results: - kernel_matrix += result - return kernel_matrix + if self.n_jobs == 1: + return compute_fidelity_partial_matrix(0) + else: + print("n_jobs greater than 1, parallelizing") + results = joblib.Parallel(n_jobs = self.n_jobs)\ + (joblib.delayed(compute_fidelity_partial_matrix)( i_thread ) + for i_thread in range(self.n_jobs) + ) + for result in results: + kernel_matrix += result + return kernel_matrix @@ -194,44 +195,11 @@ def get_quantum_kernel(feature_map, gen_feature_map, quantum_instance, use_fidel ): # For simulation: - print(feature_map.num_qubits) if feature_map.num_qubits <= 9: # With a small number of qubits, let's use qiskit-symb # See: # https://medium.com/qiskit/qiskit-symb-a-qiskit-ecosystem-package-for-symbolic-quantum-computation-b6b4407fa705 - circuit = feature_map.compose(feature_map.inverse()).decompose() - from qiskit.circuit.library import PauliFeatureMap - - # fm1 = PauliFeatureMap( - # feature_dimension=feature_map.num_qubits, - # paulis=["X"], - # data_map_func=None, - # parameter_prefix="a", - # insert_barriers=False, - # name="xfm", - # ) - - # fm2 = PauliFeatureMap( - # feature_dimension=feature_map.num_qubits, - # paulis=["X"], - # data_map_func=None, - # parameter_prefix="b", - # insert_barriers=False, - # name="xfm", - # ) - # original_parameters = feature_map.ordered_parameters - # num_param = len(original_parameters) - # parameters_2 = ParameterVector("b") - # feature_map.ordered_parameters = parameters_2 - # fm2 = feature_map.inverse() - # feature_map.ordered_parameters =ParameterVector("a") - fm2 = gen_feature_map(feature_map.num_qubits, "b") - circuit = feature_map.compose(fm2.inverse()).decompose() - print(circuit.num_qubits) - key = f"{feature_map.name}-{feature_map.reps}" - import os - # circuit = key if os.path.isfile(key) else circuit - kernel = SymbFidelityStatevectorKernel(circuit=circuit) + kernel = SymbFidelityStatevectorKernel(feature_map, gen_feature_map, n_jobs=1) logging.log( logging.WARN, """Using SymbFidelityStatevectorKernel""", diff --git a/XFeatureMap-2 b/symb_statevectors/XFeatureMap-2 similarity index 84% rename from XFeatureMap-2 rename to symb_statevectors/XFeatureMap-2 index 967e11321b9aeccd203c1b50185e94761657848c..d4a034e35cb426cf68005ceff3c51a4785b4c2f7 100644 GIT binary patch delta 548 zcmaDI_A!j5fn{piMwVnI=89;O$&AcKljkrcF;-0e&vb#YV)F%N4@RJbAxL7gFRLm@ zl>wNuoc)%ZaZ?GbO`fPO zJDFKaR7kJ}n*#2nXrtIEty6-gWNA+h*3u9Xti`5m@@g%v$q5=FlTU(7s>7;;Pn&D< zVGVU5EH3}8p#}E-Ms;C<_7jRVw+*to=DE1Y@UjSTq9d^wg3CI?H%6$XQ+3 Xm8=0PF##*-#;$~4TNBe$9@@$P0dLNh delta 569 zcmewu_BxEEfn{pKMwVnI=EP`|$&AcKljkrcF(yv_&vbz?aq|Uc4@RJbAxL7gFRLm@ zl>wNuoc)%Z5s(u*rH7@oG&2QAg@$^%Oqo1IvvEr8lpf~Hypkzh0_<1LU8!}xG*#4h z702$-BEHF6)VvuJC#f4bBu>c^V`E^5ouZK?4WzTAfCNyhMh^?nzSt>Q@(_OQlq@A6 zt4n|b-K0QGd3mtX)+s?#vb2GUyctWTBq19#d84|Bpa3Tpoj@OcSC>^wj5fw%6&H35 z(HgQqZ5Ome1-P***sozAi0NZSO)a$~P(WdLDgRP@MQRt5mLGSjO7 From 57fe9b1b83ad10a741b63a675195b51315e2e24a Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Thu, 26 Sep 2024 13:40:39 +0200 Subject: [PATCH 09/41] add documentation --- pyriemann_qiskit/classification.py | 6 ++-- pyriemann_qiskit/pipelines.py | 2 +- pyriemann_qiskit/utils/quantum_provider.py | 42 ++++++++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/pyriemann_qiskit/classification.py b/pyriemann_qiskit/classification.py index 553f9d7c..b4eaee6c 100644 --- a/pyriemann_qiskit/classification.py +++ b/pyriemann_qiskit/classification.py @@ -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 @@ -357,7 +357,7 @@ 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 @@ -497,7 +497,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 diff --git a/pyriemann_qiskit/pipelines.py b/pyriemann_qiskit/pipelines.py index d643fa8e..ea994300 100644 --- a/pyriemann_qiskit/pipelines.py +++ b/pyriemann_qiskit/pipelines.py @@ -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. diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index 440b3309..4dca2498 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -23,6 +23,38 @@ class SymbFidelityStatevectorKernel: + """Symbolic Statevector kernel + + An implementation of the quantum kernel for classically simulated + state vectors [2]_ using qiskit-symb for symbolic representation of statevectors [1]_. + + Here, the kernel function is defined as the overlap of two simulated quantum statevectors produced + by a parametrized quantum circuit (called feature map) [2]_. + + Notes + ----- + .. versionadded:: 0.4.0 + + Parameters + ---------- + feature_map: QuantumCircuit | FeatureMap + An instance of a feature map. + gen_feature_map: Callable[[int, str], QuantumCircuit | FeatureMap], \ + default=Callable[int, ZZFeatureMap] + Function generating a feature map to encode data into a quantum state. + n_jobs: int + The number of job for fidelity evaluation. + If null or negative, the number of jobs is set to 1 + If set to 1, evaluation will run on the main thread. + + References + ---------- + .. [1] https://github.com/SimoneGasperini/qiskit-symb/issues/6 + .. [2] \ + https://github.com/qiskit-community/qiskit-machine-learning/blob/30dad803e9457f955464220eddc1e55a65452bbc/qiskit_machine_learning/kernels/fidelity_statevector_kernel.py#L31 + + """ + def __init__(self, feature_map, gen_feature_map, n_jobs=1): self.n_jobs = n_jobs if n_jobs >= 1 else 1 @@ -43,7 +75,17 @@ def __init__(self, feature_map, gen_feature_map, n_jobs=1): self.function = sv.to_lambda() + """Evaluate the quantum kernel. + + Returns + ------- + kernel : ndarray, shape (len(x_vec), len(y_vec)) + The kernel matrix. + Notes + ----- + .. versionadded:: 0.4.0 + """ def evaluate(self, x_vec, y_vec=None): if y_vec is None: y_vec = x_vec From 086a580475ce95a9e16d8bc8f0efc686b0e71e7e Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Thu, 26 Sep 2024 22:24:18 +0200 Subject: [PATCH 10/41] add some common feature maps --- pyriemann_qiskit/utils/hyper_params_factory.py | 2 +- pyriemann_qiskit/utils/quantum_provider.py | 12 ++++++------ symb_statevectors/XFeatureMap-3 | Bin 0 -> 23349 bytes symb_statevectors/ZFeatureMap-2 | Bin 0 -> 23140 bytes symb_statevectors/ZFeatureMap-3 | Bin 0 -> 34880 bytes symb_statevectors/ZZFeatureMap-2 | Bin 0 -> 26782 bytes symb_statevectors/ZZFeatureMap-3 | Bin 0 -> 40031 bytes 7 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 symb_statevectors/XFeatureMap-3 create mode 100644 symb_statevectors/ZFeatureMap-2 create mode 100644 symb_statevectors/ZFeatureMap-3 create mode 100644 symb_statevectors/ZZFeatureMap-2 create mode 100644 symb_statevectors/ZZFeatureMap-3 diff --git a/pyriemann_qiskit/utils/hyper_params_factory.py b/pyriemann_qiskit/utils/hyper_params_factory.py index 5fda16af..bc8cb743 100644 --- a/pyriemann_qiskit/utils/hyper_params_factory.py +++ b/pyriemann_qiskit/utils/hyper_params_factory.py @@ -159,7 +159,7 @@ def gen_zz_feature_map(reps=2, entanglement="linear"): feature_dimension=n_features, reps=reps, entanglement=entanglement, - param_prefix=param_prefix + parameter_prefix=param_prefix ) diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index 4dca2498..b0052923 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -26,10 +26,10 @@ class SymbFidelityStatevectorKernel: """Symbolic Statevector kernel An implementation of the quantum kernel for classically simulated - state vectors [2]_ using qiskit-symb for symbolic representation of statevectors [1]_. + state vectors [1]_ using qiskit-symb for symbolic representation of statevectors [2]_. Here, the kernel function is defined as the overlap of two simulated quantum statevectors produced - by a parametrized quantum circuit (called feature map) [2]_. + by a parametrized quantum circuit (called feature map) [1]_. Notes ----- @@ -49,10 +49,10 @@ class SymbFidelityStatevectorKernel: References ---------- - .. [1] https://github.com/SimoneGasperini/qiskit-symb/issues/6 - .. [2] \ + .. [1] \ https://github.com/qiskit-community/qiskit-machine-learning/blob/30dad803e9457f955464220eddc1e55a65452bbc/qiskit_machine_learning/kernels/fidelity_statevector_kernel.py#L31 - + .. [2] https://github.com/SimoneGasperini/qiskit-symb/issues/6 + """ def __init__(self, feature_map, gen_feature_map, n_jobs=1): @@ -241,7 +241,7 @@ def get_quantum_kernel(feature_map, gen_feature_map, quantum_instance, use_fidel # With a small number of qubits, let's use qiskit-symb # See: # https://medium.com/qiskit/qiskit-symb-a-qiskit-ecosystem-package-for-symbolic-quantum-computation-b6b4407fa705 - kernel = SymbFidelityStatevectorKernel(feature_map, gen_feature_map, n_jobs=1) + kernel = SymbFidelityStatevectorKernel(feature_map, gen_feature_map, n_jobs=4) logging.log( logging.WARN, """Using SymbFidelityStatevectorKernel""", diff --git a/symb_statevectors/XFeatureMap-3 b/symb_statevectors/XFeatureMap-3 new file mode 100644 index 0000000000000000000000000000000000000000..1f662c743fc3cce2f6e5736178eb6eef6b32019c GIT binary patch literal 23349 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 literal 0 HcmV?d00001 diff --git a/symb_statevectors/ZFeatureMap-2 b/symb_statevectors/ZFeatureMap-2 new file mode 100644 index 0000000000000000000000000000000000000000..2c38862772308de14a42f7f83789e18ca256c2ac GIT binary patch literal 23140 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 literal 0 HcmV?d00001 diff --git a/symb_statevectors/ZFeatureMap-3 b/symb_statevectors/ZFeatureMap-3 new file mode 100644 index 0000000000000000000000000000000000000000..9029640450f91a0ec3e423a849e32e7dd5f65237 GIT binary patch literal 34880 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 UR!T&h{IXVl=@DPD1DVGE11TscG5`Po literal 0 HcmV?d00001 diff --git a/symb_statevectors/ZZFeatureMap-2 b/symb_statevectors/ZZFeatureMap-2 new file mode 100644 index 0000000000000000000000000000000000000000..085b894354aa45b5a20302998baf9ed102243e3e GIT binary patch literal 26782 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 WTujHw;3WMxLqE>pkNj}1{r>=;lhLvO literal 0 HcmV?d00001 diff --git a/symb_statevectors/ZZFeatureMap-3 b/symb_statevectors/ZZFeatureMap-3 new file mode 100644 index 0000000000000000000000000000000000000000..c0590a04f9bb551ed4461117d610c3b83133e9f7 GIT binary patch literal 40031 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%0AHWU~geq$(g9$K1Y>vnDsLR zYv_I{MMeVAz3P}==qMH#eyItM$7Ut;EVL>trXVjZi+VeQ2~qQ6gPUXg((J_sY(|i% z>020Ak{YPIQwz4`@Y}&S0YCXcJ!Km!2RSXVe3?afW00lzWD}Lri$e*$St4&QwJzC7 z^Al3!5M9dkN2A zdyqXj$VtpiZXYEohs)w?P@ZfmU(=iP#k7TqADLE!ZvA~bP4(Q*;@=%W$P7a{D9>x0 z;%QS%qE+wh6`Z0(735l~W&>284&=+WR zDSaiGqJNO)Cq#ZFz>yg_^jlh;@E}<{q4rBO?yH@&LmL@8K76=gopjTb&9w+qX<@P3 zqnvD*_-cLAMd>(`*YEj4BOpp#68NwPr)T3_$dUj-xck12ki-&}+N}f-WcT>>2s)ED zG9?ZI3sz+?BI4nUGEP8HTxLMyXT2gf+iaT&m5F)Tws5wvt~~10GT4SOk+eGkm;&Zx zl&s)%`*#sip2p8h8ZIT#ep~P!#);(J#}ENY`9X}#BUGqS<8j<@c~I{HdB%y0^nZrM zxC=%?j?f0&%#l#0EzNTlJA5aNQ?%S1lU-mB?Mw;WqcpB@bD9Z9u*p$fGe~y7u9JJw z0t*l?N^zq~k#|TzFHKFnx(cIW1=$mGmMx~JgYcr z$;8)6+t?)3`R&n2u_gkpn&}4PGd87sf^A^UO!WZCx9u*-#k(hDeL;4HsY_-+wIe|VKzBU;TY|HUgf;o&ZKo9i;v4BZbUfZ z80Zg6Db!mv47q{ETUiCLQ<5iO4#>?UmfjZVz@-A3Z3}QLhxkF{z4k8B7`%W?9s zKktid%~m)(tJ3WC(j-cP!z$vK7ZDO`@;nEfVmR){+-xLImPIOJxfc;;H*Vv=L z_j%wEgjo#-Rm5R0BBT@a&$F}NC^)JBk9&YA3hh(l1=*2}7?0?e(`;q25N|{$_Kf9Q zDv%Xs%Z?+TOC7?YP!(nq2?C2`aZ2zu914Te>ms2NlZ1U5_IM1Nh=(rei_p0hhjQqM zqW;6Q9OquCBA9$*Y_(ozdr)O7@)PXP2+t}6eNuU^eAt#Dv;7+PC54-_?4eDpDk65` zkQOn}PmTa%*yQ6t^k@+rpCSJ)O<}&Gkn2euyhH`3Jt;+a&1Z#8%Wu`#Ju!C5m{lD& z8pkD$)%4MkvM93*b=<7eZc%9q9lA{;>`(~Gp^*e3sa+cKc?Fqg&OJJKp9&^EfjQ*| zd3`Dxl3j_e+J>VVSYW;eHOa_G3mFe$KSRh(ValNHNg?U> zC?_+IuUXS6T|%{^LW9bb8N?-l4{g)Cb6fkf0 zf&@khDNo}Kl7>r3wBHuInQHui~Cw6;4E@?leWS} zn&c_S>L28Bg^-YkSDlrqgXHiwbB0_<lhXi}oX%XwTOXbFR762qSNAm;}2 zuT|h58}t9tBmX(S^sg!g<;_OJ+48y3hq4iu!n8?_(?zIf7_luIQ3Vv~x=+Cz_h1r{ z&?TK1D-9{C$*^3BY2sK$6@TkJt?qQ{} z?^F@HyofM+;3^{vSu5TpYu)4NFO!p`Ch?;60PZTea^bRvi8u!?1BfSwosNZgV!zI(Ra}wA480l_b)zDh{2T zz_5WJV$E3MO>#5s;8VB)*oHGvh`+{*ZBwy>|2CUvg*cUAS`vai!B;pe2aO1`9nBqV zO{tx&O?&DN^3;hx#KC$E`JjUI?8oLbThtC6{HzKNJo=g*+^|pQKM?0n>3CSj9f{-g zwxUeOS_H=?9M|BJ$(2Eq@)Ye5JBl-AsNg`+f?pyA+F8}Y_|Pfm(8=Q{&a?ENeEf( zd$b_?NRZaft%EexvkTXJm?2){bL*I9+eY##wyGP!a)7B6l;GXTV8Xk=!Dq1I@Mjo? zjRU;2vR!Y?=Gn$gWtf&42X{ykad0mVouq?D2_o;@+8{U64xYvpz*d}zLVN-*tqAd% zY@QY3OonMm2zGF@E9}r8H}%k)oXy^Yg55NWpJl!GZ)VarLK@2y@y6~zU|cK^Z`a_Zr{YoBMezmIHprfrAGl@I{%%FaFNZXsfjulFofKs z{#yg{+X6I_IS60n1;IWb$F(%W4H?XY?qm`6`nWJIvAD}tf2I`2$ zJ9YA1DtUsrm0>qcO=!G_A>`%>XnY_C{7@RaP~#&Q6KQ;uVOrF?JTM}2Iq?Y}tNE zLZ-uibvWlO#QEn~Pg$4_hH2_l^12JvUygBa~P&6XMdlBPA$j~38G%*MZU0wZ>OoA-*}bpWeD#3 z$q6hA=ZI$8M)E4QsvBIiGvxeNJAU*rBIn5TeO9$^!!ND&3nx5ToNauek z&L358cpueq$KyDyqcR<95uBVbRU9SF?Zly=x&DG?6vJ$m4xX!m14Ro~{rT)t_&#Ew z*^di4`8I#mcb)5>TQeA@C9}g}Nh0+hqY_T4_0WlwR0DX`&y}0$Reu3j0E=)Y3i0l& zz-H&x`?Gm=)nCXkEeRn@?0^>J5DB7Ag2<|N|35-gy#>fMA7u#H|4&L_VcRa!Nc%c) zNV8SlU?W@JGbt#+dp3g!?*a$EjunRrhGFB@UFiQ zRRjH{zG|(jymoM?T&wjBREJ7y>|mpQ_VqHlw6x|rGqv$><5K(7d2eG*eZo+Auu-4x zBleeuhx%5QYhATf{f+vB_g!~`4WZv4=;$5~m*Ly>-EA3% zC|yp0XXtV&e3>q%!6kTXcDF+pU8cZdx||O0r^^}e09~fS7P?G>&(h^g_yS$df@^T8 zba%iz>2fxd=yDFMrpvkTDY|sR6LdKbzD}3v@Ljr`4_Bgg-7{bzT`quI=yD;fqRZ>x z5xUHT?R2>ap2N!ssWGWmDGinz@J~2UnbLi6<@E0H^~sr<@GY9w1N-q}X21{VJ3Bhk zQ$Jn-Uu)csNHg#5tKHQ%+_kcAXypiA&8_lqd1$n}a(G~&O{S6MX5{+S z<^FPYIFp+G94G!|ochF(k-k-US+;EPb@tZ1*pfb+xB1LBJazLMulm)-=RUmT$2WZI z$j+s;p87@D$8z<~zG}H^bze`H{Ip`tP-$?mjA`3f50qA|=qc6uRwCZDGw>gFn=%f+ zdtSQVN zK;;x|aSHr Date: Thu, 26 Sep 2024 20:33:27 +0000 Subject: [PATCH 11/41] [pre-commit.ci] auto fixes from pre-commit.com hooks --- .../utils/hyper_params_factory.py | 2 +- pyriemann_qiskit/utils/quantum_provider.py | 51 ++++++++++--------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/pyriemann_qiskit/utils/hyper_params_factory.py b/pyriemann_qiskit/utils/hyper_params_factory.py index bc8cb743..c4ebe21a 100644 --- a/pyriemann_qiskit/utils/hyper_params_factory.py +++ b/pyriemann_qiskit/utils/hyper_params_factory.py @@ -159,7 +159,7 @@ def gen_zz_feature_map(reps=2, entanglement="linear"): feature_dimension=n_features, reps=reps, entanglement=entanglement, - parameter_prefix=param_prefix + parameter_prefix=param_prefix, ) diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index b0052923..efde9341 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -21,6 +21,7 @@ import os import pickle + class SymbFidelityStatevectorKernel: """Symbolic Statevector kernel @@ -52,17 +53,18 @@ class SymbFidelityStatevectorKernel: .. [1] \ https://github.com/qiskit-community/qiskit-machine-learning/blob/30dad803e9457f955464220eddc1e55a65452bbc/qiskit_machine_learning/kernels/fidelity_statevector_kernel.py#L31 .. [2] https://github.com/SimoneGasperini/qiskit-symb/issues/6 - + """ def __init__(self, feature_map, gen_feature_map, n_jobs=1): - self.n_jobs = n_jobs if n_jobs >= 1 else 1 - cached_file = os.path.join("symb_statevectors", f"{feature_map.name}-{feature_map.reps}") + cached_file = os.path.join( + "symb_statevectors", f"{feature_map.name}-{feature_map.reps}" + ) - if os.path.isfile(cached_file) : + if os.path.isfile(cached_file): print("Loading symbolic Statevector from cache") - file = open(cached_file,'rb') + file = open(cached_file, "rb") sv = pickle.load(file) else: print("Computing symbolic Statevector") @@ -70,7 +72,7 @@ def __init__(self, feature_map, gen_feature_map, n_jobs=1): self.circuit = feature_map.compose(fm2.inverse()).decompose() sv = Statevector(self.circuit) print(f"Dumping to {cached_file}") - file = open(cached_file, 'wb') + file = open(cached_file, "wb") pickle.dump(sv, file) self.function = sv.to_lambda() @@ -86,6 +88,7 @@ def __init__(self, feature_map, gen_feature_map, n_jobs=1): ----- .. versionadded:: 0.4.0 """ + def evaluate(self, x_vec, y_vec=None): if y_vec is None: y_vec = x_vec @@ -94,9 +97,9 @@ def evaluate(self, x_vec, y_vec=None): y_vec_len = len(y_vec) is_sim = x_vec_len == y_vec_len and (x_vec == y_vec).all() - + kernel_matrix = np.zeros((x_vec_len, y_vec_len)) - + chunck = x_vec_len // self.n_jobs def compute_fidelity_partial_matrix(i_thread): @@ -109,21 +112,20 @@ def compute_fidelity_partial_matrix(i_thread): if is_sim: kernel_matrix[j, i] = fidelity return kernel_matrix - + if self.n_jobs == 1: return compute_fidelity_partial_matrix(0) else: print("n_jobs greater than 1, parallelizing") - results = joblib.Parallel(n_jobs = self.n_jobs)\ - (joblib.delayed(compute_fidelity_partial_matrix)( i_thread ) - for i_thread in range(self.n_jobs) - ) + results = joblib.Parallel(n_jobs=self.n_jobs)( + joblib.delayed(compute_fidelity_partial_matrix)(i_thread) + for i_thread in range(self.n_jobs) + ) for result in results: kernel_matrix += result return kernel_matrix - def get_provider(): """Return an IBM quantum provider. @@ -204,7 +206,9 @@ def get_device(provider, min_qubits): ) -def get_quantum_kernel(feature_map, gen_feature_map, quantum_instance, use_fidelity_state_vector_kernel): +def get_quantum_kernel( + feature_map, gen_feature_map, quantum_instance, use_fidelity_state_vector_kernel +): """Get a quantum kernel Return an instance of FidelityQuantumKernel or @@ -235,17 +239,18 @@ def get_quantum_kernel(feature_map, gen_feature_map, quantum_instance, use_fidel if use_fidelity_state_vector_kernel and isinstance( quantum_instance._backend, AerSimulator ): - # For simulation: if feature_map.num_qubits <= 9: # With a small number of qubits, let's use qiskit-symb # See: # https://medium.com/qiskit/qiskit-symb-a-qiskit-ecosystem-package-for-symbolic-quantum-computation-b6b4407fa705 - kernel = SymbFidelityStatevectorKernel(feature_map, gen_feature_map, n_jobs=4) + kernel = SymbFidelityStatevectorKernel( + feature_map, gen_feature_map, n_jobs=4 + ) logging.log( - logging.WARN, - """Using SymbFidelityStatevectorKernel""", - ) + logging.WARN, + """Using SymbFidelityStatevectorKernel""", + ) else: # For a larger number of qubits, # we will not use FidelityQuantumKernel as it is slow. See @@ -256,12 +261,12 @@ def get_quantum_kernel(feature_map, gen_feature_map, quantum_instance, use_fidel shots=quantum_instance.options["shots"], ) logging.log( - logging.WARN, - """FidelityQuantumKernel skipped because of time. + logging.WARN, + """FidelityQuantumKernel skipped because of time. Using FidelityStatevectorKernel with AerStatevector. Seed cannot be set with FidelityStatevectorKernel. Increase the number of shots to diminish the noise.""", - ) + ) else: kernel = FidelityQuantumKernel( feature_map=feature_map, fidelity=ComputeUncompute(quantum_instance) From 0600c8bed2423ac02864a1a395012bf8f6048920 Mon Sep 17 00:00:00 2001 From: gcattan Date: Fri, 27 Sep 2024 21:35:34 +0200 Subject: [PATCH 12/41] edge case for pegasos implementation --- pyriemann_qiskit/utils/quantum_provider.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index efde9341..f2c4545f 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -107,7 +107,12 @@ def compute_fidelity_partial_matrix(i_thread): x = x_vec[i] for j in range(i if is_sim else y_vec_len): y = y_vec[j] - fidelity = abs(self.function(*x, *y)[0, 0]) ** 2 + if isinstance(x, np.numpy.float64): + # Pegagos implementation + fidelity = abs(self.function(x, y)[0, 0]) ** 2 + else: + fidelity = abs(self.function(*x, *y)[0, 0]) ** 2 + kernel_matrix[i, j] = fidelity if is_sim: kernel_matrix[j, i] = fidelity From bdb799dd95f579b4c9c5f300cb684fbad4014969 Mon Sep 17 00:00:00 2001 From: gcattan Date: Fri, 27 Sep 2024 21:40:09 +0200 Subject: [PATCH 13/41] flake8 --- pyriemann_qiskit/utils/quantum_provider.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index f2c4545f..37103591 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -1,8 +1,11 @@ """Module containing helpers for IBM quantum backends providers and simulators.""" +import joblib import logging import numpy as np +import os +import pickle from qiskit_aer import AerSimulator from qiskit_aer.quantum_info import AerStatevector @@ -12,25 +15,19 @@ FidelityStatevectorKernel, FidelityQuantumKernel, ) -from qiskit.circuit import Parameter, ParameterVector from qiskit_symb.quantum_info import Statevector -import numpy as np -import joblib -import os -import pickle - - class SymbFidelityStatevectorKernel: """Symbolic Statevector kernel An implementation of the quantum kernel for classically simulated - state vectors [1]_ using qiskit-symb for symbolic representation of statevectors [2]_. + state vectors [1]_ using qiskit-symb for symbolic representation + of statevectors [2]_. - Here, the kernel function is defined as the overlap of two simulated quantum statevectors produced - by a parametrized quantum circuit (called feature map) [1]_. + Here, the kernel function is defined as the overlap of two simulated quantum + statevectors produced by a parametrized quantum circuit (called feature map) [1]_. Notes ----- From 5440d47f5e0d7b73e55fda71d3b3b57c06c7ef96 Mon Sep 17 00:00:00 2001 From: gcattan Date: Fri, 27 Sep 2024 21:55:37 +0200 Subject: [PATCH 14/41] fix typo --- pyriemann_qiskit/utils/quantum_provider.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index 37103591..15e34814 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -104,7 +104,7 @@ def compute_fidelity_partial_matrix(i_thread): x = x_vec[i] for j in range(i if is_sim else y_vec_len): y = y_vec[j] - if isinstance(x, np.numpy.float64): + if isinstance(x, np.float64): # Pegagos implementation fidelity = abs(self.function(x, y)[0, 0]) ** 2 else: From 0a6d6eda946f810fba6b837781c9a435a7e2f340 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Sun, 29 Sep 2024 17:14:32 +0200 Subject: [PATCH 15/41] add qiskit-symb as an optional dependency --- README.md | 10 +++++++++- pyriemann_qiskit/classification.py | 1 + pyriemann_qiskit/utils/quantum_provider.py | 23 +++++++++++++++++----- requirements.txt | 2 +- setup.py | 4 ++-- 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 785e2728..f4e1cbcb 100644 --- a/README.md +++ b/README.md @@ -123,12 +123,20 @@ 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). diff --git a/pyriemann_qiskit/classification.py b/pyriemann_qiskit/classification.py index b4eaee6c..3b23d8b6 100644 --- a/pyriemann_qiskit/classification.py +++ b/pyriemann_qiskit/classification.py @@ -423,6 +423,7 @@ def _init_algo(self, n_features): self.gen_feature_map, self._quantum_instance, self.use_fidelity_state_vector_kernel, + not self.pegasos ) if self.pegasos: self._log("[Warning] `gamma` is not supported by PegasosQSVC") diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index 15e34814..70079a05 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -15,7 +15,12 @@ FidelityStatevectorKernel, FidelityQuantumKernel, ) -from qiskit_symb.quantum_info import Statevector +try: + from qiskit_symb.quantum_info import Statevector + QISKIT_SYMB=True +except: + QISKIT_SYMB=False + class SymbFidelityStatevectorKernel: @@ -209,14 +214,19 @@ def get_device(provider, min_qubits): def get_quantum_kernel( - feature_map, gen_feature_map, quantum_instance, use_fidelity_state_vector_kernel + feature_map, + gen_feature_map, + quantum_instance, + use_fidelity_state_vector_kernel, + use_qiskit_symb ): """Get a quantum kernel Return an instance of FidelityQuantumKernel or FidelityStatevectorKernel (in the case of a simulation). - For simulation with a small number of qubits (< 9), qiskit-symb is used. + For simulation with a small number of qubits (< 9), and `use_qiskit_symb` is True, + qiskit-symb is used. Parameters ---------- @@ -225,7 +235,10 @@ def get_quantum_kernel( quantum_instance: BaseSampler A instance of BaseSampler. use_fidelity_state_vector_kernel: boolean - if True, use a FidelitystatevectorKernel for simulation. + If True, use a FidelitystatevectorKernel for simulation. + use_qiskit_symb: boolean + This flag is used only if qiskit-symb is installed. + If True and the number of qubits < 9, then qiskit_symb is used. Returns ------- @@ -242,7 +255,7 @@ def get_quantum_kernel( quantum_instance._backend, AerSimulator ): # For simulation: - if feature_map.num_qubits <= 9: + if QISKIT_SYMB and feature_map.num_qubits <= 9 and use_qiskit_symb: # With a small number of qubits, let's use qiskit-symb # See: # https://medium.com/qiskit/qiskit-symb-a-qiskit-ecosystem-package-for-symbolic-quantum-computation-b6b4407fa705 diff --git a/requirements.txt b/requirements.txt index 176d064d..9f6e94a5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,4 +14,4 @@ docplex>=2.21.207 firebase_admin==6.5.0 tqdm pandas -qiskit-symb + diff --git a/setup.py b/setup.py index 6e0c0017..b52edd1a 100644 --- a/setup.py +++ b/setup.py @@ -50,7 +50,6 @@ 'scikit-learn==1.5.1', 'tqdm', 'pandas', - 'qiskit-symb' ], extras_require={'docs': [ 'sphinx-gallery', @@ -65,6 +64,7 @@ 'tests': ['pytest', 'seaborn', 'flake8', 'mne', 'pooch'], # GPU optimization not available on all platform. # See https://github.com/Qiskit/qiskit-aer/issues/929#issuecomment-691716936 - 'optim': ['qiskit-aer-gpu==0.15.0']}, + 'optim': ['qiskit-symb'], + 'optim_linux': ['qiskit-aer-gpu==0.15.0']}, zip_safe=False, ) From 44d875a04e44475058ae7738ac6ae13ffe45faca Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Sun, 29 Sep 2024 17:25:03 +0200 Subject: [PATCH 16/41] fix no bare exception --- pyriemann_qiskit/utils/quantum_provider.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index 70079a05..bc42f450 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -18,7 +18,7 @@ try: from qiskit_symb.quantum_info import Statevector QISKIT_SYMB=True -except: +except ImportError: QISKIT_SYMB=False From ba0877a25177c6efd7608d86c50d7b143ea70cde Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 29 Sep 2024 15:26:22 +0000 Subject: [PATCH 17/41] [pre-commit.ci] auto fixes from pre-commit.com hooks --- README.md | 3 ++- pyriemann_qiskit/classification.py | 2 +- pyriemann_qiskit/utils/quantum_provider.py | 11 ++++++----- requirements.txt | 1 - 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f4e1cbcb..537436a0 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,8 @@ To use symbolic quantum simulation, run: pip install .[optim] ``` -Which will enable [qiskit-symb](https://github.com/SimoneGasperini/qiskit-symb) integration. +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 diff --git a/pyriemann_qiskit/classification.py b/pyriemann_qiskit/classification.py index 3b23d8b6..6d01cd36 100644 --- a/pyriemann_qiskit/classification.py +++ b/pyriemann_qiskit/classification.py @@ -423,7 +423,7 @@ def _init_algo(self, n_features): self.gen_feature_map, self._quantum_instance, self.use_fidelity_state_vector_kernel, - not self.pegasos + not self.pegasos, ) if self.pegasos: self._log("[Warning] `gamma` is not supported by PegasosQSVC") diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index bc42f450..1ef44439 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -15,12 +15,13 @@ FidelityStatevectorKernel, FidelityQuantumKernel, ) + try: from qiskit_symb.quantum_info import Statevector - QISKIT_SYMB=True -except ImportError: - QISKIT_SYMB=False + QISKIT_SYMB = True +except ImportError: + QISKIT_SYMB = False class SymbFidelityStatevectorKernel: @@ -218,14 +219,14 @@ def get_quantum_kernel( gen_feature_map, quantum_instance, use_fidelity_state_vector_kernel, - use_qiskit_symb + use_qiskit_symb, ): """Get a quantum kernel Return an instance of FidelityQuantumKernel or FidelityStatevectorKernel (in the case of a simulation). - For simulation with a small number of qubits (< 9), and `use_qiskit_symb` is True, + For simulation with a small number of qubits (< 9), and `use_qiskit_symb` is True, qiskit-symb is used. Parameters diff --git a/requirements.txt b/requirements.txt index 9f6e94a5..e5486b47 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,4 +14,3 @@ docplex>=2.21.207 firebase_admin==6.5.0 tqdm pandas - From 9a649fdb29154698046d17a7c5645161e0f67378 Mon Sep 17 00:00:00 2001 From: gcattan Date: Sun, 29 Sep 2024 20:01:02 +0200 Subject: [PATCH 18/41] Update deploy_ghpages.yml copy cached feature maps to examples at runtime --- .github/workflows/deploy_ghpages.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/deploy_ghpages.yml b/.github/workflows/deploy_ghpages.yml index b61cf7da..33dc35b4 100644 --- a/.github/workflows/deploy_ghpages.yml +++ b/.github/workflows/deploy_ghpages.yml @@ -34,6 +34,10 @@ jobs: apt-get -y install --fix-missing git-core apt-get -y install build-essential pip install -r doc/requirements.txt + cp -a /symb_statevectors/. /examples/ERP + cp -a /symb_statevectors/. /examples/MI + cp -a /symb_statevectors/. /examples/other_datasets + cp -a /symb_statevectors/. /examples/toys_dataset - name: Upload generated HTML as artifact uses: actions/upload-artifact@v4 with: From 567c6f1c2ce1a83c8015dab4c12b7a2a6664a424 Mon Sep 17 00:00:00 2001 From: gcattan Date: Mon, 30 Sep 2024 11:33:35 +0200 Subject: [PATCH 19/41] Update pyriemann_qiskit/utils/hyper_params_factory.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Quentin Barthélemy --- pyriemann_qiskit/utils/hyper_params_factory.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyriemann_qiskit/utils/hyper_params_factory.py b/pyriemann_qiskit/utils/hyper_params_factory.py index c4ebe21a..08305a2a 100644 --- a/pyriemann_qiskit/utils/hyper_params_factory.py +++ b/pyriemann_qiskit/utils/hyper_params_factory.py @@ -27,6 +27,7 @@ def gen_x_feature_map(reps=2): ------- 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. From 10a385e393637d7750df861fadbcd58869ac0671 Mon Sep 17 00:00:00 2001 From: gcattan Date: Mon, 30 Sep 2024 11:33:41 +0200 Subject: [PATCH 20/41] Update pyriemann_qiskit/utils/hyper_params_factory.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Quentin Barthélemy --- pyriemann_qiskit/utils/hyper_params_factory.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyriemann_qiskit/utils/hyper_params_factory.py b/pyriemann_qiskit/utils/hyper_params_factory.py index 08305a2a..f5858dda 100644 --- a/pyriemann_qiskit/utils/hyper_params_factory.py +++ b/pyriemann_qiskit/utils/hyper_params_factory.py @@ -131,6 +131,7 @@ def gen_zz_feature_map(reps=2, entanglement="linear"): ------- 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. From e3f101bc137addb52a9a53fc333f2c180628f60c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 09:33:47 +0000 Subject: [PATCH 21/41] [pre-commit.ci] auto fixes from pre-commit.com hooks --- pyriemann_qiskit/utils/hyper_params_factory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyriemann_qiskit/utils/hyper_params_factory.py b/pyriemann_qiskit/utils/hyper_params_factory.py index f5858dda..c481da1b 100644 --- a/pyriemann_qiskit/utils/hyper_params_factory.py +++ b/pyriemann_qiskit/utils/hyper_params_factory.py @@ -27,7 +27,7 @@ def gen_x_feature_map(reps=2): ------- 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. From 783d6e2f53aaf3732c6bae29c30d84178498d74c Mon Sep 17 00:00:00 2001 From: gcattan Date: Mon, 30 Sep 2024 11:34:07 +0200 Subject: [PATCH 22/41] Update pyriemann_qiskit/utils/quantum_provider.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Quentin Barthélemy --- pyriemann_qiskit/utils/quantum_provider.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index 1ef44439..1c09bada 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -3,10 +3,10 @@ import joblib import logging -import numpy as np import os import pickle +import numpy as np from qiskit_aer import AerSimulator from qiskit_aer.quantum_info import AerStatevector from qiskit_algorithms.state_fidelities import ComputeUncompute From 25007eedc322ea1b0c3d61c09d73ba6d6c969617 Mon Sep 17 00:00:00 2001 From: gcattan Date: Mon, 30 Sep 2024 11:34:22 +0200 Subject: [PATCH 23/41] Update pyriemann_qiskit/utils/quantum_provider.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Quentin Barthélemy --- pyriemann_qiskit/utils/quantum_provider.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index 1c09bada..f7affd6f 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -80,20 +80,20 @@ def __init__(self, feature_map, gen_feature_map, n_jobs=1): self.function = sv.to_lambda() - """Evaluate the quantum kernel. - - Returns - ------- - kernel : ndarray, shape (len(x_vec), len(y_vec)) - The kernel matrix. + def evaluate(self, x_vec, y_vec=None): + """Evaluate the quantum kernel. - Notes - ----- - .. versionadded:: 0.4.0 - """ + Returns + ------- + kernel : ndarray, shape (len(x_vec), len(y_vec)) + The kernel matrix. - def evaluate(self, x_vec, y_vec=None): + Notes + ----- + .. versionadded:: 0.4.0 + """ if y_vec is None: + y_vec = x_vec x_vec_len = len(x_vec) From c83c93b80cc7e0090585e0a068bc1f1e92006a10 Mon Sep 17 00:00:00 2001 From: gcattan Date: Mon, 30 Sep 2024 11:34:30 +0200 Subject: [PATCH 24/41] Update pyriemann_qiskit/utils/hyper_params_factory.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Quentin Barthélemy --- pyriemann_qiskit/utils/hyper_params_factory.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyriemann_qiskit/utils/hyper_params_factory.py b/pyriemann_qiskit/utils/hyper_params_factory.py index c481da1b..ff27c1d7 100644 --- a/pyriemann_qiskit/utils/hyper_params_factory.py +++ b/pyriemann_qiskit/utils/hyper_params_factory.py @@ -78,6 +78,7 @@ def gen_z_feature_map(reps=2): ------- 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. From 087a490a83624828a0f60c09b550d910d1d515b9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 09:34:32 +0000 Subject: [PATCH 25/41] [pre-commit.ci] auto fixes from pre-commit.com hooks --- pyriemann_qiskit/utils/quantum_provider.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index f7affd6f..fabee4bd 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -93,7 +93,6 @@ def evaluate(self, x_vec, y_vec=None): .. versionadded:: 0.4.0 """ if y_vec is None: - y_vec = x_vec x_vec_len = len(x_vec) From aec2678db7805fa2a58368d4ec11abbb42ad9647 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Mon, 30 Sep 2024 11:33:00 +0200 Subject: [PATCH 26/41] correct workflow file --- .github/workflows/deploy_ghpages.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/deploy_ghpages.yml b/.github/workflows/deploy_ghpages.yml index 33dc35b4..0f054e0f 100644 --- a/.github/workflows/deploy_ghpages.yml +++ b/.github/workflows/deploy_ghpages.yml @@ -34,10 +34,7 @@ jobs: apt-get -y install --fix-missing git-core apt-get -y install build-essential pip install -r doc/requirements.txt - cp -a /symb_statevectors/. /examples/ERP - cp -a /symb_statevectors/. /examples/MI - cp -a /symb_statevectors/. /examples/other_datasets - cp -a /symb_statevectors/. /examples/toys_dataset + cp -a /symb_statevectors/. /doc - name: Upload generated HTML as artifact uses: actions/upload-artifact@v4 with: From 3ec4e1303afddde4afe89e120b9f0a5ae8430612 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Mon, 30 Sep 2024 15:21:25 +0200 Subject: [PATCH 27/41] tentative to fix error in workflow (features map not found) --- .github/workflows/deploy_ghpages.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy_ghpages.yml b/.github/workflows/deploy_ghpages.yml index 0f054e0f..aadd52f8 100644 --- a/.github/workflows/deploy_ghpages.yml +++ b/.github/workflows/deploy_ghpages.yml @@ -22,6 +22,9 @@ jobs: with: path: ~/.cache/pip key: deploy_ghpages.yml + - name: Copy feature maps + run: | + cp -a /symb_statevectors/ /doc - name: Generate HTML docs env: FIREBASE_CERTIFICATE: ${{ secrets.FIREBASE_CERTIFICATE }} @@ -33,8 +36,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 - cp -a /symb_statevectors/. /doc - name: Upload generated HTML as artifact uses: actions/upload-artifact@v4 with: From 9a9103e6e024565f7f91c67b497a6d6c45b375aa Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Mon, 30 Sep 2024 15:29:40 +0200 Subject: [PATCH 28/41] fix workflow: wrong directory --- .github/workflows/deploy_ghpages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy_ghpages.yml b/.github/workflows/deploy_ghpages.yml index aadd52f8..38191e70 100644 --- a/.github/workflows/deploy_ghpages.yml +++ b/.github/workflows/deploy_ghpages.yml @@ -24,7 +24,7 @@ jobs: key: deploy_ghpages.yml - name: Copy feature maps run: | - cp -a /symb_statevectors/ /doc + cp -a ./symb_statevectors/ ./doc - name: Generate HTML docs env: FIREBASE_CERTIFICATE: ${{ secrets.FIREBASE_CERTIFICATE }} From 04755254fdc1e91d330462b51a860510f7e36533 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Mon, 30 Sep 2024 15:51:28 +0200 Subject: [PATCH 29/41] simplify workflow file --- .github/workflows/deploy_ghpages.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/deploy_ghpages.yml b/.github/workflows/deploy_ghpages.yml index 38191e70..86c83492 100644 --- a/.github/workflows/deploy_ghpages.yml +++ b/.github/workflows/deploy_ghpages.yml @@ -22,9 +22,6 @@ jobs: with: path: ~/.cache/pip key: deploy_ghpages.yml - - name: Copy feature maps - run: | - cp -a ./symb_statevectors/ ./doc - name: Generate HTML docs env: FIREBASE_CERTIFICATE: ${{ secrets.FIREBASE_CERTIFICATE }} @@ -36,6 +33,7 @@ jobs: python -m pip install --upgrade pip apt-get -y install --fix-missing git-core apt-get -y install build-essential + cp -a ./symb_statevectors/. ./doc - name: Upload generated HTML as artifact uses: actions/upload-artifact@v4 with: From 37c876ca0fb709f1e659697ff251f27c093b36e4 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Mon, 30 Sep 2024 22:35:09 +0200 Subject: [PATCH 30/41] revert changes to workflow back. Correct syntax of cp command --- .github/workflows/deploy_ghpages.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy_ghpages.yml b/.github/workflows/deploy_ghpages.yml index 86c83492..66b296f5 100644 --- a/.github/workflows/deploy_ghpages.yml +++ b/.github/workflows/deploy_ghpages.yml @@ -22,6 +22,9 @@ jobs: with: path: ~/.cache/pip key: deploy_ghpages.yml + - name: Copy feature maps + run: | + cp -a ./symb_statevectors/. ./doc - name: Generate HTML docs env: FIREBASE_CERTIFICATE: ${{ secrets.FIREBASE_CERTIFICATE }} @@ -33,7 +36,6 @@ jobs: python -m pip install --upgrade pip apt-get -y install --fix-missing git-core apt-get -y install build-essential - cp -a ./symb_statevectors/. ./doc - name: Upload generated HTML as artifact uses: actions/upload-artifact@v4 with: From ec94c95955e059b25f815f11db42546c7a3f3bca Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Mon, 30 Sep 2024 22:52:07 +0200 Subject: [PATCH 31/41] create missing cache `symb_statevectors` inside doc --- .github/workflows/deploy_ghpages.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/deploy_ghpages.yml b/.github/workflows/deploy_ghpages.yml index 66b296f5..3191d4ad 100644 --- a/.github/workflows/deploy_ghpages.yml +++ b/.github/workflows/deploy_ghpages.yml @@ -22,9 +22,6 @@ jobs: with: path: ~/.cache/pip key: deploy_ghpages.yml - - name: Copy feature maps - run: | - cp -a ./symb_statevectors/. ./doc - name: Generate HTML docs env: FIREBASE_CERTIFICATE: ${{ secrets.FIREBASE_CERTIFICATE }} @@ -36,6 +33,7 @@ jobs: python -m pip install --upgrade pip apt-get -y install --fix-missing git-core apt-get -y install build-essential + cp -a ./symb_statevectors/. ./doc/symb_statevectors - name: Upload generated HTML as artifact uses: actions/upload-artifact@v4 with: From f08a599badb5965c252285d720828473e4221bfa Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Mon, 30 Sep 2024 23:09:49 +0200 Subject: [PATCH 32/41] second version (not passed as a prebuilt command) --- .github/workflows/deploy_ghpages.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy_ghpages.yml b/.github/workflows/deploy_ghpages.yml index 3191d4ad..cc8b74ed 100644 --- a/.github/workflows/deploy_ghpages.yml +++ b/.github/workflows/deploy_ghpages.yml @@ -22,6 +22,9 @@ jobs: with: path: ~/.cache/pip key: deploy_ghpages.yml + - name: Copy feature maps + run: | + cp -a ./symb_statevectors/. ./doc/symb_statevectors - name: Generate HTML docs env: FIREBASE_CERTIFICATE: ${{ secrets.FIREBASE_CERTIFICATE }} @@ -33,7 +36,6 @@ jobs: python -m pip install --upgrade pip apt-get -y install --fix-missing git-core apt-get -y install build-essential - cp -a ./symb_statevectors/. ./doc/symb_statevectors - name: Upload generated HTML as artifact uses: actions/upload-artifact@v4 with: From 124419588bbe79c2995cf3e17462b4dc3719eb48 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Mon, 30 Sep 2024 23:18:57 +0200 Subject: [PATCH 33/41] add debug trace --- .github/workflows/deploy_ghpages.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/deploy_ghpages.yml b/.github/workflows/deploy_ghpages.yml index cc8b74ed..84d4245a 100644 --- a/.github/workflows/deploy_ghpages.yml +++ b/.github/workflows/deploy_ghpages.yml @@ -25,6 +25,11 @@ jobs: - name: Copy feature maps run: | cp -a ./symb_statevectors/. ./doc/symb_statevectors + 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 + ls doc - name: Generate HTML docs env: FIREBASE_CERTIFICATE: ${{ secrets.FIREBASE_CERTIFICATE }} From de4bd0fc2894816ce982e9fd91b99946759221d2 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Tue, 1 Oct 2024 09:16:58 +0200 Subject: [PATCH 34/41] joblib result assignation read-only when started from within another job. Disabling multhithreading for one of the moabb example --- examples/ERP/plot_classify_P300_bi.py | 5 ++++- pyriemann_qiskit/classification.py | 9 +++++++++ pyriemann_qiskit/utils/quantum_provider.py | 10 +++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/examples/ERP/plot_classify_P300_bi.py b/examples/ERP/plot_classify_P300_bi.py index a8c70930..08cc7d28 100644 --- a/examples/ERP/plot_classify_P300_bi.py +++ b/examples/ERP/plot_classify_P300_bi.py @@ -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': ''} + params={ + 'n_jobs': 1, # Number of jobs for the simulator + # 'q_account_token': '' + } ) # Here we provide a pipeline for comparison: diff --git a/pyriemann_qiskit/classification.py b/pyriemann_qiskit/classification.py index 6d01cd36..9ce3efe3 100644 --- a/pyriemann_qiskit/classification.py +++ b/pyriemann_qiskit/classification.py @@ -326,6 +326,8 @@ 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 parameter for the SymbFidelityStatevectorKernel Parameters ---------- @@ -364,10 +366,14 @@ class QuanticSVM(QuanticClassifierBase): Random seed for the simulation use_fidelity_state_vector_kernel: boolean (default=True) if True, use a FidelitystatevectorKernel for simulation. + n_jobs: boolean + The number of jobs for the qiskit-symb fidelity state vector + (if applicable) See Also -------- QuanticClassifierBase + SymbFidelityStatevectorKernel References ---------- @@ -405,6 +411,7 @@ def __init__( gen_feature_map=gen_zz_feature_map(), seed=None, use_fidelity_state_vector_kernel=True, + n_jobs=4 ): QuanticClassifierBase.__init__( self, quantum, q_account_token, verbose, shots, gen_feature_map, seed @@ -414,6 +421,7 @@ 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 def _init_algo(self, n_features): self._log("SVM initiating algorithm") @@ -424,6 +432,7 @@ def _init_algo(self, n_features): self._quantum_instance, self.use_fidelity_state_vector_kernel, not self.pegasos, + self.n_jobs ) if self.pegasos: self._log("[Warning] `gamma` is not supported by PegasosQSVC") diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index fabee4bd..d8e98e99 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -219,6 +219,7 @@ def get_quantum_kernel( quantum_instance, use_fidelity_state_vector_kernel, use_qiskit_symb, + n_jobs=4 ): """Get a quantum kernel @@ -239,12 +240,19 @@ def get_quantum_kernel( use_qiskit_symb: boolean This flag is used only if qiskit-symb is installed. 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) Returns ------- kernel: QuantumKernel The quantum kernel. + See also + -------- + SymbFidelityStatevectorKernel + Notes ----- .. versionadded:: 0.3.0 @@ -260,7 +268,7 @@ def get_quantum_kernel( # See: # https://medium.com/qiskit/qiskit-symb-a-qiskit-ecosystem-package-for-symbolic-quantum-computation-b6b4407fa705 kernel = SymbFidelityStatevectorKernel( - feature_map, gen_feature_map, n_jobs=4 + feature_map, gen_feature_map, n_jobs=n_jobs ) logging.log( logging.WARN, From 29a90b90b2c9cc6450e88ffb5b79c91714de9615 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Tue, 1 Oct 2024 09:17:24 +0200 Subject: [PATCH 35/41] simplify workflow --- .github/workflows/deploy_ghpages.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/deploy_ghpages.yml b/.github/workflows/deploy_ghpages.yml index 84d4245a..70bce3b0 100644 --- a/.github/workflows/deploy_ghpages.yml +++ b/.github/workflows/deploy_ghpages.yml @@ -24,12 +24,10 @@ jobs: key: deploy_ghpages.yml - name: Copy feature maps run: | - cp -a ./symb_statevectors/. ./doc/symb_statevectors 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 - ls doc - name: Generate HTML docs env: FIREBASE_CERTIFICATE: ${{ secrets.FIREBASE_CERTIFICATE }} From 7b2663a2079a21d8057835ce89aa0ac6036d149d Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Tue, 1 Oct 2024 09:20:15 +0200 Subject: [PATCH 36/41] disable multithreading for financial data too --- examples/other_datasets/plot_financial_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/other_datasets/plot_financial_data.py b/examples/other_datasets/plot_financial_data.py index 9c75f36c..88060c9a 100644 --- a/examples/other_datasets/plot_financial_data.py +++ b/examples/other_datasets/plot_financial_data.py @@ -370,7 +370,7 @@ 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, seed=42, n_jobs=1), ) 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) From d20b3fbb37e2ec2b0acd83792e41adb1fd2d7215 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 07:21:13 +0000 Subject: [PATCH 37/41] [pre-commit.ci] auto fixes from pre-commit.com hooks --- examples/ERP/plot_classify_P300_bi.py | 4 ++-- pyriemann_qiskit/classification.py | 4 ++-- pyriemann_qiskit/utils/quantum_provider.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/ERP/plot_classify_P300_bi.py b/examples/ERP/plot_classify_P300_bi.py index 08cc7d28..78616e49 100644 --- a/examples/ERP/plot_classify_P300_bi.py +++ b/examples/ERP/plot_classify_P300_bi.py @@ -87,9 +87,9 @@ # On a real Quantum computer (n_components = qubits) dim_red=PCA(n_components=5), params={ - 'n_jobs': 1, # Number of jobs for the simulator + "n_jobs": 1, # Number of jobs for the simulator # 'q_account_token': '' - } + }, ) # Here we provide a pipeline for comparison: diff --git a/pyriemann_qiskit/classification.py b/pyriemann_qiskit/classification.py index 9ce3efe3..92a4dfb8 100644 --- a/pyriemann_qiskit/classification.py +++ b/pyriemann_qiskit/classification.py @@ -411,7 +411,7 @@ def __init__( gen_feature_map=gen_zz_feature_map(), seed=None, use_fidelity_state_vector_kernel=True, - n_jobs=4 + n_jobs=4, ): QuanticClassifierBase.__init__( self, quantum, q_account_token, verbose, shots, gen_feature_map, seed @@ -432,7 +432,7 @@ def _init_algo(self, n_features): self._quantum_instance, self.use_fidelity_state_vector_kernel, not self.pegasos, - self.n_jobs + self.n_jobs, ) if self.pegasos: self._log("[Warning] `gamma` is not supported by PegasosQSVC") diff --git a/pyriemann_qiskit/utils/quantum_provider.py b/pyriemann_qiskit/utils/quantum_provider.py index d8e98e99..de7f787a 100644 --- a/pyriemann_qiskit/utils/quantum_provider.py +++ b/pyriemann_qiskit/utils/quantum_provider.py @@ -219,7 +219,7 @@ def get_quantum_kernel( quantum_instance, use_fidelity_state_vector_kernel, use_qiskit_symb, - n_jobs=4 + n_jobs=4, ): """Get a quantum kernel From 47f1054000ffc5f44cd2f318640bcd86a4f63811 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Tue, 1 Oct 2024 11:11:17 +0200 Subject: [PATCH 38/41] fix version of symengine for serialization --- doc/requirements.txt | 1 + setup.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/requirements.txt b/doc/requirements.txt index bb52688e..cea7bf98 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -24,3 +24,4 @@ pyriemann==0.6 docplex>=2.21.207 firebase_admin==6.5.0 qiskit-symb +symengine==0.11.0 diff --git a/setup.py b/setup.py index b52edd1a..243bce8c 100644 --- a/setup.py +++ b/setup.py @@ -64,7 +64,7 @@ 'tests': ['pytest', 'seaborn', 'flake8', 'mne', 'pooch'], # GPU optimization not available on all platform. # See https://github.com/Qiskit/qiskit-aer/issues/929#issuecomment-691716936 - 'optim': ['qiskit-symb'], + 'optim': ['qiskit-symb', 'symengine==0.11.0'], 'optim_linux': ['qiskit-aer-gpu==0.15.0']}, zip_safe=False, ) From 661a72803548a48b2a2c705765da6db6f3281081 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Tue, 1 Oct 2024 11:52:21 +0200 Subject: [PATCH 39/41] improve simulation time for plot_financial_data --- examples/other_datasets/plot_financial_data.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/other_datasets/plot_financial_data.py b/examples/other_datasets/plot_financial_data.py index 88060c9a..ed2b8203 100644 --- a/examples/other_datasets/plot_financial_data.py +++ b/examples/other_datasets/plot_financial_data.py @@ -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_x_feature_map from pyriemann_qiskit.utils.preprocessing import NdRobustScaler print(__doc__) @@ -370,7 +371,13 @@ 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, n_jobs=1), + QuanticSVM( + quantum=True, + C=best_C, + gamma=best_gamma, + gen_feature_map=gen_x_feature_map(), + seed=42, + n_jobs=1), ) 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) From bf43d2e4c8daabafa185b9ca59dd23bd5e122e69 Mon Sep 17 00:00:00 2001 From: Gregoire Cattan Date: Tue, 1 Oct 2024 14:10:36 +0200 Subject: [PATCH 40/41] Missing flag to deactivate qiskit_symb --- examples/other_datasets/plot_financial_data.py | 8 +++++--- pyriemann_qiskit/classification.py | 12 +++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/examples/other_datasets/plot_financial_data.py b/examples/other_datasets/plot_financial_data.py index ed2b8203..8fc4e113 100644 --- a/examples/other_datasets/plot_financial_data.py +++ b/examples/other_datasets/plot_financial_data.py @@ -50,7 +50,7 @@ from sklearn.metrics import balanced_accuracy_score from pyriemann_qiskit.classification import QuanticSVM -from pyriemann_qiskit.utils.hyper_params_factory import gen_x_feature_map +from pyriemann_qiskit.utils.hyper_params_factory import gen_zz_feature_map from pyriemann_qiskit.utils.preprocessing import NdRobustScaler print(__doc__) @@ -375,9 +375,11 @@ def transform(self, X): quantum=True, C=best_C, gamma=best_gamma, - gen_feature_map=gen_x_feature_map(), + gen_feature_map=gen_zz_feature_map(), seed=42, - n_jobs=1), + 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) diff --git a/pyriemann_qiskit/classification.py b/pyriemann_qiskit/classification.py index 92a4dfb8..3b6c2a86 100644 --- a/pyriemann_qiskit/classification.py +++ b/pyriemann_qiskit/classification.py @@ -327,7 +327,8 @@ class QuanticSVM(QuanticClassifierBase): .. versionchanged:: 0.3.0 Add use_fidelity_state_vector_kernel parameter .. versionchanged:: 0.4.0 - Add n_jobs parameter for the SymbFidelityStatevectorKernel + Add n_jobs and use_qiskit_symb parameter + for SymbFidelityStatevectorKernel Parameters ---------- @@ -364,8 +365,11 @@ class QuanticSVM(QuanticClassifierBase): 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) @@ -411,6 +415,7 @@ 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__( @@ -422,6 +427,7 @@ def __init__( 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") @@ -431,7 +437,7 @@ def _init_algo(self, n_features): self.gen_feature_map, self._quantum_instance, self.use_fidelity_state_vector_kernel, - not self.pegasos, + self.use_qiskit_symb and not self.pegasos, self.n_jobs, ) if self.pegasos: From 56227cb741928f72cf38e7bccb84d245cdc69602 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 12:10:52 +0000 Subject: [PATCH 41/41] [pre-commit.ci] auto fixes from pre-commit.com hooks --- examples/other_datasets/plot_financial_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/other_datasets/plot_financial_data.py b/examples/other_datasets/plot_financial_data.py index 8fc4e113..54a01a04 100644 --- a/examples/other_datasets/plot_financial_data.py +++ b/examples/other_datasets/plot_financial_data.py @@ -378,7 +378,7 @@ def transform(self, X): gen_feature_map=gen_zz_feature_map(), seed=42, n_jobs=1, - use_qiskit_symb=False + use_qiskit_symb=False, ), ) train_pred_qsvm = gs.best_estimator_.fit(X_train, y_train).predict(X_train)