Skip to content

Conversation

@andynader
Copy link

Title:
Before You Train: Pre-screening Quantum Kernels with Geometric Difference

Summary:
This demo implements the geometric difference metric (g) from Huang et al. (2021) for pre-screening quantum kernels before training. The metric quantifies how differently a quantum kernel's geometry represents data compared to a classical kernel, allowing practitioners to identify promising quantum approaches early and avoid wasting time on kernels with no potential advantage. Using synthetic two-moons data, we demonstrate how to calculate g for multiple quantum kernel variants (fidelity-based and projected) and interpret the results to guide kernel selection.

Relevant references:

Possible Drawbacks:
None

Related GitHub Issues:
None


GOALS — Why are we working on this now?
Provide practitioners with a practical tool for quantum kernel evaluation. Address a common pain point where researchers spend significant time tuning quantum kernels that fundamentally cannot outperform classical ones.

AUDIENCE — Who is this for?
QML researchers and practitioners working with quantum kernels, ML engineers exploring quantum advantages, and anyone interested in practical quantum machine learning workflows.

KEYWORDS:
quantum kernels, geometric difference, pre-screening, kernel methods, SVM, quantum machine learning, quantum advantage

Which type of documentation?

  • Tutorial
  • Demo
  • How-to

@github-actions
Copy link

github-actions bot commented Oct 6, 2025

Your preview is ready 🎉!

You can view your changes here

Deployed at: 2025-12-01 22:10:53 UTC

@andynader
Copy link
Author

Hi @daniela-angulo , I checked the preview and some things did not render properly, do I need to do anything?

@daniela-angulo
Copy link
Contributor

Hi @andynader, yeah, I saw that.
Not for now, let me try to fix a few things and I'll loop you in when I have finished the demo so you can address all the suggestions and/or changes at once.
Thanks.

@daniela-angulo
Copy link
Contributor

Hi @andynader, I think I addressed all the formatting issues. Could you verify that for me? Is the demo looking the way it is intended to?
I have not yet reviewed it, but I will this week. However, I noted a few things in the PR as comments regarding two figures. We can start with these two things and then move forward to the review when I get to it.
Thank you!

@andynader
Copy link
Author

Hi Daniela, thank you for your hard work. I changed the code as you recommended; should we also make some figures such as the scatter plot and embedding circuit plots smaller or do you think they're good?

@daniela-angulo
Copy link
Contributor

Yes, I think we could probably do that.
Have you started discussing the graphics with Ben?
Thanks @andynader !

@andynader
Copy link
Author

Yes, I think we could probably do that. Have you started discussing the graphics with Ben? Thanks @andynader !

Hi Daniela, yes he told me you have an in house graphic designer who can make them, how should I move forward? Should I contact Ben?

@andynader
Copy link
Author

I will also work on making the figures smaller this weekend and push the changes

@daniela-angulo
Copy link
Contributor

Hi!
yes, please. You can contact Ben over email and he'll help us with that.
Thank you.
I will review the demo from a more content/science perspective next week.

Copy link
Contributor

@daniela-angulo daniela-angulo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Such a cool demo, the main idea is clearly well presented.
I only added a few comments. Thanks!

From a practitioner’s perspective, such a **pre-screening test** is invaluable: it lets us rule out
quantum kernels that don’t offer any potential quantum advantage right from the start.

Huang *et al.* (https://arxiv.org/abs/2011.01938) introduced exactly this test. Their proposed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should have a reference section at the end, before the appendix. It doesn't matter if all we cite is the same article several times.
You can take a look at other demos in the open PRs in the repo #1577

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the best way to incorporate this directly into the demo file, put the reference here, or in the notebook and then convert again?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

best to do it in the demo file directly. If you run into difficulties, let me know, and I'll help.

Comment on lines 237 to 255
# :math:`K_{\text{RBF}}` obtained from:
#
# .. math:: k_{\text{RBF}}(x, x') = \exp(-\gamma \|x - x'\|^2)
#
# :math:`K_{\text{QK-E1}}` obtained from:
#
# .. math:: k_{\text{QK-E1}}(x, x') = |\langle \psi_{\text{E1}}(x) \mid \psi_{\text{E1}}(x') \rangle|^2
#
# :math:`K_{\text{QK-E2}}` obtained from:
#
# .. math:: k_{\text{QK-E2}}(x, x') = |\langle \psi_{\text{E2}}(x) \mid \psi_{\text{E2}}(x') \rangle|^2
#
# :math:`K_{\text{PQK-E1}}` obtained from:
#
# .. math:: k_{\text{PQK-E1}}(x, x') = \exp\left( -\gamma \|v_{\text{E1}}(x) - v_{\text{E1}}(x')\|^2 \right)
#
# :math:`K_{\text{PQK-E2}}` obtained from:
#
# .. math:: k_{\text{PQK-E2}}(x, x') = \exp\left( -\gamma \|v_{\text{E2}}(x) - v_{\text{E2}}(x')\|^2 \right)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we might leave this out since it is repeated from the above equations. Just to shorten up the demo a bit.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem. Should I update myself?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes! go for it

andynader and others added 5 commits October 29, 2025 15:06
Co-authored-by: Daniela Angulo <42325731+daniela-angulo@users.noreply.github.com>
Co-authored-by: Daniela Angulo <42325731+daniela-angulo@users.noreply.github.com>
Co-authored-by: Daniela Angulo <42325731+daniela-angulo@users.noreply.github.com>
Co-authored-by: Daniela Angulo <42325731+daniela-angulo@users.noreply.github.com>
Co-authored-by: Daniela Angulo <42325731+daniela-angulo@users.noreply.github.com>
Co-authored-by: Daniela Angulo <42325731+daniela-angulo@users.noreply.github.com>
@andynader
Copy link
Author

Thanks for your hard work @daniela-angulo, I committed the suggestions, hope this didn't break anything. What's left is to make the figures smaller, and include the changes in my replies to your comments. Can I pull the latest changes and update myself?

@daniela-angulo
Copy link
Contributor

Thanks for reviewing this, @andynader . Yes, you can update the changes yourself and commit them to the repo.

@daniela-angulo
Copy link
Contributor

Hi, I wanted to let you know I will be away for the next three weeks. I will continue working on the demo once I am back. Thank you!

@andynader
Copy link
Author

Absolutely, thank you for your hard work Daniela!

Comment on lines +230 to +313
from sklearn.metrics.pairwise import rbf_kernel

# ---------------------------------------------------------------------------#
# Classical RBF Gram matrix #
# ---------------------------------------------------------------------------#
def classical_rbf_kernel(X, gamma=1.0):
return rbf_kernel(X, gamma=gamma)


K_classical = classical_rbf_kernel(X_train)
print(f"K_RBF shape: {K_classical.shape}")

# ---------------------------------------------------------------------------#
# Quantum fidelity-based Gram matrices #
# ---------------------------------------------------------------------------#
dev = qml.device("default.qubit", wires=n_qubits, shots=None)


def overlap_prob(x, y, embed):
"""Probability of measuring |0…0⟩ after U(x) U†(y)."""

@qml.qnode(dev)
def circuit():
embed(x)
qml.adjoint(embed)(y)
return qml.probs(wires=range(n_qubits))

return circuit()[0]


def quantum_kernel_matrix(X, embed):
return qml.kernels.kernel_matrix(X, X, lambda v1, v2: overlap_prob(v1, v2, embed))


print("Computing QK-E1 (fidelity)...")
K_quantum_E1 = quantum_kernel_matrix(X_train, embed=embedding_E1)

print("Computing QK-E2 (fidelity)...")
K_quantum_E2 = quantum_kernel_matrix(X_train, embed=embedding_E2)

print(f"K_QK_E1 shape: {K_quantum_E1.shape}")
print(f"K_QK_E2 shape: {K_quantum_E2.shape}")


# ---------------------------------------------------------------------------#
# Projected quantum kernels (Pauli vectors + classical RBF) #
# ---------------------------------------------------------------------------#
def get_pauli_vectors(embedding_func, X):
"""Returns Pauli expectation vectors for each input using the given embedding."""
observables = []
for i in range(n_qubits):
observables.extend([qml.PauliX(i), qml.PauliY(i), qml.PauliZ(i)])

@qml.qnode(dev)
def pauli_qnode(x):
embedding_func(x)
return [qml.expval(obs) for obs in observables]

vectors = [pauli_qnode(x) for x in X]
return np.array(vectors)


def calculate_gamma(vectors):
"""Use heuristic gamma = 1 / (d * var) for RBF kernel on Pauli space."""
d = vectors.shape[1]
var = np.var(vectors)
return 1.0 / (d * var) if var > 1e-8 else 1.0


def pqk_kernel_matrix(X, embedding_func):
"""Computes PQK kernel matrix from Pauli vectors + RBF kernel."""
pauli_vecs = get_pauli_vectors(embedding_func, X)
gamma = calculate_gamma(pauli_vecs)
return rbf_kernel(pauli_vecs, gamma=gamma)


print("Computing PQK-E1 (Pauli + RBF)...")
K_pqk_E1 = pqk_kernel_matrix(X_train, embedding_E1)

print("Computing PQK-E2 (Pauli + RBF)...")
K_pqk_E2 = pqk_kernel_matrix(X_train, embedding_E2)

print(f"K_PQK_E1 shape: {K_pqk_E1.shape}")
print(f"K_PQK_E2 shape: {K_pqk_E2.shape}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this block of code is quite long, is there a possibility to break it into two?

@daniela-angulo
Copy link
Contributor

Hi @andynader ! As you can probably tell, I am back :D
I left one more comment in the code. But I also wanted to mention that we were considering the possibility of leaving the Appendix out because it is of considerable length and complexity, almost looks like another demo. Let me know if you feel strongly about this change. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants