code: public static double[][] histogram(int[] data, double[] breaks) {
          int k = breaks.length - 1;
          if (k <= 1) {
              throw new IllegalArgumentException("Invalid number of bins: " + k);
          }
          
          double[][] freq = new double[3][k];
          for (int i = 0; i < k; i++) {
              freq[0][i] = breaks[i];
              freq[1][i] = breaks[i + 1];
              freq[2][i] = 0;
          }
  
          for (int d : data) {
              int j = Arrays.binarySearch(breaks, d);
              
              if (j >= k) {
                  j = k - 1;
              }
  
              if (j < -1 && j >= -breaks.length) {
                  j = -j - 2;
              }
              
              if (j >= 0) {
                  freq[2][j]++;
              }
          }
  
          return freq;
      }
docs: Generate the histogram of n bins.
  @param data the data points.
  @param breaks an array of size k+1 giving the breakpoints between
  histogram cells. Must be in ascending order.
  @return a 3-by-n bins array of which first row is the lower bound of bins,
  second row is the upper bound of bins, and the third row is the frequence
  count.