code: def compare_svm(
      svm1,
      svm2,
      X,
      y,
      b_tol=None,
      coef_tol=None,
      report_summary=False,
      cmp_decision_func=False,
  ):
      """Compares two svm classifiers
      Parameters:
      -----------
      svm1 : svm classifier to be tested
      svm2 : svm classifier, the correct model
      b_tol : float
          tolerance while comparing the constant in the decision functions
      coef_tol: float
          tolerance used while comparing coef_ attribute for linear SVM
  
      Support vector machines have a decision function:
  
      F(x) = sum_{i=1}^{n_sv} d_i K(x_i, x) + b,
  
      where n_sv is the number of support vectors, K is the kernel function, x_i
      are the support vectors, d_i are the dual coefficients (more precisely
      d = alpha_i * y_i, where alpha_i is the dual coef), and b is the intercept.
  
      For linear svms K(x_i, x) = x_i * x, and we can simplify F by introducing
      w = sum_{i=1}^{n_sv} d_i x_i, the normal vector of the separating
      hyperplane:
  
      F(x) = w * x + b.
  
      Mathematically the solution of the optimization should be unique, which
      means w and b should be unique.
  
      There could be multiple set of vectors that lead to the same w, therefore
      comparing parameters d_k, n_sv or the support vector indices can lead to
      false positives.
  
      We can only evaluate w for linear models, for nonlinear models we can only
      test model accuracy and intercept.
      """
  
      n = X.shape[0]
      accuracy1 = svm1.score(X, y)
      accuracy2 = svm2.score(X, y)
  
      # We use at least 0.1% tolerance for accuracy comparison
      accuracy_tol_min = 0.001
      if accuracy2 < 1:
          # Set tolerance to include the 95% confidence interval of svm2's
          # accuracy. In practice this gives 0.9% tolerance for a 90% accurate
          # model (assuming n_test = 4000).
          accuracy_tol = 1.96 * np.sqrt(accuracy2 * (1 - accuracy2) / n)
          if accuracy_tol < accuracy_tol_min:
              accuracy_tol = accuracy_tol_min
      else:
          accuracy_tol = accuracy_tol_min
  
      assert accuracy1 >= accuracy2 - accuracy_tol
  
      if b_tol is None:
          b_tol = (
              100 * svm1.tol
          )  # Using default tol=1e-3 leads to b_tol=0.1
  
      if accuracy2 < 0.5:
          # Increase error margin for classifiers that are not accurate.
          # Although analytically the classifier should always be the same,
          # we fit only until we reach a certain numerical tolerance, and
          # therefore the resulting SVM's can be different. We increase the
          # tolerance in these cases.
          #
          # A good example is the gaussian dataset with linear classifier:
          # the classes are concentric blobs, and we cannot separate that with a
          # straight line. When we have a large number of data points, then
          # any separating hyperplane that goes through the center would be good.
          b_tol *= 10
          if n >= 250:
              coef_tol = 2  # allow any direction
          else:
              coef_tol *= 10
  
      # Compare model parameter b (intercept). In practice some models can have
      # some differences in the model parameters while still being within
      # the accuracy tolerance.
      #
      # We skip this test for multiclass (when intercept_ is an array). Apart
      # from the larger discrepancies in multiclass case, sklearn also uses a
      # different sign convention for intercept in that case.
      if (not is_array_like(svm2.intercept_)) or svm2.intercept_.shape[
          0
      ] == 1:
          if abs(svm2.intercept_) > 1e-6:
              assert (
                  abs(
                      (svm1.intercept_ - svm2.intercept_)
                      / svm2.intercept_
                  )
                  <= b_tol
              )
          else:
              assert abs((svm1.intercept_ - svm2.intercept_)) <= b_tol
  
      # For linear kernels we can compare the normal vector of the separating
      # hyperplane w, which is stored in the coef_ attribute.
      if svm1.kernel == "linear":
          if coef_tol is None:
              coef_tol = 1e-5
          cs = np.dot(svm1.coef_, svm2.coef_.T) / (
              np.linalg.norm(svm1.coef_) * np.linalg.norm(svm2.coef_)
          )
          assert cs > 1 - coef_tol
  
      if cmp_decision_func:
          if accuracy2 > 0.9 and svm1.kernel != "sigmoid":
              df1 = svm1.decision_function(X)
              df2 = svm2.decision_function(X)
              # For classification, the class is determined by
              # sign(decision function). We should not expect tight match for
              # the actual value of the function, therefore we set large tolerance
              assert svm_array_equal(
                  df1,
                  df2,
                  tol=1e-1,
                  relative_diff=True,
                  report_summary=True,
              )
          else:
              print(
                  "Skipping decision function test due to low  accuracy",
                  accuracy2,
              )
  
      # Compare support_ (dataset indices of points that form the support
      # vectors) and ensure that some overlap (~1/8) between two exists
      support1 = set(svm1.support_)
      support2 = set(svm2.support_)
      intersection_len = len(support1.intersection(support2))
      average_len = (len(support1) + len(support2)) / 2
      assert intersection_len > average_len / 8
  
imports: import pytest
  from cuml.internals.mem_type import MemoryType
  from cuml.internals.input_utils import input_to_cuml_array, is_array_like
  from cuml.internals.base import Base
  import cuml
  from sklearn.model_selection import train_test_split
  from sklearn.metrics import mean_squared_error, brier_score_loss
  from sklearn.datasets import make_classification, make_regression
  from sklearn import datasets
  from pylibraft.common.cuda import Stream
  from sklearn.datasets import make_regression
  from numba.cuda.cudadrv.devicearray import DeviceNDArray
  from numbers import Number
  from cuml.internals.safe_imports import gpu_only_import_from
  from itertools import dropwhile
  from copy import deepcopy
  from cuml.internals.safe_imports import cpu_only_import
  import inspect
  from textwrap import dedent, indent
  from cuml.internals.safe_imports import gpu_only_import
label_desc: Use image node_id 23 for calling a global function with example usage: compare_svm(svm1, svm2, X, y, b_tol, coef_tol, report_summary, cmp_decision_func) without return types