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;
        }
Ejemplo n.º 3
0
        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);
        }