示例#1
0
        /// <summary>
        /// sort point @A 's all neighbor index by their distance to @A
        /// </summary>
        /// <param name="A"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private static List <DPoint> sortIndexOfNborByDist(DStatusPacket A, int index)
        {
            List <DPoint> distList = new List <DPoint>(LENGTH - 1);
            DPoint        tmp;
            double        AB; // dist(A, B)

            for (int i = 0; i < LENGTH; i++)
            {
                if (i == index)
                {
                    continue;
                }
                else if (i < index)
                {
                    AB = distTable[i, index];
                }
                else
                {
                    AB = distTable[index, i];
                }

                tmp = new DPoint(i, AB);  // i: the index of B in the database
                distList.Add(tmp);
            }
            distList.Sort();    // sort by tmp.Value (distance) ascending
            return(distList);
        }
示例#2
0
        /// <summary>
        /// drop index form packet (convert DStatus to DStatusPacket)
        /// </summary>
        /// <param name="src"></param>
        /// <returns></returns>
        private static DStatusPacket dropIndexFromPacket(DStatus src)
        {
            DStatusPacket dst = new DStatusPacket();

            dst.ID         = src.ID;
            dst.Attributes = src.Attributes;
            return(dst);
        }
示例#3
0
        /// <summary>
        /// add index of database to DStatusPacket @src
        /// </summary>
        /// <param name="index"></param>
        /// <param name="src"></param>
        /// <returns></returns>
        private static DStatus addIndexToPacket(int index, DStatusPacket src)
        {
            DStatus dst = new DStatus();

            dst.Index      = index;
            dst.ID         = src.ID;
            dst.Attributes = src.Attributes;
            return(dst);
        }
示例#4
0
        /// <summary>
        /// Parse statusData table
        /// </summary>
        /// <param name="p_Ds">Dataset</param>
        /// <returns>Parsing results</returns>
        public static List <DStatusPacket> RawDataToDStatusPacket(DataSet p_Ds)
        {
            // Resulting list
            List <DStatusPacket> packets = new List <DStatusPacket>();

            // Check if table exists or if table is empty
            if (p_Ds.Tables.Contains(tableName) == false || p_Ds.Tables[tableName].Rows.Count < 1)
            {
                return(packets);
            }

            int Dimension = p_Ds.Tables[tableName].Columns.Count;

            // Convert each row in table "Neighbor" to a "DNeighborPacket" structure
            foreach (DataRow row in p_Ds.Tables[tableName].Rows)
            {
                try
                {
                    // Create a new DStatusPacket
                    DStatusPacket status_packet = new DStatusPacket();

                    // get the value of ID
                    int p_ID = int.Parse(row["ID"].ToString());
                    // add to the object attributes
                    status_packet.ID = p_ID;

                    // Convert every elements in the attributes
                    for (int i = 1; i < Dimension; i++)
                    {
                        int p_Ai;

                        // get the value of each element of attributes
                        if (DBNull.Value.Equals(row[i]))
                        {
                            p_Ai = ErrorReadingInt;
                        }
                        else
                        {
                            p_Ai = int.Parse(row[i].ToString());
                        }
                        // add to the structure
                        status_packet.Attributes.Add(p_Ai);
                    }

                    // Add it to results
                    packets.Add(status_packet);
                }
                catch (Exception e)
                {
                    //TODO
                    //SystemLog.Log("SQLServerDBConvert", "RawDataToDStatusPacket", e.Message, null);
                }
            }

            return(packets);
        }
示例#5
0
        /// <summary>
        /// calculate dot product of vector @A and @B
        /// </summary>
        /// <param name="A"></param>
        /// <param name="B"></param>
        /// <returns>A * B</returns>
        private static double calcDotProduct(DStatusPacket vectorAB, DStatusPacket vectorAC)
        {
            double result = 0.0;

            for (int i = 0; i < vectorAB.Attributes.Count(); i++)
            {
                result += vectorAB.Attributes[i] * vectorAC.Attributes[i];
            }
            return(result);
        }
        /// <summary>
        /// Parse statusData table
        /// </summary>
        /// <param name="p_Ds">Dataset</param>
        /// <returns>Parsing results</returns>
        public static List<DStatusPacket> RawDataToDStatusPacket(DataSet p_Ds)
        {
            // Resulting list
            List<DStatusPacket> packets = new List<DStatusPacket>();
            // Check if table exists or if table is empty
            if (p_Ds.Tables.Contains(tableName) == false || p_Ds.Tables[tableName].Rows.Count < 1)
            {
                return packets;
            }

            int Dimension = p_Ds.Tables[tableName].Columns.Count;

            // Convert each row in table "Neighbor" to a "DNeighborPacket" structure
            foreach (DataRow row in p_Ds.Tables[tableName].Rows)
            {
                try
                {
                    // Create a new DStatusPacket
                    DStatusPacket status_packet = new DStatusPacket();

                    // get the value of ID
                    int p_ID = int.Parse(row["ID"].ToString());
                    // add to the object attributes
                    status_packet.ID = p_ID;

                    // Convert every elements in the attributes
                    for(int i = 1; i < Dimension; i++)
                    {
                        int p_Ai;

                        // get the value of each element of attributes
                        if (DBNull.Value.Equals(row[i]))
                        {
                            p_Ai = ErrorReadingInt;
                        }
                        else
                        {
                            p_Ai = int.Parse(row[i].ToString());
                        }
                        // add to the structure
                        status_packet.Attributes.Add(p_Ai);
                    }

                    // Add it to results
                    packets.Add(status_packet);
                }
                catch (Exception e)
                {
                    //TODO
                    //SystemLog.Log("SQLServerDBConvert", "RawDataToDStatusPacket", e.Message, null);
                }
            }

            return packets;
        }
示例#7
0
        /// <summary>
        /// get index of @kNN points of point @A in the database
        /// </summary>
        /// <param name="index"></param>
        /// <param name="kNN"></param>
        /// <returns>kNN Index</returns>
        private static int[] getkNNIndexOfA(DStatusPacket A, int index, int kNN)
        {
            int[] kNNIndex = new int[kNN];        // index of database, not ID

            List <DPoint> distList = sortIndexOfNborByDist(A, index);

            for (int i = 0; i < kNN; i++)
            {
                kNNIndex[i] = (int)distList[i].ID;
            }
            return(kNNIndex);
        }
示例#8
0
        /// <summary>
        /// calculate euclidean distTableance of point @A and @B
        /// </summary>
        /// <param name="A"></param>
        /// <param name="B"></param>
        /// <returns>|AB|</returns>
        private static double euclDistance(DStatusPacket A, DStatusPacket B)
        {
            DStatusPacket tmp = new DStatusPacket();

            tmp = A - B;        // vector BA = A - B, we have reloaded the operator - in class DStatusPacket
            double result = 0.0;

            for (int i = 0; i < A.Attributes.Count(); i++)
            {
                result += Math.Pow(tmp.Attributes[i], 2);
            }
            return(Math.Sqrt(result));
        }
示例#9
0
        /// <summary>
        /// calculate the approximate ABOF of point @A
        /// </summary>
        /// <param name="A"></param>
        /// <param name="index"></param>
        /// <param name="kNN"></param>
        /// <returns>ApproxABOF(A)</returns>
        private static double ApproxABOF(DStatusPacket A, int index, int kNN)
        {
            int[]          kNNIndex = getkNNIndexOfA(A, index, kNN);
            List <DStatus> Nk       = new List <DStatus>();
            DStatusPacket  B;
            double         variance;

            for (int i = 0; i < kNNIndex.Length; i++)
            {
                B = data.getDataByID(kNNIndex[i]);
                Nk.Add(addIndexToPacket(kNNIndex[i], B));
            }

            variance = ABOF(Nk, A, index);
            return(variance);
        }
示例#10
0
        /// <summary>
        /// calculate angle BAC(<AB, AC>)
        /// </summary>
        /// <param name="A"></param>
        /// <param name="B"></param>
        /// <param name="C"></param>
        /// <returns><AB, AC></returns>
        private static double calcAngleBAC(DStatusPacket A, DStatusPacket B, DStatusPacket C, double AB, double AC)
        {
            DStatusPacket vector_AB = B - A;
            DStatusPacket vector_AC = C - A;
            double        dotProduct, cos_BAC = 0.0, angle;

            dotProduct = calcDotProduct(vector_AB, vector_AC);
            try
            {
                cos_BAC = dotProduct / (AB * AC);
            }
            catch (DivideByZeroException e)
            {
                Console.WriteLine("Overflow Exception:" + e.Message);
            }
            if (Math.Abs(cos_BAC) > 1)
            {
                Console.WriteLine("DotProduct: " + dotProduct + "\tAB: " + AB + "\tAC: " + AC);
                Console.WriteLine("Math Domain Error: |cos<AB, AC>| <= 1");
            }
            angle = Math.Acos(cos_BAC);
            return(angle);
        }
示例#11
0
 /// <summary>
 /// add index of database to DStatusPacket @src
 /// </summary>
 /// <param name="index"></param>
 /// <param name="src"></param>
 /// <returns></returns>
 private static DStatus addIndexToPacket(int index, DStatusPacket src)
 {
     DStatus dst = new DStatus();
     dst.Index = index;
     dst.ID = src.ID;
     dst.Attributes = src.Attributes;
     return dst;
 }
示例#12
0
        /// <summary>
        /// calculate ABOF of point @A
        /// </summary>
        /// <param name="D">neighbour of point A</param>
        /// <param name="A"></param>
        /// <param name="index"></param>
        /// <returns>ABOF(A)</returns>
        private static double ABOF(List <DStatus> D, DStatusPacket A, int index)
        {
            DStatusPacket B, C;
            int           indexB, indexC;
            double        AB, AC;              // AB = |AB|, AC = |AC|
            double        angle_BAC, tmp = 0.0, variance;
            double        dotProductOfABandAC; // AB * AC

            /*
             * For ABOD, D include all the points, except for the point @A, the size
             * of @tmpList is (D.Count() - 1) * (D.Count() - 2) / 2 ;
             * However, for Fast ABOD, @D is the k nearest neighbor of point @A, when
             * index >= Nk.Count(), there's no need to except @A, therefore, the size
             * of @tmpList is D.Count * (D.Count - 1) / 2.
             */
            double[] tmpList = new double[D.Count() * (D.Count() - 1) / 2];
            int      k       = 0;

            for (int i = 0; i < D.Count(); i++)
            {
                indexB = D[i].Index;
                if (indexB == index)
                {
                    continue;
                }
                B = dropIndexFromPacket(D[i]);
                if (indexB < index)
                {
                    AB = distTable[indexB, index];
                }
                else
                {
                    AB = distTable[index, indexB];
                }

                for (int j = i + 1; j < D.Count(); j++)
                {
                    indexC = D[j].Index;
                    if (indexC == index || indexC == indexB)
                    {
                        continue;
                    }
                    C = dropIndexFromPacket(D[j]);
                    if (indexC < index)
                    {
                        AC = distTable[indexC, index];
                    }
                    else
                    {
                        AC = distTable[index, indexC];
                    }

                    dotProductOfABandAC = calcDotProduct(B - A, C - A);

                    /* //debug
                     * angle_BAC = calcAngleBAC(A, B, C, AB, AC);
                     * if (AB == 0 || AC == 0 || angle_BAC == 0)
                     *  Console.WriteLine("indexA: {0}\tindexB: {1}\tindexC: {2}\tAB: {3}\tAC: {4}\tangle_BAC = {5}", index, indexB, indexC, AB, AC, angle_BAC);
                     */

                    try
                    {
                        tmp = dotProductOfABandAC / Math.Pow(AB * AC, 2);
                    }
                    catch (DivideByZeroException e)
                    {
                        Console.WriteLine("Overflow Exception:" + e.Message);
                    }
                    tmpList[k++] = tmp;
                }
            }
            variance = calcVariance(tmpList);
            return(variance);
        }
示例#13
0
        /// <summary>
        /// calculate the approximate ABOF of point @A
        /// </summary>
        /// <param name="A"></param>
        /// <param name="index"></param>
        /// <param name="kNN"></param>
        /// <returns>ApproxABOF(A)</returns>
        private static double ApproxABOF(DStatusPacket A, int index, int kNN)
        {
            int[] kNNIndex = getkNNIndexOfA(A, index, kNN);
            List<DStatus> Nk = new List<DStatus>();
            DStatusPacket B;
            double variance;

            for (int i = 0; i < kNNIndex.Length; i++)
            {
                B = data.getDataByID(kNNIndex[i]);
                Nk.Add(addIndexToPacket(kNNIndex[i], B));
            }

            variance = ABOF(Nk, A, index);
            return variance;
        }
示例#14
0
 /// <summary>
 /// calculate dot product of vector @A and @B
 /// </summary>
 /// <param name="A"></param>
 /// <param name="B"></param>
 /// <returns>A * B</returns>
 private static double calcDotProduct(DStatusPacket vectorAB, DStatusPacket vectorAC)
 {
     double result = 0.0;
     for (int i = 0; i < vectorAB.Attributes.Count(); i++)
     {
         result += vectorAB.Attributes[i] * vectorAC.Attributes[i];
     }
     return result;
 }
示例#15
0
        /// <summary>
        /// calculate angle BAC(<AB, AC>)
        /// </summary>
        /// <param name="A"></param>
        /// <param name="B"></param>
        /// <param name="C"></param>
        /// <returns><AB, AC></returns>
        private static double calcAngleBAC(DStatusPacket A, DStatusPacket B, DStatusPacket C, double AB, double AC)
        {
            DStatusPacket vector_AB = B - A;
            DStatusPacket vector_AC = C - A;
            double dotProduct, cos_BAC = 0.0, angle;

            dotProduct = calcDotProduct(vector_AB, vector_AC);
            try
            {
                cos_BAC = dotProduct / (AB * AC);
            }
            catch (DivideByZeroException e)
            {
                Console.WriteLine("Overflow Exception:" + e.Message);
            }
            if (Math.Abs(cos_BAC) > 1)
            {
                Console.WriteLine("DotProduct: " + dotProduct + "\tAB: " + AB + "\tAC: " + AC);
                Console.WriteLine("Math Domain Error: |cos<AB, AC>| <= 1");
            }
            angle = Math.Acos(cos_BAC);
            return angle;
        }
示例#16
0
        /// <summary>
        /// calculate LB-ABOF of point @A
        /// </summary>
        /// <param name="A"></param>
        /// <param name="index"></param>
        /// <param name="kNN"></param>
        /// <returns>LB-ABOF(A)</returns>
        private static double LB_ABOF(List <DStatus> D, DStatusPacket A, int index, int kNN)
        {
            int[]          kNNIndex = getkNNIndexOfA(A, index, kNN);
            List <DStatus> Nk       = new List <DStatus>(kNNIndex.Length);

            int           indexB, indexC;
            DStatusPacket B, C;
            double        AB, AC, dotProductOfABandAC, angle_BAC, R1 = 0.0, R2, tmp = 0.0;
            double        Minuend_Numerator = 0.0, Subtrahend_Numerator = 0.0, Denominator;
            double        Minuend = 0.0, Subtrahend = 0.0;

            for (int i = 0; i < kNNIndex.Length; i++)           // Nk
            {
                indexB = kNNIndex[i];
                if (indexB == index)
                {
                    continue;
                }
                B = data.getDataByID(indexB);
                Nk.Add(addIndexToPacket(indexB, B));          // k nearest neighbor of point A

                if (indexB < index)
                {
                    AB = distTable[indexB, index];
                }
                else
                {
                    AB = distTable[index, indexB];
                }
                for (int j = i + 1; j < kNNIndex.Length; j++)
                {
                    indexC = kNNIndex[j];
                    if (indexC == index || indexC == indexB)
                    {
                        continue;
                    }
                    C = data.getDataByID(indexC);
                    if (indexC < index)
                    {
                        AC = distTable[indexC, index];
                    }
                    else
                    {
                        AC = distTable[index, indexC];
                    }

                    //angle_BAC = calcAngleBAC(A, B, C, AB, AC);
                    dotProductOfABandAC = calcDotProduct(B - A, C - A);
                    try
                    {
                        tmp = dotProductOfABandAC / Math.Pow(AB * AC, 3);     // <AB, AC> / (|AB| * |AC|) ^ 3
                    }
                    catch (DivideByZeroException e)
                    {
                        Console.WriteLine("Overflow Exception:" + e.Message);
                    }
                    Minuend_Numerator    += Math.Pow(tmp, 2) * AB * AC;
                    Subtrahend_Numerator += tmp;
                }
            }
            R2 = calcR2(D, Nk, index);
            //R1 = R2;

            Denominator = rcpcOfModePlot_Linear(D, index, 1);          // D
            try
            {
                Minuend    = 2.0 * (Minuend_Numerator + R1) / Denominator;
                Subtrahend = Math.Pow(((2.0 * Subtrahend_Numerator + R2) / Denominator), 2);
            }
            catch (DivideByZeroException e)
            {
                Console.WriteLine("Deominator != 0" + e.Message);
            }
            return(Minuend - Subtrahend);       // return LB-ABOF(A)
        }
示例#17
0
        /// <summary>
        /// calculate ABOF of point @A
        /// </summary>
        /// <param name="D">neighbour of point A</param>
        /// <param name="A"></param>
        /// <param name="index"></param>
        /// <returns>ABOF(A)</returns>
        private static double ABOF(List<DStatus> D, DStatusPacket A, int index)
        {
            DStatusPacket B, C;
            int indexB, indexC;
            double AB, AC;      // AB = |AB|, AC = |AC|
            double angle_BAC, tmp = 0.0, variance;
            double dotProductOfABandAC;     // AB * AC
            /*
             * For ABOD, D include all the points, except for the point @A, the size
             * of @tmpList is (D.Count() - 1) * (D.Count() - 2) / 2 ;
             * However, for Fast ABOD, @D is the k nearest neighbor of point @A, when
             * index >= Nk.Count(), there's no need to except @A, therefore, the size
             * of @tmpList is D.Count * (D.Count - 1) / 2.
             */
            double[] tmpList = new double[D.Count() * (D.Count() - 1) / 2];
            int k = 0;

            for (int i = 0; i < D.Count(); i++)
            {
                indexB = D[i].Index;
                if (indexB == index)
                    continue;
                B = dropIndexFromPacket(D[i]);
                if (indexB < index)
                    AB = distTable[indexB, index];
                else
                    AB = distTable[index, indexB];

                for (int j = i + 1; j < D.Count(); j++)
                {
                    indexC = D[j].Index;
                    if (indexC == index || indexC == indexB)
                        continue;
                    C = dropIndexFromPacket(D[j]);
                    if (indexC < index)
                        AC = distTable[indexC, index];
                    else
                        AC = distTable[index, indexC];

                    dotProductOfABandAC = calcDotProduct(B - A, C - A);

                    /* //debug
                    angle_BAC = calcAngleBAC(A, B, C, AB, AC);
                    if (AB == 0 || AC == 0 || angle_BAC == 0)
                        Console.WriteLine("indexA: {0}\tindexB: {1}\tindexC: {2}\tAB: {3}\tAC: {4}\tangle_BAC = {5}", index, indexB, indexC, AB, AC, angle_BAC);
                    */

                    try
                    {
                        tmp = dotProductOfABandAC / Math.Pow(AB * AC, 2);
                    }
                    catch (DivideByZeroException e)
                    {
                        Console.WriteLine("Overflow Exception:" + e.Message);
                    }
                    tmpList[k++] = tmp;
                }
            }
            variance = calcVariance(tmpList);
            return variance;
        }
示例#18
0
        /// <summary>
        /// calculate LB-ABOF of point @A
        /// </summary>
        /// <param name="A"></param>
        /// <param name="index"></param>
        /// <param name="kNN"></param>
        /// <returns>LB-ABOF(A)</returns>
        private static double LB_ABOF(List<DStatus> D, DStatusPacket A, int index, int kNN)
        {
            int[] kNNIndex = getkNNIndexOfA(A, index, kNN);
            List<DStatus> Nk = new List<DStatus>(kNNIndex.Length);

            int indexB, indexC;
            DStatusPacket B, C;
            double AB, AC, dotProductOfABandAC, angle_BAC, R1 = 0.0, R2, tmp = 0.0;
            double Minuend_Numerator = 0.0, Subtrahend_Numerator = 0.0, Denominator;
            double Minuend = 0.0, Subtrahend = 0.0;

            for (int i = 0; i < kNNIndex.Length; i++)           // Nk
            {
                indexB = kNNIndex[i];
                if (indexB == index)
                    continue;
                B = data.getDataByID(indexB);
                Nk.Add(addIndexToPacket(indexB, B));          // k nearest neighbor of point A

                if (indexB < index)
                    AB = distTable[indexB, index];
                else
                    AB = distTable[index, indexB];
                for (int j = i + 1; j < kNNIndex.Length; j++)
                {
                    indexC = kNNIndex[j];
                    if (indexC == index || indexC == indexB)
                        continue;
                    C = data.getDataByID(indexC);
                    if (indexC < index)
                        AC = distTable[indexC, index];
                    else
                        AC = distTable[index, indexC];

                    //angle_BAC = calcAngleBAC(A, B, C, AB, AC);
                    dotProductOfABandAC = calcDotProduct(B - A, C - A);
                    try
                    {
                        tmp = dotProductOfABandAC / Math.Pow(AB * AC, 3);     // <AB, AC> / (|AB| * |AC|) ^ 3
                    }
                    catch (DivideByZeroException e)
                    {
                        Console.WriteLine("Overflow Exception:" + e.Message);
                    }
                    Minuend_Numerator += Math.Pow(tmp, 2) * AB * AC;
                    Subtrahend_Numerator += tmp;
                }
            }
            R2 = calcR2(D, Nk, index);
            //R1 = R2;

            Denominator = rcpcOfModePlot_Linear(D, index, 1);          // D
            try
            {
                Minuend = 2.0 * (Minuend_Numerator + R1) / Denominator;
                Subtrahend = Math.Pow(((2.0 * Subtrahend_Numerator + R2) / Denominator), 2);
            }
            catch (DivideByZeroException e)
            {
                Console.WriteLine("Deominator != 0" + e.Message);
            }
            return (Minuend - Subtrahend);      // return LB-ABOF(A)
        }
示例#19
0
        /// <summary>
        /// get index of @kNN points of point @A in the database
        /// </summary>
        /// <param name="index"></param>
        /// <param name="kNN"></param>
        /// <returns>kNN Index</returns>
        private static int[] getkNNIndexOfA(DStatusPacket A, int index, int kNN)
        {
            int[] kNNIndex = new int[kNN];        // index of database, not ID

            List<DPoint> distList = sortIndexOfNborByDist(A, index);

            for (int i = 0; i < kNN; i++)
            {
                kNNIndex[i] = (int)distList[i].ID;
            }
            return kNNIndex;
        }
示例#20
0
 /// <summary>
 /// calculate euclidean distTableance of point @A and @B
 /// </summary>
 /// <param name="A"></param>
 /// <param name="B"></param>
 /// <returns>|AB|</returns>
 private static double euclDistance(DStatusPacket A, DStatusPacket B)
 {
     DStatusPacket tmp = new DStatusPacket();
     tmp = A - B;        // vector BA = A - B, we have reloaded the operator - in class DStatusPacket
     double result = 0.0;
     for (int i = 0; i < A.Attributes.Count(); i++)
     {
         result += Math.Pow(tmp.Attributes[i], 2);
     }
     return Math.Sqrt(result);
 }
示例#21
0
 /// <summary>
 /// drop index form packet (convert DStatus to DStatusPacket)
 /// </summary>
 /// <param name="src"></param>
 /// <returns></returns>
 private static DStatusPacket dropIndexFromPacket(DStatus src)
 {
     DStatusPacket dst = new DStatusPacket();
     dst.ID = src.ID;
     dst.Attributes = src.Attributes;
     return dst;
 }
示例#22
0
        /// <summary>
        /// code by H-P. Kerigel
        /// </summary>
        /// <param name="D"></param>
        /// <param name="A"></param>
        /// <param name="index"></param>
        /// <param name="kNN"></param>
        /// <returns></returns>
        private static double calcLBABOF(DStatusPacket A, int index, int kNN)
        {
            List<DPoint> NkIndex = new List<DPoint>();
            // Compute nearest neighbors and distances.

            double simAA = calcDotProduct(A, A);
            // Sum of 1./(|AB|) and 1./(|AB|^2); for computing R2.
            double sumid = 0, sumisqd = 0;
            for (int j = 0; j < LENGTH; j++)
            {
                if (index == j)
                {
                    continue;
                }
                DStatusPacket nB = data.getDataByID(j);
                double simBB = calcDotProduct(nB, nB);
                double simAB = calcDotProduct(A, nB);
                double sqdAB = simAA + simBB - simAB - simAB;

                if (!(sqdAB > 0))
                {
                    continue;
                }
                sumid += 1 / Math.Sqrt(sqdAB);
                sumisqd += 1 / sqdAB;
                // Update heap
                DPoint temp = new DPoint(j, sqdAB);
                if (NkIndex.Count < kNN)
                {
                    NkIndex.Add(temp);
                }
                else if (sqdAB < NkIndex.Max().Value)
                {
                    //移出最大的
                    NkIndex.Remove(NkIndex.Max());
                    NkIndex.Add(temp);
                }
            }

            // Compute FastABOD approximation, adjust for lower bound.
            // LB-ABOF is defined via a numerically unstable formula.
            // Variance as E(X^2)-E(X)^2 suffers from catastrophic cancellation!
            // TODO: ensure numerical precision!
            double nnsum = 0, nnsumsq = 0, nnsumisqd = 0;
            for (int k = 0; k < NkIndex.Count; k++)
            {
                DPoint iB = NkIndex[k];
                DStatusPacket nB = data.getDataByID(iB.ID);
                double sqdAB = iB.Value;
                double simAB = calcDotProduct(A, nB);
                if (!(sqdAB > 0))
                {
                    continue;
                }
                for (int l = 0; l < NkIndex.Count; l++)
                {
                    if (k == l)
                    {
                        continue;
                    }
                    DPoint iC = NkIndex[l];
                    DStatusPacket nC = data.getDataByID(iC.ID);
                    double sqdAC = iC.Value;
                    double simAC = calcDotProduct(A, nC);
                    if (!(sqdAC > 0))
                    {
                        continue;
                    }
                    // Exploit bilinearity of scalar product:
                    // <B-A, C-A> = <B, C-A> - <A,C-A>
                    // = <B,C> - <B,A> - <A,C> + <A,A>
                    double simBC = calcDotProduct(nB, nC);
                    double numerator = simBC - simAB - simAC + simAA;
                    double sqweight = 1 / (sqdAB * sqdAC);
                    double weight = Math.Sqrt(sqweight);
                    double val = numerator * sqweight;
                    nnsum += val * weight;
                    nnsumsq += val * val * weight;
                    nnsumisqd += sqweight;
                }
            }
            // Remaining weight, term R2:
            double r2 = sumisqd * sumisqd - 2 * nnsumisqd;
            double tmp = (2 * nnsum + r2) / (sumid * sumid);
            double lbabof = 2 * nnsumsq / (sumid * sumid) - tmp * tmp;

            return lbabof;
        }
示例#23
0
        /// <summary>
        /// code by H-P. Kerigel
        /// </summary>
        /// <param name="D"></param>
        /// <param name="A"></param>
        /// <param name="index"></param>
        /// <param name="kNN"></param>
        /// <returns></returns>
        private static double calcLBABOF(DStatusPacket A, int index, int kNN)
        {
            List <DPoint> NkIndex = new List <DPoint>();
            // Compute nearest neighbors and distances.

            double simAA = calcDotProduct(A, A);
            // Sum of 1./(|AB|) and 1./(|AB|^2); for computing R2.
            double sumid = 0, sumisqd = 0;

            for (int j = 0; j < LENGTH; j++)
            {
                if (index == j)
                {
                    continue;
                }
                DStatusPacket nB    = data.getDataByID(j);
                double        simBB = calcDotProduct(nB, nB);
                double        simAB = calcDotProduct(A, nB);
                double        sqdAB = simAA + simBB - simAB - simAB;

                if (!(sqdAB > 0))
                {
                    continue;
                }
                sumid   += 1 / Math.Sqrt(sqdAB);
                sumisqd += 1 / sqdAB;
                // Update heap
                DPoint temp = new DPoint(j, sqdAB);
                if (NkIndex.Count < kNN)
                {
                    NkIndex.Add(temp);
                }
                else if (sqdAB < NkIndex.Max().Value)
                {
                    //移出最大的
                    NkIndex.Remove(NkIndex.Max());
                    NkIndex.Add(temp);
                }
            }

            // Compute FastABOD approximation, adjust for lower bound.
            // LB-ABOF is defined via a numerically unstable formula.
            // Variance as E(X^2)-E(X)^2 suffers from catastrophic cancellation!
            // TODO: ensure numerical precision!
            double nnsum = 0, nnsumsq = 0, nnsumisqd = 0;

            for (int k = 0; k < NkIndex.Count; k++)
            {
                DPoint        iB    = NkIndex[k];
                DStatusPacket nB    = data.getDataByID(iB.ID);
                double        sqdAB = iB.Value;
                double        simAB = calcDotProduct(A, nB);
                if (!(sqdAB > 0))
                {
                    continue;
                }
                for (int l = 0; l < NkIndex.Count; l++)
                {
                    if (k == l)
                    {
                        continue;
                    }
                    DPoint        iC    = NkIndex[l];
                    DStatusPacket nC    = data.getDataByID(iC.ID);
                    double        sqdAC = iC.Value;
                    double        simAC = calcDotProduct(A, nC);
                    if (!(sqdAC > 0))
                    {
                        continue;
                    }
                    // Exploit bilinearity of scalar product:
                    // <B-A, C-A> = <B, C-A> - <A,C-A>
                    // = <B,C> - <B,A> - <A,C> + <A,A>
                    double simBC     = calcDotProduct(nB, nC);
                    double numerator = simBC - simAB - simAC + simAA;
                    double sqweight  = 1 / (sqdAB * sqdAC);
                    double weight    = Math.Sqrt(sqweight);
                    double val       = numerator * sqweight;
                    nnsum     += val * weight;
                    nnsumsq   += val * val * weight;
                    nnsumisqd += sqweight;
                }
            }
            // Remaining weight, term R2:
            double r2     = sumisqd * sumisqd - 2 * nnsumisqd;
            double tmp    = (2 * nnsum + r2) / (sumid * sumid);
            double lbabof = 2 * nnsumsq / (sumid * sumid) - tmp * tmp;

            return(lbabof);
        }
示例#24
0
        /// <summary>
        /// sort point @A 's all neighbor index by their distance to @A
        /// </summary>
        /// <param name="A"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private static List<DPoint> sortIndexOfNborByDist(DStatusPacket A, int index)
        {
            List<DPoint> distList = new List<DPoint>(LENGTH - 1);
            DPoint tmp;
            double AB;  // dist(A, B)

            for (int i = 0; i < LENGTH; i++)
            {
                if (i == index)
                    continue;
                else if (i < index)
                    AB = distTable[i, index];
                else
                    AB = distTable[index, i];

                tmp = new DPoint(i, AB);  // i: the index of B in the database
                distList.Add(tmp);
            }
            distList.Sort();    // sort by tmp.Value (distance) ascending
            return distList;
        }