code: public static double goodmanKruskalGamma(DoubleVector a, DoubleVector b) {
          check(a, b);
          // NOTE: slow n^2 version.  Needs to be replaced at some point with the
          // n-log-n method and to take into account sparse vectors. -jurgens
          int length = a.length();
          double numerator = 0;
          
          int concordant = 0;
          int discordant = 0;
  
          // For all pairs, track how many pairs satisfy the ordering
          for (int i = 0; i < length; ++i) {
              for (int j = i+1; j < length; ++j) {
                  // NOTE: this value will be 1 if there exists an match or
                  // "concordance" in the ordering of the two pairs.  Otherwise
                  // it, will be a -1 of the pairs are not matched or are
                  // "discordant.
                  double ai = a.get(i);
                  double aj = a.get(j);
                  double bi = b.get(i);
                  double bj = b.get(j);
  
                  // If there was a tied rank, don't count the comparisons towards
                  // the concordance totals
                  if (ai != aj && bi != bj) {
                      if ((ai < aj && bi < bj) || (ai > aj && bi > bj))
                          concordant++;
                      else
                          discordant++;
                  }
              }
          }
          
          int cd = concordant + discordant;
          return (cd == 0) 
              ? 0
              : ((double)(concordant - discordant)) / cd;
      }
docs: Computes the <a
  href="http://www.unesco.org/webworld/idams/advguide/Chapt4_2.htm">Goodman-Kruskal
  Gamma coefficient</a>, which is preferrable to Kendall's &tau; and
  Spearman's &rho; when there are many ties in the data.
  
  @throws IllegalArgumentException when the length of the two vectors are
  not the same.