FidelityStatevectorKernel
gcattan opened this issue · 9 comments
Hello,
I am testing qiskit-symb
with FidelityStatevectorKernel
, but encounter the following error: 'Statevector' object has no attribute 'data'
from qiskit_symb.quantum_info import Statevector
quantum_kernel = FidelityStatevectorKernel(feature_map=..., statevector_type=Statevector)
Hi @gcattan and thank you for posting this!
I'm sorry but I'm not even sure how to reproduce this issue. I tried to run the following code and it works for me.
from qiskit.circuit.library import ZZFeatureMap
from qiskit_machine_learning.kernels import FidelityStatevectorKernel
from qiskit_symb.quantum_info import Statevector
qc = ZZFeatureMap(feature_dimension=3).decompose()
quantum_kernel = FidelityStatevectorKernel(feature_map=qc, statevector_type=Statevector)
Maybe your error is raised when you call the FidelityStatevectorKernel.evaluate
method?
Hi, sorry, I just put here half of the example.
Let me know if you can access this link: https://colab.research.google.com/drive/1gB5FY4NfWBIOhGbgWkeUk43nCsOcRivg?usp=sharing
Hello again! Yes, I can access the notebook and I see your issue now.
The short answer would be that you can't plug in the symbolic Statevector
type in the construction of your FidelityStatevectorKernel
like you're trying to do in your code. This is because the qiskit_symb.quantum_info.Statevector
is internally different compared to the standard qiskit.quantum_info.Statevector
. For instance, the latter has an attribute called 'data' (that your QSVC
model is trying to access) but the former does NOT provide the corresponding member with the same name.
Even if this feature is not directly provided in qiskit_symb
, I post here a simple snippet of code (far from being optimal in terms of performance) to workaround this problem and achieve exactly what you want to do:
import numpy as np
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
Once you have defined this new SymbFidelityStatevectorKernel
object, you can use it to build your QSVC
model:
from qiskit.circuit.library import ZZFeatureMap
from qiskit_machine_learning.algorithms import QSVC
fm1 = ZZFeatureMap(feature_dimension=3, parameter_prefix="a")
fm2 = ZZFeatureMap(feature_dimension=3, parameter_prefix="b")
circuit = fm1.compose(fm2.inverse()).decompose()
quantum_kernel = SymbFidelityStatevectorKernel(circuit=circuit)
qsvc = QSVC(quantum_kernel=quantum_kernel)
# Get your data and fit the model
# ...
Looks really nice! Thank you for the help.
I am not sure. But do you think we could provide a property "data" like this to the Statevector inside this library:
@property
def data(self):
return self._data
Yes, making the 'data' attribute accessible as a property looks reasonable (I was actually trying to do something similar). However, this would not be enough to solve your issue with the QSVC
model here.
To make qiskit-symb
features fully compatible with the QSVC
and possibly more qiskit_machine_learning
models, a little bit more work is required. If you have any idea and want to give it a try, feel free to start working on it and open a PR as soon as you have something working so we can further discuss ;)