code: public static GaussianRadialBasis[] learnGaussianRadialBasis(double[][] x, double[][] centers, double r) {
          if (r <= 0.0) {
              throw new IllegalArgumentException("Invalid scaling parameter: " + r);
          }
          
          int k = centers.length;
          KMeans kmeans = new KMeans(x, k, 10);
          System.arraycopy(kmeans.centroids(), 0, centers, 0, k);
  
          int n = x.length;
          int[] y = kmeans.getClusterLabel();
          double[] sigma = new double[k];
          for (int i = 0; i < n; i++) {
              sigma[y[i]] += Math.squaredDistance(x[i], centers[y[i]]);
          }
  
          int[] ni = kmeans.getClusterSize();
          GaussianRadialBasis[] rbf = new GaussianRadialBasis[k];
          for (int i = 0; i < k; i++) {
              if (ni[i] >= 5 || sigma[i] != 0.0) {
                  sigma[i] = Math.sqrt(sigma[i] / ni[i]);
              } else {
                  sigma[i] = Double.POSITIVE_INFINITY;
                  for (int j = 0; j < k; j++) {
                      if (i != j) {
                          double d = Math.distance(centers[i], centers[j]);
                          if (d < sigma[i]) {
                              sigma[i] = d;
                          }
                      }
                  }
                  sigma[i] /= 2.0;
              }
  
              rbf[i] = new GaussianRadialBasis(r * sigma[i]);            
          }
          
          return rbf;
      }
docs: Learns Gaussian RBF function and centers from data. The centers are
  chosen as the centroids of K-Means. The standard deviation (i.e. width)
  of Gaussian radial basis function is estimated as the width of each
  cluster multiplied with a given scaling parameter r.
  @param x the training dataset.
  @param centers an array to store centers on output. Its length is used as k of k-means.
  @param r the scaling parameter.
  @return Gaussian RBF functions with parameter learned from data.