docstr: Compute the p-value resulting from a permutation test using the maximum mean discrepancy
  as a distance measure between the reference data and the data to be tested. The kernel
  used within the MMD is first trained to maximise an estimate of the resulting test power.
  
  Parameters
  ----------
  x
      Batch of instances.
  
  Returns
  -------
  p-value obtained from the permutation test, the MMD^2 between the reference and test set,         and the MMD^2 threshold above which drift is flagged.
docstr_tok: ["Compute","the","p-value","resulting","from","a","permutation","test","using","the","maximum","mean","discrepancy","as","a","distance","measure","between","the","reference","data","and","the","data","to","be","tested",".","The","kernel","used","within","the","MMD","is","first","trained","to","maximise","an","estimate","of","the","resulting","test","power",".","Parameters","--","--","--","--","--","x","Batch","of","instances",".","Returns","--","--","--","-","p-value","obtained","from","the","permutation","test",",","the","MMD^2","between","the","reference","and","test","set",",","and","the","MMD^2","threshold","above","which","drift","is","flagged","."]
code: def score(
      self, x: Union[np.ndarray, list]
  ) -> Tuple[float, float, float]:
      """
          Compute the p-value resulting from a permutation test using the maximum mean discrepancy
          as a distance measure between the reference data and the data to be tested. The kernel
          used within the MMD is first trained to maximise an estimate of the resulting test power.
  
          Parameters
          ----------
          x
              Batch of instances.
  
          Returns
          -------
          p-value obtained from the permutation test, the MMD^2 between the reference and test set, \
          and the MMD^2 threshold above which drift is flagged.
          """
      x_ref, x_cur = self.preprocess(x)
      (x_ref_tr, x_cur_tr), (x_ref_te, x_cur_te) = self.get_splits(
          x_ref, x_cur
      )
      dl_ref_tr, dl_cur_tr = self.dataloader(
          self.dataset(x_ref_tr)
      ), self.dataloader(self.dataset(x_cur_tr))
  
      self.kernel = (
          deepcopy(self.original_kernel)
          if self.retrain_from_scratch
          else self.kernel
      )
      self.kernel = self.kernel.to(self.device)
      train_args = [self.j_hat, (dl_ref_tr, dl_cur_tr), self.device]
      LearnedKernelDriftKeops.trainer(*train_args, **self.train_kwargs)  # type: ignore
  
      m, n = len(x_ref_te), len(x_cur_te)
      if isinstance(x_ref_te, np.ndarray) and isinstance(
          x_cur_te, np.ndarray
      ):
          x_all = torch.from_numpy(
              np.concatenate([x_ref_te, x_cur_te], axis=0)
          ).float()
      else:
          x_all = x_ref_te + x_cur_te  # type: ignore[assignment]
  
      perms = [
          torch.randperm(m + n) for _ in range(self.n_permutations)
      ]
      mmd2, mmd2_permuted = self._mmd2(x_all, perms, m, n)
      if self.device.type == "cuda":
          mmd2, mmd2_permuted = mmd2.cpu(), mmd2_permuted.cpu()
      p_val = (mmd2 <= mmd2_permuted).float().mean()
  
      idx_threshold = int(self.p_val * len(mmd2_permuted))
      distance_threshold = torch.sort(
          mmd2_permuted, descending=True
      ).values[idx_threshold]
      return (
          p_val.numpy().item(),
          mmd2.numpy().item(),
          distance_threshold.numpy(),
      )
  
imports: from copy import deepcopy
  from functools import partial
  from tqdm import tqdm
  import numpy
  from pykeops.torch import LazyTensor
  import torch
  import torch.nn
  from torch.utils.data import DataLoader
  from typing import Callable, Dict, List, Optional, Union, Tuple
  from alibi_detect.cd.base import BaseLearnedKernelDrift
  from alibi_detect.utils.pytorch import get_device, predict_batch
  from alibi_detect.utils.pytorch.data import TorchDataset
  from alibi_detect.utils.frameworks import Framework
  from alibi_detect.utils._types import TorchDeviceType
label_desc: Use image node_id 2 for calling the LearnedKernelDriftKeops obj's underlying member method code with example usage: obj.score(x) and returns: p_val,  mmd2,  distance_threshold