public DoubleDistance distance(DBID id1, DBID id2) {
Matrix m1 = index.getLocalProjection(id1).similarityMatrix();
Matrix m2 = index.getLocalProjection(id2).similarityMatrix();
if(m1 == null || m2 == null) {
return new DoubleDistance(Double.POSITIVE_INFINITY);
}
V v1 = relation.get(id1);
V v2 = relation.get(id2);
Vector v1Mv2 = v1.getColumnVector().minusEquals(v2.getColumnVector());
Vector v2Mv1 = v2.getColumnVector().minusEquals(v1.getColumnVector());
double dist1 = v1Mv2.transposeTimesTimes(m1, v1Mv2);
double dist2 = v2Mv1.transposeTimesTimes(m2, v2Mv1);
if(dist1 < 0) {
if(-dist1 < 0.000000000001) {
dist1 = 0;
}
else {
throw new IllegalArgumentException("dist1 " + dist1 + " < 0!");
}
}
if(dist2 < 0) {
if(-dist2 < 0.000000000001) {
dist2 = 0;
}
else {
throw new IllegalArgumentException("dist2 " + dist2 + " < 0!");
}
}
return new DoubleDistance(Math.max(Math.sqrt(dist1), Math.sqrt(dist2)));
}