CERN-IT-INNOVATION / QuASK

Quantum Advantage Seeker with kernel
Apache License 2.0
32 stars 10 forks source link

Equation of Geometric Difference #6

Open Squigspear opened 1 year ago

Squigspear commented 1 year ago

Hi,

I would like to clarify the following code that was used to implement geometric difference from the paper: "The power of data in quantum machine learning".

def calculate_geometric_difference(k_1, k_2, normalization_lambda=0.001): """ Calculate the geometric difference g(K_1 || K_2), which is equation F9 in "The power of data in quantum machine learning" (https://arxiv.org/abs/2011.01938) and characterize the separation between classical and quantum kernels. Args: k_1: Quantum kernel Gram matrix k_2: Classical kernel Gram matrix normalization_lambda: normalization factor, must be close to zero Returns: geometric difference between the two kernel functions (float). """

In the paper, geometric difference between classical and quantum (gcq ) is defined with k1 = classical kernel and k2 = quantum kernel. However, in your code implementation, k1 is quantum and k2 is classical. As the equation is asymmetric to the order of the matrices k1 and k2, could there be an error in the code implementation?

Thanks for taking the time to read this!

Fradm98 commented 1 year ago

Hi @Squigspear, thanks for your insight, we fixed this issue in the branch package, we are going soon to merge it to the main one.

qifengpan commented 1 month ago

Hi,

I would like ask a follow up question for the function calculate_geometric_difference In your implementation, you calculate the root of matrix in following form:

        # √K1
        k_1_sqrt = np.real(sqrtm(k_1))
        # √K2
        k_2_sqrt = np.real(sqrtm(k_2))

Since the result of sqrtm(k_1) can be a matrix containing complex number, direct cast it to a real number matrix would lose the imformation of imagenary part, and lead a wrong result. For e.g:

import tensorflow as tf
import numpy as np
from scipy.linalg import sqrtm
x = tf.convert_to_tensor([[1,2],[3,3]])
x_sqrt_scipy = np.real(sqrtm(x))
print(x_sqrt_scipy @ x_sqrt_scipy )

According to the definition, the result of x_sqrt_scipy @ x_sqrt_scipy should be x itself, but the output of this block is not identical to x. The reason behind is that matrix [1,2;3,3] is not semi-definite matrix. Therefore, the result of sqrtm contains complex number. I'm not sure if I made some mistake for this, or misunderstanding for geometric difference. Or maybe you have other intention/implementation for that. Purely from math perspective, I would code this block as

        # √K1
        k_1_sqrt = sqrtm(k_1)
        # √K2
        k_2_sqrt = sqrtm(k_2)

Thanks for your time of reading/proofing, I'm happy to have further discussion for this.