public OutlierResult run(Relation<O> relation) {
    final int k1 = k + 1; // Query size
    final double perplexity = k / 3.;
    KNNQuery<O> knnq = relation.getKNNQuery(getDistanceFunction(), k1);
    final double logPerp = perplexity > 1. ? FastMath.log(perplexity) : .1;

    double[] p = new double[k + 10];
    ModifiableDoubleDBIDList dists = DBIDUtil.newDistanceDBIDList(k + 10);
    DoubleDBIDListIter di = dists.iter();
    FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("ISOS scores", relation.size(), LOG) : null;
    WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_DB, 1.);
    for(DBIDIter it = relation.iterDBIDs(); it.valid(); it.advance()) {
      KNNList knns = knnq.getKNNForDBID(it, k1);
      if(p.length < knns.size() + 1) {
        p = new double[knns.size() + 10];
      }
      final DoubleDBIDListIter ki = knns.iter();
      try {
        double id = estimateID(it, ki, p);
        adjustDistances(it, ki, knns.getKNNDistance(), id, dists);
        // We now continue with the modified distances below.
        // Compute affinities
        SOS.computePi(it, di, p, perplexity, logPerp);
        // Normalization factor:
        double s = SOS.sumOfProbabilities(it, di, p);
        if(s > 0.) {
          nominateNeighbors(it, di, p, 1. / s, scores);
        }
      }
      catch(ArithmeticException e) {
        // ID estimation failed, supposedly constant values because of too many
        // duplicate points, or too small k. Fall back to KNNSOS.
        // Note: this looks almost identical to the above, but uses ki instead
        // of the adjusted distances di!
        // Compute affinities
        SOS.computePi(it, ki, p, perplexity, logPerp);
        // Normalization factor:
        double s = SOS.sumOfProbabilities(it, ki, p);
        if(s > 0.) {
          nominateNeighbors(it, ki, p, 1. / s, scores);
        }
      }
      LOG.incrementProcessed(prog);
    }
    LOG.ensureCompleted(prog);
    DoubleMinMax minmax = transformScores(scores, relation.getDBIDs(), logPerp, phi);
    DoubleRelation scoreres = new MaterializedDoubleRelation("Intrinsic Stoachastic Outlier Selection", "isos-outlier", scores, relation.getDBIDs());
    OutlierScoreMeta meta = new ProbabilisticOutlierScore(minmax.getMin(), minmax.getMax(), 0.);
    return new OutlierResult(meta, scoreres);
  }
public OutlierResult run ( Relation < O > relation ) { final int k1 = k + 1 ; final double perplexity = k / 3. ; KNNQuery < O > knnq = relation . getKNNQuery ( getDistanceFunction ( ) , k1 ) ; final double logPerp = perplexity > 1. ? FastMath . log ( perplexity ) : .1 ; double [ ] p = new double [ k + 10 ] ; ModifiableDoubleDBIDList dists = DBIDUtil . newDistanceDBIDList ( k + 10 ) ; DoubleDBIDListIter di = dists . iter ( ) ; FiniteProgress prog = LOG . isVerbose ( ) ? new FiniteProgress ( "ISOS scores" , relation . size ( ) , LOG ) : null ; WritableDoubleDataStore scores = DataStoreUtil . makeDoubleStorage ( relation . getDBIDs ( ) , DataStoreFactory . HINT_HOT | DataStoreFactory . HINT_DB , 1. ) ; for ( DBIDIter it = relation . iterDBIDs ( ) ; it . valid ( ) ; it . advance ( ) ) { KNNList knns = knnq . getKNNForDBID ( it , k1 ) ; if ( p . length < knns . size ( ) + 1 ) { p = new double [ knns . size ( ) + 10 ] ; } final DoubleDBIDListIter ki = knns . iter ( ) ; try { double id = estimateID ( it , ki , p ) ; adjustDistances ( it , ki , knns . getKNNDistance ( ) , id , dists ) ; SOS . computePi ( it , di , p , perplexity , logPerp ) ; double s = SOS . sumOfProbabilities ( it , di , p ) ; if ( s > 0. ) { nominateNeighbors ( it , di , p , 1. / s , scores ) ; } } catch ( ArithmeticException e ) { SOS . computePi ( it , ki , p , perplexity , logPerp ) ; double s = SOS . sumOfProbabilities ( it , ki , p ) ; if ( s > 0. ) { nominateNeighbors ( it , ki , p , 1. / s , scores ) ; } } LOG . incrementProcessed ( prog ) ; } LOG . ensureCompleted ( prog ) ; DoubleMinMax minmax = transformScores ( scores , relation . getDBIDs ( ) , logPerp , phi ) ; DoubleRelation scoreres = new MaterializedDoubleRelation ( "Intrinsic Stoachastic Outlier Selection" , "isos-outlier" , scores , relation . getDBIDs ( ) ) ; OutlierScoreMeta meta = new ProbabilisticOutlierScore ( minmax . getMin ( ) , minmax . getMax ( ) , 0. ) ; return new OutlierResult ( meta , scoreres ) ; }
Run the algorithm.

@param relation data relation.
@return outlier detection result