code: public static <T> GaussianRadialBasis learnGaussianRadialBasis(T[] x, T[] centers, Metric<T> distance) {
          int k = centers.length;
          CLARANS<T> clarans = new CLARANS<>(x, distance, k, Math.min(100, (int) Math.round(0.01 * k * (x.length - k))));
          System.arraycopy(clarans.medoids(), 0, centers, 0, k);
  
          double r0 = 0.0;
          for (int i = 0; i < k; i++) {
              for (int j = 0; j < i; j++) {
                  double d = distance.d(centers[i], centers[j]);
                  if (r0 < d) {
                      r0 = d;
                  }
              }
          }
  
          r0 /= Math.sqrt(2*k);
          return new GaussianRadialBasis(r0);
      }
docs: Learns Gaussian RBF function and centers from data. The centers are
  chosen as the medoids of CLARANS. Let d<sub>max</sub> be the maximum
  distance between the chosen centers, the standard deviation (i.e. width)
  of Gaussian radial basis function is d<sub>max</sub> / sqrt(2*k), where
  k is number of centers. In this way, the radial basis functions are not
  too peaked or too flat. This choice would be close to the optimal
  solution if the data were uniformly distributed in the input space,
  leading to a uniform distribution of medoids.
  @param x the training dataset.
  @param centers an array to store centers on output. Its length is used as k of CLARANS.
  @param distance the distance functor.
  @return a Gaussian RBF function with parameter learned from data.