IntVect OffBitsInCommon(const T1& bv1, const T2& bv2) { if (bv1.getNumBits() != bv2.getNumBits()) throw ValueErrorException("BitVects must be same length"); IntVect res; (~(bv1 | bv2)).getOnBits(res); return res; }
double SokalSimilarity(const T1& bv1, const T2& bv2) { if (bv1.getNumBits() != bv2.getNumBits()) throw ValueErrorException("BitVects must be same length"); double x = NumOnBitsInCommon(bv1, bv2); double y = bv1.getNumOnBits(); double z = bv2.getNumOnBits(); return x / (2 * y + 2 * z - 3 * x); }
DoubleVect OffBitProjSimilarity(const T1& bv1, const T2& bv2) { if (bv1.getNumBits() != bv2.getNumBits()) throw ValueErrorException("BitVects must be same length"); DoubleVect res(2, 0.0); double num = (bv1 | bv2).getNumOffBits(); if (num) { res[0] = num / bv1.getNumOffBits(); res[1] = num / bv2.getNumOffBits(); } return res; }
double TanimotoSimilarity(const T1& bv1, const T2& bv2) { if (bv1.getNumBits() != bv2.getNumBits()) throw ValueErrorException("BitVects must be same length"); double x = NumOnBitsInCommon(bv1, bv2); double y = bv1.getNumOnBits(); double z = bv2.getNumOnBits(); if ((y + z - x) == 0.0) return 1.0; else return x / (y + z - x); }
double OnBitSimilarity(const T1& bv1, const T2& bv2) { if (bv1.getNumBits() != bv2.getNumBits()) throw ValueErrorException("BitVects must be same length"); double num = NumOnBitsInCommon(bv1, bv2); double denom = (bv1 | bv2).getNumOnBits(); if (denom > 0) { return num / denom; } else { return 0; } }
double RogotGoldbergSimilarity(const T1& bv1, const T2& bv2) { if (bv1.getNumBits() != bv2.getNumBits()) throw ValueErrorException("BitVects must be same length"); double x = NumOnBitsInCommon(bv1, bv2); double y = bv1.getNumOnBits(); double z = bv2.getNumOnBits(); double l = bv1.getNumBits(); double d = l - y - z + x; if ((x == l) || (d == l)) return 1.0; else return (x / (y + z) + (d) / (2 * l - y - z)); }
double BraunBlanquetSimilarity(const T1& bv1, const T2& bv2) { if (bv1.getNumBits() != bv2.getNumBits()) throw ValueErrorException("BitVects must be same length"); double x = NumOnBitsInCommon(bv1, bv2); double y = bv1.getNumOnBits(); double z = bv2.getNumOnBits(); if (tmax(y, z) > 0) { return x / tmax(y, z); } else { return 0.0; } }
double McConnaugheySimilarity(const T1& bv1, const T2& bv2) { if (bv1.getNumBits() != bv2.getNumBits()) throw ValueErrorException("BitVects must be same length"); double x = NumOnBitsInCommon(bv1, bv2); double y = bv1.getNumOnBits(); double z = bv2.getNumOnBits(); if (y * z > 0.0) { return (x * (y + z) - (y * z)) / (y * z); } else { return 0.0; } }
double CosineSimilarity(const T1& bv1, const T2& bv2) { if (bv1.getNumBits() != bv2.getNumBits()) throw ValueErrorException("BitVects must be same length"); double x = NumOnBitsInCommon(bv1, bv2); double y = bv1.getNumOnBits(); double z = bv2.getNumOnBits(); if (y * z > 0.0) { return x / sqrt(y * z); } else { return 0.0; } }
double TverskySimilarity(const T1& bv1, const T2& bv2, double a, double b) { RANGE_CHECK(0, a, 1); RANGE_CHECK(0, b, 1); if (bv1.getNumBits() != bv2.getNumBits()) throw ValueErrorException("BitVects must be same length"); double x = NumOnBitsInCommon(bv1, bv2); double y = bv1.getNumOnBits(); double z = bv2.getNumOnBits(); double denom = a * y + b * z + (1 - a - b) * x; if (denom == 0.0) return 1.0; else return x / denom; }
double AllBitSimilarity(const T1& bv1, const T2& bv2) { if (bv1.getNumBits() != bv2.getNumBits()) throw ValueErrorException("BitVects must be same length"); return double(NumBitsInCommon(bv1, bv2)) / bv1.getNumBits(); }
int NumBitsInCommon(const T1& bv1, const T2& bv2) { if (bv1.getNumBits() != bv2.getNumBits()) throw ValueErrorException("BitVects must be same length"); return bv1.getNumBits() - (bv1 ^ bv2).getNumOnBits(); }