private void bulkLoad(double[] lmin,double[] lmax,List<Node> children,ArrayModifiableDBIDs ids,int start,int end,int dim,int level,int code){
  if (dim == 0) {
    DBIDArrayIter iter=ids.iter();
    iter.seek(start);
    NumberVector first=relation.get(iter);
    iter.advance();
    boolean degenerate=true;
    loop:     for (; iter.getOffset() < end; iter.advance()) {
      NumberVector other=relation.get(iter);
      for (int d=0; d < lmin.length; d++) {
        if (Math.abs(first.doubleValue(d) - other.doubleValue(d)) > 1E-15) {
          degenerate=false;
          break loop;
        }
      }
    }
    if (degenerate) {
      double[] center=new double[lmin.length];
      for (int d=0; d < lmin.length; d++) {
        center[d]=lmin[d] * .5 + lmax[d] * .5 + shift[d];
        if (center[d] > min[d] + width[d]) {
          center[d]-=width[d];
        }
      }
      children.add(new Node(code,center,end - start,level,null));
      return;
    }
  }
  if (dim == lmin.length) {
    double[] center=new double[lmin.length];
    for (int d=0; d < lmin.length; d++) {
      center[d]=lmin[d] * .5 + lmax[d] * .5 + shift[d];
      if (center[d] > min[d] + width[d]) {
        center[d]-=width[d];
      }
    }
    if (end - start < nmin) {
      children.add(new Node(code,center,end - start,level,null));
      return;
    }
 else {
      List<Node> newchildren=new ArrayList<>();
      bulkLoad(lmin,lmax,newchildren,ids,start,end,0,level + 1,0);
      children.add(new Node(code,center,end - start,level,newchildren));
      return;
    }
  }
 else {
    DBIDArrayIter siter=ids.iter(), eiter=ids.iter();
    siter.seek(start);
    eiter.seek(end - 1);
    while (siter.getOffset() < eiter.getOffset()) {
      if (getShiftedDim(relation.get(siter),dim,level) <= .5) {
        siter.advance();
        continue;
      }
      if (getShiftedDim(relation.get(eiter),dim,level) > 0.5) {
        eiter.retract();
        continue;
      }
      ids.swap(siter.getOffset(),eiter.getOffset() - 1);
      siter.advance();
      eiter.retract();
    }
    final int spos=siter.getOffset();
    if (start < spos) {
      final double tmp=lmax[dim];
      lmax[dim]=lmax[dim] * .5 + lmin[dim] * .5;
      bulkLoad(lmin,lmax,children,ids,start,spos,dim + 1,level,code);
      lmax[dim]=tmp;
    }
    if (spos < end) {
      final double tmp=lmin[dim];
      lmin[dim]=lmax[dim] * .5 + lmin[dim] * .5;
      bulkLoad(lmin,lmax,children,ids,spos,end,dim + 1,level,code | (1 << dim));
      lmin[dim]=tmp;
    }
  }
}

private void bulkLoad ( double [ ] lmin , double [ ] lmax , List < Node > children , ArrayModifiableDBIDs ids , int start , int end , int dim , int level , int code ) { if ( dim == 0 ) { DBIDArrayIter iter = ids . iter ( ) ; iter . seek ( start ) ; NumberVector first = relation . get ( iter ) ; iter . advance ( ) ; boolean degenerate = true ; loop : for ( ; iter . getOffset ( ) < end ; iter . advance ( ) ) { NumberVector other = relation . get ( iter ) ; for ( int d = 0 ; d < lmin . length ; d ++ ) { if ( Math . abs ( first . doubleValue ( d ) - other . doubleValue ( d ) ) > 1E-15 ) { degenerate = false ; break loop ; } } } if ( degenerate ) { double [ ] center = new double [ lmin . length ] ; for ( int d = 0 ; d < lmin . length ; d ++ ) { center [ d ] = lmin [ d ] * .5 + lmax [ d ] * .5 + shift [ d ] ; if ( center [ d ] > min [ d ] + width [ d ] ) { center [ d ] -= width [ d ] ; } } children . add ( new Node ( code , center , end - start , level , null ) ) ; return ; } } if ( dim == lmin . length ) { double [ ] center = new double [ lmin . length ] ; for ( int d = 0 ; d < lmin . length ; d ++ ) { center [ d ] = lmin [ d ] * .5 + lmax [ d ] * .5 + shift [ d ] ; if ( center [ d ] > min [ d ] + width [ d ] ) { center [ d ] -= width [ d ] ; } } if ( end - start < nmin ) { children . add ( new Node ( code , center , end - start , level , null ) ) ; return ; } else { List < Node > newchildren = new ArrayList < > ( ) ; bulkLoad ( lmin , lmax , newchildren , ids , start , end , 0 , level + 1 , 0 ) ; children . add ( new Node ( code , center , end - start , level , newchildren ) ) ; return ; } } else { DBIDArrayIter siter = ids . iter ( ) , eiter = ids . iter ( ) ; siter . seek ( start ) ; eiter . seek ( end - 1 ) ; while ( siter . getOffset ( ) < eiter . getOffset ( ) ) { if ( getShiftedDim ( relation . get ( siter ) , dim , level ) <= .5 ) { siter . advance ( ) ; continue ; } if ( getShiftedDim ( relation . get ( eiter ) , dim , level ) > 0.5 ) { eiter . retract ( ) ; continue ; } ids . swap ( siter . getOffset ( ) , eiter . getOffset ( ) - 1 ) ; siter . advance ( ) ; eiter . retract ( ) ; } final int spos = siter . getOffset ( ) ; if ( start < spos ) { final double tmp = lmax [ dim ] ; lmax [ dim ] = lmax [ dim ] * .5 + lmin [ dim ] * .5 ; bulkLoad ( lmin , lmax , children , ids , start , spos , dim + 1 , level , code ) ; lmax [ dim ] = tmp ; } if ( spos < end ) { final double tmp = lmin [ dim ] ; lmin [ dim ] = lmax [ dim ] * .5 + lmin [ dim ] * .5 ; bulkLoad ( lmin , lmax , children , ids , spos , end , dim + 1 , level , code | ( 1 << dim ) ) ; lmin [ dim ] = tmp ; } } }
bulk load the tree
