class_docstr: Jointly trains 2 surrogate decision trees.
  Refines diff (or sim) regions by sample generation.
code: def find_best_split_of_all_double(
      self,
      x1: np.ndarray,
      y1: np.ndarray,
      x2: np.ndarray,
      y2: np.ndarray,
  ):
      if isinstance(x1, pd.DataFrame):
          x1 = x1.to_numpy()
      if isinstance(y1, pd.Series):
          y1 = y1.to_numpy()
      if isinstance(x2, pd.DataFrame):
          x2 = x2.to_numpy()
      if isinstance(y2, pd.Series):
          y2 = y2.to_numpy()
  
      col = None
      min_entropy = 10
      cutoff = None
  
      for idx, c in enumerate(x1.T):
          values = np.unique(c)
          split_points = (values[:-1] + values[1:]) / 2
  
          for value in split_points:
              y_predict = c < value
              cur_entropy1 = self.get_entropy_split(y_predict, y1)
              cur_entropy2 = self.get_entropy_split(y_predict, y2)
              cur_entropy = (cur_entropy1 + cur_entropy2) / 2
  
              # choose a split that minimizes entropy of sum of the two
              if cur_entropy == 0:
                  return idx, value, cur_entropy
  
              elif cur_entropy <= min_entropy:
                  min_entropy = cur_entropy
                  col = idx
                  cutoff = value
  
      return col, cutoff, min_entropy
  
imports: import numpy
  import pandas
  from aix360.algorithms.imd.rule import Rule
label_desc: Use image node_id 8 for calling the JointSurrogateTree obj's underlying member method code with example usage: obj.find_best_split_of_all_double(x1, y1, x2, y2) and returns: col,  cutoff,  min_entropy, idx,  value,  cur_entropy