/// <summary> /// Get hash similarity of one song /// </summary> /// <param name = "service">Fingerprint service</param> /// <param name = "hashTables">Number of hash tables in the LSH transformation</param> /// <param name = "hashKeys">Number of hash keys per table in the LSH transformation</param> /// <param name = "path">Path to analyzed file</param> /// <param name = "results">Results object to be filled with the appropriate data</param> private void GetHashSimilarity(IFingerprintService service, int hashTables, int hashKeys, IWorkUnit unitOfWork, IWorkUnit sameUnitOfWork, DumpResults results) { double sum = 0; int hashesCount = 0; int startindex = 0; List<bool[]> listDb = unitOfWork.GetFingerprintsUsingService(service).Result; List<bool[]> listQuery = sameUnitOfWork.GetFingerprintsUsingService(service).Result; IPermutations perms = new DbPermutations(ConfigurationManager.ConnectionStrings["FingerprintConnectionString"].ConnectionString); MinHash minHash = new MinHash(perms); List<int[]> minHashDb = listDb.Select(minHash.ComputeMinHashSignature).ToList(); List<int[]> minHashQuery = listQuery.Select(minHash.ComputeMinHashSignature).ToList(); /*Calculate Min Hash signature similarity by comparing 2 consecutive signatures*/ int countDb = minHashDb.Count; int countQuery = minHashQuery.Count; int minHashSignatureLen = minHashDb[0].Length; int similarMinHashValues = 0; for (int i = 0; i < countDb; i++) { for (int j = 0; j < countQuery; j++) { for (int k = 0; k < minHashSignatureLen; k++) if (minHashDb[i][k] == minHashQuery[j][k]) similarMinHashValues++; } } results.Results.SumIdenticalMinHash = similarMinHashValues; results.Results.AverageIdenticalMinHash = (double) similarMinHashValues/(countDb*countQuery*minHashSignatureLen); /*Group min hash signatures into LSH Buckets*/ List<Dictionary<int, long>> lshBucketsDb = minHashDb.Select(item => minHash.GroupMinHashToLSHBuckets(item, hashTables, hashKeys)).ToList(); List<Dictionary<int, long>> lshBucketsQuery = minHashQuery.Select(item => minHash.GroupMinHashToLSHBuckets(item, hashTables, hashKeys)).ToList(); int countSignatures = lshBucketsDb.Count; sum = 0; foreach (Dictionary<int, long> a in lshBucketsDb) { Dictionary<int, long>.ValueCollection aValues = a.Values; foreach (Dictionary<int, long> b in lshBucketsQuery) { Dictionary<int, long>.ValueCollection bValues = b.Values; hashesCount += aValues.Intersect(bValues).Count(); } } results.Results.SumJaqLSHBucketSimilarity = -1; results.Results.AverageJaqLSHBucketSimilarity = -1; results.Results.TotalIdenticalLSHBuckets = hashesCount; }
/// <summary> /// Get signature similarity between 2 different songs. /// </summary> /// <param name="service"> /// The service. /// </param> /// <param name="unitOfWork"> /// The unit Of Work. /// </param> /// <param name="unitOfWorkToCompareWith"> /// The unit Of Work To Compare With. /// </param> /// <param name="results"> /// The results. /// </param> private void GetFingerprintSimilarity(IFingerprintService service, IWorkUnit unitOfWork, IWorkUnit unitOfWorkToCompareWith, DumpResults results) { double sum = 0; List<bool[]> imglista = unitOfWork.GetFingerprintsUsingService(service).Result; List<bool[]> imglistb = unitOfWorkToCompareWith.GetFingerprintsUsingService(service).Result; int count = imglista.Count > imglistb.Count ? imglistb.Count : imglista.Count; double max = double.MinValue; for (int i = 0; i < count; i++) { int j = i; double value = MinHash.CalculateSimilarity(imglista[i], imglistb[j]); if (value > max) { max = value; } sum += value; } results.SumJaqFingerprintSimilarityBetweenDiffertSongs = sum; results.AverageJaqFingerprintsSimilarityBetweenDifferentSongs = sum / count; results.MaxJaqFingerprintsSimilarityBetweenDifferentSongs = max; }