public CollectionResult < double [ ] > run ( Database database , Relation < O > rel ) { DistanceQuery < O > dq = rel . getDistanceQuery ( getDistanceFunction ( ) ) ; int size = rel . size ( ) ; long pairs = ( size * ( long ) size ) >> 1 ; final long ssize = sampling <= 1 ? ( long ) Math . ceil ( sampling * pairs ) : ( long ) sampling ; if ( ssize > Integer . MAX_VALUE ) { throw new AbortException ( "Sampling size too large." ) ; } final int qsize = quantile <= 0 ? 1 : ( int ) Math . ceil ( quantile * ssize ) ; DoubleMaxHeap heap = new DoubleMaxHeap ( qsize ) ; ArrayDBIDs ids = DBIDUtil . ensureArray ( rel . getDBIDs ( ) ) ; DBIDArrayIter i1 = ids . iter ( ) , i2 = ids . iter ( ) ; Random r = rand . getSingleThreadedRandom ( ) ; FiniteProgress prog = LOG . isVerbose ( ) ? new FiniteProgress ( "Sampling" , ( int ) ssize , LOG ) : null ; for ( long i = 0 ; i < ssize ; i ++ ) { int x = r . nextInt ( size - 1 ) + 1 , y = r . nextInt ( x ) ; double dist = dq . distance ( i1 . seek ( x ) , i2 . seek ( y ) ) ; // Skip NaN, and/or zeros. if ( dist != dist || ( nozeros && dist < Double . MIN_NORMAL ) ) { continue ; } heap . add ( dist , qsize ) ; LOG . incrementProcessed ( prog ) ; } LOG . statistics ( new DoubleStatistic ( PREFIX + ".quantile" , quantile ) ) ; LOG . statistics ( new LongStatistic ( PREFIX + ".samplesize" , ssize ) ) ; LOG . statistics ( new DoubleStatistic ( PREFIX + ".distance" , heap . peek ( ) ) ) ; LOG . ensureCompleted ( prog ) ; Collection < String > header = Arrays . asList ( new String [ ] { "Distance" } ) ; Collection < double [ ] > data = Arrays . asList ( new double [ ] [ ] { new double [ ] { heap . peek ( ) } } ) ; return new CollectionResult < double [ ] > ( "Distances sample" , "distance-sample" , data , header ) ; }
Run the distance quantile sampler .