protected void init(DistanceMatrix distanceMatrix) {

    numClusters = distanceMatrix.getTaxonCount();
    clusters = new SimpleNode[numClusters];

    distance = new double[numClusters][numClusters];
    for (int i = 0; i < numClusters; i++) {
      for (int j = 0; j < numClusters; j++) {
        distance[i][j] = distanceMatrix.getElement(i, j);
      }
    }

    for (int i = 0; i < numClusters; i++) {
      clusters[i] = new SimpleNode();
      clusters[i].setTaxon(distanceMatrix.getTaxon(i));
    }

    alias = new int[numClusters];
    tipCount = new int[numClusters];

    for (int i = 0; i < numClusters; i++) {
      alias[i] = i;
      tipCount[i] = 1;
    }
  }
  /**
   * constructor ClusteringTree
   *
   * @param distanceMatrix distance matrix
   */
  public ClusteringTree(DistanceMatrix distanceMatrix, int minimumTaxa) {

    this.distanceMatrix = distanceMatrix;

    if (distanceMatrix.getTaxonCount() < minimumTaxa) {
      throw new IllegalArgumentException("less than " + minimumTaxa + " taxa in distance matrix");
    }

    init(distanceMatrix);

    while (true) {
      findNextPair();

      if (numClusters < minimumTaxa) break;

      newCluster();
    }

    finish();
  }