public void TestBinTemplateCorrelationMassive() { string homeFolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); BinTemplateSimilarityTests.ParseDb(homeFolder + "\\mcc_cs_db.txt"); BinTemplateSimilarityTests.ParseQuery(homeFolder + "\\mcc_cs_query.txt"); CylinderDatabase cylinderDb = new CylinderDatabase( BinTemplateSimilarityTests.contiguousCylinders, BinTemplateSimilarityTests.templateIndices); int cylinderSize = Marshal.SizeOf(typeof(CylinderC)); IntPtr db = Marshal.AllocHGlobal(BinTemplateSimilarityTests.contiguousCylinders.Length * cylinderSize); IntPtr curDbPtr = new IntPtr(db.ToInt32()); // No idea why not just " = db", copypasted from SO for (int i = 0; i < BinTemplateSimilarityTests.contiguousCylinders.Length; i++) { CylinderC curDbCylinder = new CylinderC(); curDbCylinder.values = Marshal.AllocHGlobal(cylindersPerTemplate * sizeof(int)); int[] curManagedValues = new int[cylindersPerTemplate]; for (int j = 0; j < cylindersPerTemplate; j++) { curManagedValues[j] = unchecked((int)BinTemplateSimilarityTests.contiguousCylinders[i].Values[j]); } Marshal.Copy(curManagedValues, 0, curDbCylinder.values, cylindersPerTemplate); curDbCylinder.angle = (float)BinTemplateSimilarityTests.contiguousCylinders[i].Angle; curDbCylinder.norm = (float)BinTemplateSimilarityTests.contiguousCylinders[i].Norm; curDbCylinder.valuesCount = (uint)BinTemplateSimilarityTests.contiguousCylinders[i].Values.Length; curDbCylinder.templateIndex = BinTemplateSimilarityTests.templateIndices[i]; Marshal.StructureToPtr(curDbCylinder, curDbPtr, false); curDbPtr = new IntPtr(curDbPtr.ToInt32() + Marshal.SizeOf(typeof(CylinderC))); } IntPtr query = Marshal.AllocHGlobal(BinTemplateSimilarityTests.query.Cylinders.Length * cylinderSize); IntPtr curQueryPtr = new IntPtr(query.ToInt32()); for (int i = 0; i < BinTemplateSimilarityTests.query.Cylinders.Length; i++) { CylinderC curQueryCylinder = new CylinderC(); curQueryCylinder.values = Marshal.AllocHGlobal(cylindersPerTemplate * sizeof(int)); int[] curManagedValues = new int[cylindersPerTemplate]; for (int j = 0; j < cylindersPerTemplate; j++) { curManagedValues[j] = unchecked((int)BinTemplateSimilarityTests.query.Cylinders[i].Values[j]); } Marshal.Copy(curManagedValues, 0, curQueryCylinder.values, cylindersPerTemplate); curQueryCylinder.angle = (float)BinTemplateSimilarityTests.query.Cylinders[i].Angle; curQueryCylinder.norm = (float)BinTemplateSimilarityTests.query.Cylinders[i].Norm; curQueryCylinder.valuesCount = (uint)BinTemplateSimilarityTests.query.Cylinders[i].Values.Length; curQueryCylinder.templateIndex = 0; // Always 0 for query, just for the sake of completeness, doesn't really matter Marshal.StructureToPtr(curQueryCylinder, curQueryPtr, false); curQueryPtr = new IntPtr(curQueryPtr.ToInt32() + Marshal.SizeOf(typeof(CylinderC))); } IntPtr templateDbLengths = Marshal.AllocHGlobal(BinTemplateSimilarityTests.templateDbLengths.Length * sizeof(int)); Marshal.Copy(BinTemplateSimilarityTests.templateDbLengths, 0, templateDbLengths, BinTemplateSimilarityTests.templateDbLengths.Length); initMCC( db, (uint)BinTemplateSimilarityTests.contiguousCylinders.Length, templateDbLengths, (uint)BinTemplateSimilarityTests.templateDbLengths.Length); IntPtr similaritiesPtr = processMCC( query, (uint)BinTemplateSimilarityTests.query.Cylinders.Length, (uint)BinTemplateSimilarityTests.contiguousCylinders.Length, (uint)BinTemplateSimilarityTests.templateDbLengths.Length); float[] similarities = new float[BinTemplateSimilarityTests.templateDbLengths.Length]; Marshal.Copy(similaritiesPtr, similarities, 0, similarities.Length); for (int i = 0; i < similarities.Length; i++) { Console.Write(similarities[i] + (i != similarities.Length - 1 ? ", " : "")); } Console.WriteLine(); }
public static double[] GetTemplateSimilarityOptimized(Template query, CylinderDatabase db, int[] dbTemplateLengths) { double[] similarityRates = new double[dbTemplateLengths.Length]; bucketMatrix = new uint[dbTemplateLengths.Length, bucketsCount]; for (int k = 0; k < db.Cylinders.Length; k++) { Cylinder cylinderDb = db.Cylinders[k]; foreach (Cylinder queryCylinder in query.Cylinders) { uint[] givenXOR = queryCylinder.Values.Zip(cylinderDb.Values, (first, second) => first ^ second).ToArray(); //for (int i = 0; i < givenXOR.Length; i++) //{ // Console.Write(givenXOR[i] + ", "); //} //Console.WriteLine(); uint oneBitsCount = CylinderHelper.GetOneBitsCount(givenXOR); //Console.Write(oneBitsCount + " "); double givenXORNorm = Math.Sqrt(oneBitsCount); // Bitwise version //double givenXORNorm = CalculateCylinderNorm(givenXOR); // Stupid version if (CylinderHelper.GetAngleDiff(queryCylinder.Angle, cylinderDb.Angle) < angleThreshold && queryCylinder.Norm + cylinderDb.Norm != 0) { uint bucketIndex = (uint)Math.Floor(givenXORNorm / (queryCylinder.Norm + cylinderDb.Norm) * bucketsCount); //if (bucketIndex >= 63) //{ // Console.Write("LOOOOL"); // Console.WriteLine(k); //} if (bucketIndex == bucketsCount) { bucketIndex--; } uint row = db.TemplateIndices[k]; bucketMatrix[row, bucketIndex]++; } } } //Console.WriteLine("END"); PrintMatrix(bucketMatrix); for (int k = 0; k < dbTemplateLengths.Length; k++) { int numPairs = ComputeNumPairs(dbTemplateLengths[k], query.Cylinders.Length); int sum = 0, t = numPairs, i = 0; while (i < bucketsCount && t > 0) { sum += (int)Math.Min(bucketMatrix[k, i], t) * i; t -= (int)Math.Min(bucketMatrix[k, i], t); i++; } sum += t * (int)bucketsCount; similarityRates[k] = 1 - (float)sum / (numPairs * bucketsCount); } return similarityRates; }
public static double[] GetTemplateSimilarityOptimized(Template query, CylinderDatabase db, int[] dbTemplateLengths) { double[] similarityRates = new double[dbTemplateLengths.Length]; bucketMatrix = new uint[dbTemplateLengths.Length, bucketsCount]; for (int k = 0; k < db.Cylinders.Length; k++) { Cylinder cylinderDb = db.Cylinders[k]; foreach (Cylinder queryCylinder in query.Cylinders) { uint[] givenXOR = queryCylinder.Values.Zip(cylinderDb.Values, (first, second) => first ^ second).ToArray(); //for (int i = 0; i < givenXOR.Length; i++) //{ // Console.Write(givenXOR[i] + ", "); //} //Console.WriteLine(); uint oneBitsCount = CylinderHelper.GetOneBitsCount(givenXOR); //Console.Write(oneBitsCount + " "); double givenXORNorm = Math.Sqrt(oneBitsCount); // Bitwise version //double givenXORNorm = CalculateCylinderNorm(givenXOR); // Stupid version if (CylinderHelper.GetAngleDiff(queryCylinder.Angle, cylinderDb.Angle) < angleThreshold && queryCylinder.Norm + cylinderDb.Norm != 0) { uint bucketIndex = (uint)Math.Floor(givenXORNorm / (queryCylinder.Norm + cylinderDb.Norm) * bucketsCount); //if (bucketIndex >= 63) //{ // Console.Write("LOOOOL"); // Console.WriteLine(k); //} if (bucketIndex == bucketsCount) { bucketIndex--; } uint row = db.TemplateIndices[k]; bucketMatrix[row, bucketIndex]++; } } } //Console.WriteLine("END"); PrintMatrix(bucketMatrix); for (int k = 0; k < dbTemplateLengths.Length; k++) { int numPairs = ComputeNumPairs(dbTemplateLengths[k], query.Cylinders.Length); int sum = 0, t = numPairs, i = 0; while (i < bucketsCount && t > 0) { sum += (int)Math.Min(bucketMatrix[k, i], t) * i; t -= (int)Math.Min(bucketMatrix[k, i], t); i++; } sum += t * (int)bucketsCount; similarityRates[k] = 1 - (float)sum / (numPairs * bucketsCount); } return(similarityRates); }