code: def approx_kernel_based(
      X: np.ndarray,
      Y: np.ndarray,
      Z: Optional[np.ndarray] = None,
      num_random_features_X: int = 50,
      num_random_features_Y: int = 50,
      num_random_features_Z: int = 50,
      num_permutations: int = 100,
      approx_kernel: Callable[
          [np.ndarray], np.ndarray
      ] = approximate_rbf_kernel_features,
      scale_data: bool = False,
      use_bootstrap: bool = True,
      bootstrap_num_runs: int = 10,
      bootstrap_num_samples: int = 1000,
      bootstrap_n_jobs: Optional[int] = None,
      p_value_adjust_func: Callable[
          [Union[np.ndarray, List[float]]], float
      ] = quantile_based_fwer,
  ) -> float:
      """Implementation of the Randomized Conditional Independence Test. The independence test estimates a p-value
      for the null hypothesis that X and Y are independent (given Z). Depending whether Z is given, a conditional or
      pairwise independence test is performed.
  
      If Z is given: Using RCIT as conditional independence test.
      If Z is not given: Using RIT as pairwise independence test.
  
      Note:
      - The data can be multivariate, i.e. the given input matrices can have multiple columns.
      - Categorical data need to be represented as strings.
      - It is possible to apply a different kernel to each column in the matrices. For instance, a RBF kernel for the
        first dimension in X and a delta kernel for the second.
  
      Based on the work:
          Strobl, Eric V., Kun Zhang, and Shyam Visweswaran.
          Approximate kernel-based conditional independence tests for fast non-parametric causal discovery.
          Journal of Causal Inference 7.1 (2019).
  
      :param X: Data matrix for observations from X.
      :param Y: Data matrix for observations from Y.
      :param Z: Optional data matrix for observations from Z. This is the conditional variable.
      :param num_random_features_X: Number of features sampled from the approximated kernel map for X.
      :param num_random_features_Y: Number of features sampled from the approximated kernel map for Y.
      :param num_random_features_Z: Number of features sampled from the approximated kernel map for Z.
      :param num_permutations: Number of permutations for estimating the test test statistic.
      :param approx_kernel: The approximated kernel map. The expected input is a n x d numpy array and the output is
                            expected to be a n x k numpy array with k << d. By default, the Nystroem method with a RBF
                            kernel is used.
      :param scale_data: If set to True, the data will be standardized. If set to False, the data is taken as it is.
                         Standardizing the data helps in identifying weak dependencies. If one is only interested in
                         stronger ones, consider setting this to False.
      :param use_bootstrap: If True, the independence tests are performed on multiple subsets of the data and the final
                            p-value is constructed based on the provided p_value_adjust_func function.
      :param bootstrap_num_runs: Number of bootstrap runs (only relevant if use_bootstrap is True).
      :param bootstrap_num_samples: Maximum number of used samples per bootstrap run.
      :param bootstrap_n_jobs: Number of parallel jobs for the bootstrap runs.
      :param p_value_adjust_func: A callable that expects a numpy array of multiple p-values and returns one p-value. This
                                  is typically used a family wise error rate control method.
      :return: The p-value for the null hypothesis that X and Y are independent (given Z).
      """
      bootstrap_n_jobs = (
          config.default_n_jobs
          if bootstrap_n_jobs is None
          else bootstrap_n_jobs
      )
  
      X = _remove_constant_columns(X)
      Y = _remove_constant_columns(Y)
  
      if X.shape[1] == 0 or Y.shape[1] == 0:
          # Either X and/or Y is constant.
          return 1.0
  
      if Z is not None:
          Z = _remove_constant_columns(Z)
          if Z.shape[1] == 0:
              # If Z is empty, we are in the pairwise setting.
              Z = None
  
      if not use_bootstrap:
          bootstrap_num_runs = 1
          bootstrap_num_samples = float("inf")
          bootstrap_n_jobs = 1
  
      if Z is None:
          return _rit(
              X,
              Y,
              num_permutations=num_permutations,
              num_random_features_X=num_random_features_X,
              num_random_features_Y=num_random_features_Y,
              num_runs=bootstrap_num_runs,
              num_max_samples_per_run=bootstrap_num_samples,
              approx_kernel=approx_kernel,
              scale_data=scale_data,
              n_jobs=bootstrap_n_jobs,
              p_value_adjust_func=p_value_adjust_func,
          )
      else:
          return _rcit(
              X,
              Y,
              Z,
              num_permutations=num_permutations,
              num_random_features_X=num_random_features_X,
              num_random_features_Y=num_random_features_Y,
              num_random_features_Z=num_random_features_Z,
              num_runs=bootstrap_num_runs,
              num_max_samples_per_run=bootstrap_num_samples,
              approx_kernel=approx_kernel,
              scale_data=scale_data,
              n_jobs=bootstrap_n_jobs,
              p_value_adjust_func=p_value_adjust_func,
          )
  
file_path: dowhy/dowhy/gcm/independence_test/kernel.py
imports: from typing import Callable, List, Optional, Union
  import numpy
  import scipy
  from causallearn.utils.KCI.KCI import KCI_CInd, KCI_UInd
  from joblib import Parallel, delayed
  from sklearn.preprocessing import scale
  import dowhy.gcm.config
  from dowhy.gcm.independence_test.kernel_operation import approximate_rbf_kernel_features
  from dowhy.gcm.stats import quantile_based_fwer
  from dowhy.gcm.util.general import auto_apply_encoders, auto_fit_encoders, set_random_seed, shape_into_2d
label_desc: Use image node_id 2 for calling a global function with example usage: approx_kernel_based(X, Y, Z, num_random_features_X, num_random_features_Y, num_random_features_Z, num_permutations, approx_kernel, scale_data, use_bootstrap, bootstrap_num_runs, bootstrap_num_samples, bootstrap_n_jobs, p_value_adjust_func) and returns: int, _rit, _rcit