/** * Subspace relevance test. * * @param subspace Subspace to test * @param neigh Neighbor list * @param kernel Kernel density estimator * @return relevance test result */ protected boolean relevantSubspace( long[] subspace, DoubleDBIDList neigh, KernelDensityEstimator kernel) { Relation<V> relation = kernel.relation; final double crit = K_S_CRITICAL001 / Math.sqrt(neigh.size()); for (int dim = BitsUtil.nextSetBit(subspace, 0); dim > 0; dim = BitsUtil.nextSetBit(subspace, dim + 1)) { // TODO: can we save this copy somehow? double[] data = new double[neigh.size()]; { int count = 0; for (DBIDIter neighbor = neigh.iter(); neighbor.valid(); neighbor.advance()) { V vector = relation.get(neighbor); data[count] = vector.doubleValue(dim); count++; } assert (count == neigh.size()); } Arrays.sort(data); final double norm = data[data.length - 1] - data[0]; final double min = data[0]; // Kolmogorow-Smirnow-Test against uniform distribution: for (int j = 1; j < data.length - 2; j++) { double delta = (j / (data.length - 1.)) - ((data[j] - min) / norm); if (Math.abs(delta) > crit) { return false; } } } return true; }
@Override protected double minDistObject(SpatialComparable mbr, NumberVector v) { if (mbr.getDimensionality() != v.getDimensionality()) { throw new IllegalArgumentException( "Different dimensionality of objects\n " + "first argument: " + mbr.toString() + "\n " + "second argument: " + v.toString()); } double agg = 0.; for (int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) { final double value = v.doubleValue(d); final double omin = mbr.getMin(d); final double diff1 = omin - value; if (diff1 > 0.) { if (diff1 > agg) { agg = diff1; } } else { final double omax = mbr.getMax(d); final double diff2 = value - omax; if (diff2 > agg) { agg = diff2; } } } return agg; }
@Override public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) { if (mbr1.getDimensionality() != mbr2.getDimensionality()) { throw new IllegalArgumentException( "Different dimensionality of objects\n " + "first argument: " + mbr1.toString() + "\n " + "second argument: " + mbr2.toString()); } double agg = 0.; for (int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) { final double max1 = mbr1.getMax(d); final double min2 = mbr2.getMin(d); if (max1 < min2) { double v = min2 - max1; if (v > agg) { agg = v; } } else { final double min1 = mbr1.getMin(d); final double max2 = mbr2.getMax(d); double v = min1 - max2; if (v > agg) { agg = v; } } } return agg; }
@Override public double norm(NumberVector obj) { double agg = 0.; for (int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) { double v = Math.abs(obj.doubleValue(d)); if (v > agg) { agg = v; } } return agg; }
@Override public double distance(NumberVector v1, NumberVector v2) { if (v1.getDimensionality() != v2.getDimensionality()) { throw new IllegalArgumentException( "Different dimensionality of FeatureVectors\n " + "first argument: " + v1 + "\n " + "second argument: " + v2); } double agg = 0.; for (int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) { double v = Math.abs(v1.doubleValue(d) - v2.doubleValue(d)); if (v > agg) { agg = v; } } return agg; }