/** Associates the features together. */
  public void associate() {
    // initialize data structures
    matches.reset();
    unassociatedSrc.reset();

    // find and add the matches
    assoc.setSource((FastQueue) srcPositive);
    assoc.setDestination((FastQueue) dstPositive);
    assoc.associate();
    FastQueue<AssociatedIndex> m = assoc.getMatches();
    for (int i = 0; i < m.size; i++) {
      AssociatedIndex a = m.data[i];
      int globalSrcIndex = srcPositive.data[a.src].index;
      int globalDstIndex = dstPositive.data[a.dst].index;
      matches.grow().setAssociation(globalSrcIndex, globalDstIndex, a.fitScore);
    }
    GrowQueue_I32 un = assoc.getUnassociatedSource();
    for (int i = 0; i < un.size; i++) {
      unassociatedSrc.add(srcPositive.data[un.get(i)].index);
    }
    assoc.setSource((FastQueue) srcNegative);
    assoc.setDestination((FastQueue) dstNegative);
    assoc.associate();
    m = assoc.getMatches();
    for (int i = 0; i < m.size; i++) {
      AssociatedIndex a = m.data[i];
      int globalSrcIndex = srcNegative.data[a.src].index;
      int globalDstIndex = dstNegative.data[a.dst].index;
      matches.grow().setAssociation(globalSrcIndex, globalDstIndex, a.fitScore);
    }
    un = assoc.getUnassociatedSource();
    for (int i = 0; i < un.size; i++) {
      unassociatedSrc.add(srcNegative.data[un.get(i)].index);
    }
  }