@Override
  public void transform(RowWindow rowWindow, PointCollector collector) throws Exception {
    if (this.method.equals(DEFAULT_METHOD)) {
      int size = rowWindow.windowSize();
      Double[][] knn = new Double[size][dim];
      long[] timestamp = new long[size];
      int i = 0;
      int row = 0;
      while (row < rowWindow.windowSize()) {
        timestamp[i] = rowWindow.getRow(row).getTime();
        for (int j = 0; j < dim; j++) {
          if (!rowWindow.getRow(row).isNull(j)) {
            knn[i][j] = Util.getValueAsDouble(rowWindow.getRow(i), j);
          } else {
            i--;
            size--;
            break;
          }
        }
        i++;
        row++;
      }
      if (size > multipleK) {
        double[] lof = new double[size];
        for (int m = 0; m < size; m++) {
          try {
            lof[m] = getLOF(knn, knn[m], size);
            collector.putDouble(timestamp[m], lof[m]);
          } catch (Exception e) {
            throw new UDFException("Fail to get LOF " + m, e);
          }
        }
      }
    } else if (this.method.equals("series")) {
      int size = rowWindow.windowSize() - window + 1;
      if (size > 0) {
        Double[][] knn = new Double[size][window];
        long[] timestamp = new long[rowWindow.windowSize()];
        double temp;
        int i = 0;
        int row = 0;
        while (row < rowWindow.windowSize()) {
          timestamp[i] = rowWindow.getRow(row).getTime();
          if (!rowWindow.getRow(row).isNull(0)) {
            temp = Util.getValueAsDouble(rowWindow.getRow(row), 0);
            for (int p = 0; p < window; p++) {
              if (i - p < 0) {
                break;
              }
              if (i - p < size) {
                knn[i - p][p] = temp;
              }
            }
          } else {
            i--;
            size--;
          }
          i++;
          row++;
        }
        if (size > multipleK) {
          double[] lof = new double[size];
          for (int m = 0; m < size; m++) {
            try {
              lof[m] = getLOF(knn, knn[m], size);
              collector.putDouble(timestamp[m], lof[m]);
            } catch (Exception e) {
              throw new UDFException("Fail to get LOF " + m, e);
            }
          }
        }
      }
    }
  }
This function is used to detect density anomaly of time series.
library-udf/src/main/java/org/apache/iotdb/library/anomaly/UDTFLOF.java