private void initializeClusters() {
    if (m_uniqueInitSamplesList.size() == 0) {
      throw new RuntimeException();
    }
    for (int i = 0; i < m_numClusters; i++) {
      int randomIndex = (int) Math.floor(m_uniqueInitSamplesList.size() * Math.random());
      m_clusters[i] =
          initSmoothClusterRandomly((IntTouple) m_uniqueInitSamplesList.get(randomIndex));
      m_uniqueInitSamplesList.remove(randomIndex);
    }

    m_state = state_updating;

    for (int i = 0; i < m_initCounter; i++) {
      addSample(m_initSamples[i]);
    }
  }
  private static long curveDistance(int x[], int y[], long abortIfGreaterThan) {
    long answer = 0;

    //		for(int i = 0; i < x.length; i++) {
    for (int i = x.length; --i >= 0; ) {
      answer += sqrLookup[Math.abs(x[i] - y[i])];
      if (answer > abortIfGreaterThan) {
        return Long.MAX_VALUE;
      }
    }

    return answer;
  }
  private boolean computeNewMeans() {
    boolean changed = false;
    double avg_delta = 0;
    for (int i = 0; i < m_numClusters; i++) {
      long delta = 0;

      int sampleToCopyFrom = (int) Math.floor(Math.random() * m_initSamples.length);

      if (m_tmpClusterCount[i] == 0) {
        System.out.println("    Warning: zero sized cluster");
      }

      for (int j = 0; j < m_dimensions; j++) {
        int newValue = 0;

        if (m_tmpClusterCount[i] != 0) {
          newValue = (int) Math.round((float) m_tmpClusterAccum[i][j] / m_tmpClusterCount[i]);
        } else {
          try {
            newValue = m_initSamples[sampleToCopyFrom][j];
          } catch (NullPointerException npe) {
            int count = 0;
            do {
              sampleToCopyFrom = (int) Math.floor(Math.random() * m_initSamples.length);
              count++;
              if (count == 50) {
                throw new RuntimeException();
              }
            } while (m_initSamples[sampleToCopyFrom] == null);
          }
        }

        if (!changed) {
          if (newValue != m_clusters[i][j]) {
            changed = true;
          }
        }

        delta += sqrLookup[Math.abs(newValue - m_clusters[i][j])];

        m_clusters[i][j] = newValue;
      }
      avg_delta += (delta / m_dimensions);
    }
    avg_delta /= m_numClusters;
    //		System.out.println("avg_delta per dimension: " + avg_delta);

    return changed;
  }