code: def partial_kernel_mmd_qp(
      x, y, n_perm=None, kernel=GaussianKernel(), fraction_to_match=1.0
  ):
      """Partial Kernel MMD using quadratic programming.
  
      This is very slow and mainly intended for reference purposes.
      You need to install qpsolvers to use this function."""
  
      torchdrift.utils.check(
          n_perm is None,
          "Bootstrapping within partial MMD is not implemented, use bootstrap during fit",
          error_class=NotImplementedError,
      )
      import qpsolvers
  
      n, d = x.shape
      m, d2 = y.shape
      torchdrift.utils.check(d == d2, "feature dimension mismatch")
      xy = torch.cat([x.detach(), y.detach()], dim=0)
      dists = torch.cdist(xy, xy, p=2.0)
      # we are a bit sloppy here as we just keep the diagonal and everything twice
      k = kernel(dists.double())
      k_x = k[:n, :n]
      k_y = k[n:, n:]
      k_xy = k[:n, n:]
  
      v = torch.full((m,), 1 / m, dtype=k_y.dtype, device=k_y.device)
      R = torch.cholesky(k_x, upper=True)
      d = torch.inverse(R.t()) @ (k_xy.sum(1) / m)
      lb = torch.zeros((n,), dtype=k_x.dtype, device=k_x.device)
      ub = torch.full(
          (n,),
          1.0 / (n * fraction_to_match),
          dtype=k_x.dtype,
          device=k_x.device,
      )
      w = qpsolvers.solve_ls(
          R.cpu().numpy(),
          d.cpu().numpy(),
          lb=lb.cpu().numpy(),
          ub=ub.cpu().numpy(),
          A=torch.ones(
              (
                  1,
                  n,
              ),
              dtype=R.dtype,
          ).numpy(),
          b=torch.ones((1,), dtype=R.dtype).numpy(),
      )
      torchdrift.utils.check(
          w is not None,
          "QP failed to find a solution (numerical accuracy with the bounds?)",
      )
      w = torch.as_tensor(w, device=k_x.device, dtype=k_x.dtype)
      mmd = (
          (w @ k_x) @ w + k_y.sum() / (m * m) - 2 * (w @ k_xy).sum() / m
      )
      return mmd
  
file_path: TorchDrift/torchdrift/detectors/partial_mmd.py
imports: from typing import Optional
  import torch
  from .mmd import GaussianKernel
  from .detector import Detector
  import torchdrift
  import warnings
label_desc: Use image node_id 2 for calling a global function with example usage: partial_kernel_mmd_qp(x, y, n_perm, kernel, fraction_to_match) and returns: mmd