public void CanFindNearestForUniform()
        {
            const int d     = 10;
            const int n     = 100;
            const int tests = 100;

            var tester = new NearestNeighborSearchTester();

            var rnd = new Random();

            var pointsSet = tester.CreateRandomPointsSet_Uniform(d, n, rnd);

            var queryPoints = tester.CreateRandomQueryPoints_NotFarFromSet(tests, d, rnd, n, pointsSet);

            var brutes = queryPoints
                         .Select(query => tester.FindNearestBrute(query, pointsSet))
                         .ToArray();

            var searcher = new NearestNeighborSearch(pointsSet);

            var algos = queryPoints
                        .Select(query => searcher.Closest(query, 0.1))
                        .ToArray();

            for (var i = 0; i < queryPoints.Length; i++)
            {
                Assert.AreEqual(brutes[i], algos[i]);
            }
        }
        public static double[] PolyharmonicSplineInterpolation(double[] newCoordinateValues, double[,] coordinates, double[,] interpolantValues, int numberOfNN, int order)
        {
            double[] newInterpolantValues = new double[interpolantValues.GetLength(0)];
            double[,] coordinatesOfNNs = new double[coordinates.GetLength(0), numberOfNN];

            int[] indices = NearestNeighborSearch.KnnSearch(coordinates, newCoordinateValues, numberOfNN).Item1;
            for (int j = 0; j < numberOfNN; j++)
            {
                for (int i = 0; i < coordinates.GetLength(0); i++)
                {
                    coordinatesOfNNs[i, j] = coordinates[i, indices[j]];
                }
            }

            double[] l = new double[numberOfNN];
            double[,] L = new double[numberOfNN, numberOfNN];

            if (order % 2 == 0)
            {
                for (int i = 0; i < numberOfNN; i++)
                {
                    double[] iNearestNeighbor = Enumerable.Range(0, coordinatesOfNNs.GetLength(1)).Select(x => coordinatesOfNNs[i, x]).ToArray();
                    double   iDist            = GetDistance(newCoordinateValues, iNearestNeighbor);
                    l[i] = Math.Pow(iDist, (2 * order) - 1);
                    for (int j = 0; j < numberOfNN; j++)
                    {
                        double[] jNearestNeighbor = Enumerable.Range(0, coordinatesOfNNs.GetLength(1)).Select(x => coordinatesOfNNs[j, x]).ToArray();
                        double   ijDist           = GetDistance(iNearestNeighbor, jNearestNeighbor);
                        L[i, j] = Math.Pow(ijDist, (2 * order) - 1);
                    }
                }
            }
            else
            {
                for (int i = 0; i < numberOfNN; i++)
                {
                    double[] iNearestNeighbor = Enumerable.Range(0, coordinatesOfNNs.GetLength(1)).Select(x => coordinatesOfNNs[i, x]).ToArray();
                    double   iDist            = GetDistance(newCoordinateValues, iNearestNeighbor);
                    l[i] = Math.Pow(iDist, 2 * (order - 1)) * Math.Log(iDist);
                    for (int j = 0; j < numberOfNN; j++)
                    {
                        double[] jNearestNeighbor = Enumerable.Range(0, coordinatesOfNNs.GetLength(1)).Select(x => coordinatesOfNNs[j, x]).ToArray();
                        double   ijDist           = GetDistance(iNearestNeighbor, jNearestNeighbor);
                        L[i, j] = Math.Pow(iDist, 2 * (order - 1)) * Math.Log(iDist);
                    }
                }
            }

            Vector lVector   = Vector.CreateFromArray(l);
            Matrix matrixOfL = Matrix.CreateFromArray(L);
            Matrix invL      = matrixOfL.Invert();
            Matrix matrixOfCoordinatesOfNNs = Matrix.CreateFromArray(coordinatesOfNNs);
            Matrix A                    = invL.MultiplyRight(matrixOfCoordinatesOfNNs.Transpose());
            Matrix Atranspose           = A.Transpose();
            Vector newinterpolantValues = Atranspose.Multiply(lVector);

            return(newInterpolantValues);
        }
        public void SinglePoint_OutsideRadius()
        {
            //Given
            var tree = new NearestNeighborSearch();
            var p    = new Vector3(14, 2.3f, 1.9f);

            tree.AddPoint(p, 13);
            tree.Build();

            //When
            var result = tree.QueryNearest(Vector3.Zero, 1, 0.1f);

            //Then
            Assert.Null(result);
        }
        public void SinglePoint_ShouldBeFound()
        {
            //Given
            var tree = new NearestNeighborSearch();
            var p    = new Vector3(14, 2.3f, 1.9f);

            tree.AddPoint(p, 13);
            tree.Build();

            //When
            var result = tree.QueryNearest(Vector3.Zero, 1, float.MaxValue);

            //Then
            Assert.Single(result);
            Assert.Equal(13, result[0]);
        }
        public void TwoPoints_OnlyInRadiusShouldBeFound()
        {
            //Given
            var tree = new NearestNeighborSearch();
            var p    = new Vector3(14, 2.3f, 1.9f);
            var pfar = new Vector3(184, 2901, 231);

            tree.AddPoint(p, 13);
            tree.AddPoint(pfar, 1);
            tree.Build();

            //When
            var result = tree.QueryNearest(Vector3.Zero, 2, 20.0f);

            //Then
            Assert.Single(result);
            Assert.Equal(13, result[0]);
        }
        public void Clear_ShouldBeEmpty()
        {
            //Given
            var tree = new NearestNeighborSearch();
            var p    = new Vector3(14, 2.3f, 1.9f);
            var pfar = new Vector3(184, 2901, 231);

            tree.AddPoint(p, 13);
            tree.AddPoint(pfar, 1);
            tree.Build();

            //When
            tree.Clear();
            var result = tree.QueryNearest(Vector3.Zero, 2, float.MaxValue);

            //Then
            Assert.Null(result);
        }
        public void TwoPoints_BothShouldBeFound()
        {
            //Given
            var tree = new NearestNeighborSearch();
            var p    = new Vector3(14, 2.3f, 1.9f);
            var pfar = new Vector3(184, 2901, 231);

            tree.AddPoint(p, 13);
            tree.AddPoint(pfar, 1);
            tree.Build();

            //When
            var result = tree.QueryNearest(Vector3.Zero, 2, float.MaxValue);

            //Then
            Assert.Equal(2, result.Length);
            Assert.Equal(13, result[0]);
            Assert.Equal(1, result[1]);
        }
        public static double[] GaussianRBFInterpolation(double[] newCoordinateValues, double[,] coordinates, double[,] interpolantValues, int numberOfNN, double shapeParameter)
        {
            double[] newInterpolantValues = new double[interpolantValues.GetLength(0)];
            double[,] coordinatesOfNNs = new double[coordinates.GetLength(0), numberOfNN];

            int[] indices = NearestNeighborSearch.KnnSearch(coordinates, newCoordinateValues, numberOfNN).Item1;
            for (int j = 0; j < numberOfNN; j++)
            {
                for (int i = 0; i < coordinates.GetLength(0); i++)
                {
                    coordinatesOfNNs[i, j] = coordinates[i, indices[j]];
                }
            }

            double[] l = new double[numberOfNN];
            double[,] L = new double[numberOfNN, numberOfNN];

            for (int i = 0; i < numberOfNN; i++)
            {
                double[] iNearestNeighbor = Enumerable.Range(0, coordinatesOfNNs.GetLength(0)).Select(x => coordinatesOfNNs[x, i]).ToArray();
                double   iDist            = GetDistance(newCoordinateValues, iNearestNeighbor);
                l[i] = Math.Exp(-Math.Pow(iDist * shapeParameter, 2));
                for (int j = 0; j < numberOfNN; j++)
                {
                    double[] jNearestNeighbor = Enumerable.Range(0, coordinates.GetLength(1)).Select(x => coordinates[j, x]).ToArray();
                    double   ijDist           = GetDistance(iNearestNeighbor, jNearestNeighbor);
                    L[i, j] = Math.Exp(-Math.Pow(ijDist * shapeParameter, 2));
                }
            }

            Vector lVector   = Vector.CreateFromArray(l);
            Matrix matrixOfL = Matrix.CreateFromArray(L);
            Matrix invL      = matrixOfL.Invert();
            Matrix matrixOfCoordinatesOfNNs = Matrix.CreateFromArray(coordinatesOfNNs);
            Matrix A                    = invL.MultiplyRight(matrixOfCoordinatesOfNNs.Transpose());
            Matrix Atranspose           = A.Transpose();
            Vector newinterpolantValues = Atranspose.Multiply(lVector);

            return(newInterpolantValues);
        }
Example #9
0
        public void ProcessData()
        {
            int N = dataSet.GetLength(0);

            int[,] indices            = new int[N, numberOfKNN];
            double[,] sortedDistances = new double[N, numberOfKNN];
            for (var i = 0; i < N; i++)
            {
                double[] dataPoint  = Enumerable.Range(0, dataSet.GetLength(1)).Select(x => dataSet[i, x]).ToArray();
                int[]    ind        = NearestNeighborSearch.KnnSearch(dataSet, dataPoint, numberOfKNN).Item1;
                double[] sortedDist = NearestNeighborSearch.KnnSearch(dataSet, dataPoint, numberOfKNN).Item2;
                for (var j = 0; j < numberOfKNN; j++)
                {
                    indices[i, j]         = ind[j];
                    sortedDistances[i, j] = sortedDist[j];
                }
            }

            // build ad hoc bandwidth function by autotuning epsilon for each point
            double[] epss = new double[401];
            for (var i = 0; i < 401; i++)
            {
                epss[i] = Math.Pow(2, -30 + i * 0.1);               // Will store both distance and index in here
            }
            double[] rho0 = evaluateRho0(sortedDistances, NNofKDE);
            // pre-kernel used with ad hoc bandwidth only for estimating dimension and sampling density
            double[,] dt = evaluateDt(sortedDistances, rho0, indices, numberOfKNN);
            // tune epsilon on the pre-kernel
            double[] dpreGlobal = evaluateDpreGlobal(epss, dt, numberOfKNN, N);
            (double maxval, int maxind) = findMaxvalMaxind(dpreGlobal, epss);
            double dim = 2 * maxval;

            // use ad hoc bandwidth function, rho0, to estimate the density
            for (var i = 0; i < dt.GetLength(0); i++)
            {
                for (var j = 0; j < dt.GetLength(1); j++)
                {
                    dt[i, j] = Math.Exp(-dt[i, j] / (2 * epss[maxind])) / Math.Pow(2 * Math.PI * epss[maxind], (dim / 2));
                }
            }

            // the matrix created here might be large, must change it to sparse format
            double[,] reshapedDt  = reshapeDt(dt, indices, N, numberOfKNN);
            double[,] symmetricDt = new double[reshapedDt.GetLength(0), reshapedDt.GetLength(1)];
            for (var i = 0; i < reshapedDt.GetLength(0); i++)
            {
                for (var j = 0; j < reshapedDt.GetLength(1); j++)
                {
                    symmetricDt[i, j] = (reshapedDt[i, j] + reshapedDt[j, i]) / 2;
                }
            }

            // sampling density estimate for bandwidth function
            double[] qest = new double[symmetricDt.GetLength(0)];
            for (var i = 0; i < symmetricDt.GetLength(0); i++)
            {
                double sum = 0;
                for (var j = 0; j < symmetricDt.GetLength(1); j++)
                {
                    sum += reshapedDt[i, j];
                }
                qest[i] = sum / (N * Math.Pow(rho0[i], dim));
            }

            if (differentialOperator == 1)
            {
                beta  = -0.5;
                alpha = -dim / 4 + 0.5;
            }
            else if (differentialOperator == 2)
            {
                beta  = -0.5;
                alpha = -dim / 4;
            }

            double c1 = 2 - (2 * alpha) + (dim * beta) + (2 * beta);
            double c2 = 0.5 - (2 * alpha) + (2 * dim * alpha) + (dim * beta / 2) + beta;

            for (var i = 0; i < sortedDistances.GetLength(0); i++)
            {
                for (int j = 0; j < sortedDistances.GetLength(1); j++)
                {
                    sortedDistances[i, j] = Math.Pow(sortedDistances[i, j], 2);
                }
            }

            // construct bandwidth function rho(x) from the sampling density estimate
            double[] rho    = new double[qest.Length];
            double   sumRho = 0;

            for (var i = 0; i < qest.Length; i++)
            {
                rho[i]  = Math.Pow(qest[i], beta);
                sumRho += rho[i];
            }
            for (var i = 1; i < qest.Length; i++)
            {
                rho[i] = rho[i] / sumRho * rho.Length;
            }

            // construct the exponent of K^S_epsilon
            for (var i = 0; i < sortedDistances.GetLength(0); i++)
            {
                for (var j = 0; j < sortedDistances.GetLength(1); j++)
                {
                    sortedDistances[i, j] = sortedDistances[i, j] / rho[i];
                }
            }
            for (var i = 0; i < sortedDistances.GetLength(0); i++)
            {
                for (var j = 0; j < sortedDistances.GetLength(1); j++)
                {
                    sortedDistances[i, j] = sortedDistances[i, j] / rho[indices[i, j]];
                }
            }

            // tune epsilon for the final kernel
            double epsilon = evaluateFinalEpsilon(epss, sortedDistances, N, numberOfKNN);

            // K^S_epsilon with final choice of epsilon
            for (var i = 0; i < sortedDistances.GetLength(0); i++)
            {
                for (var j = 0; j < sortedDistances.GetLength(1); j++)
                {
                    sortedDistances[i, j] = Math.Exp(-sortedDistances[i, j] / (4 * epsilon));
                }
            }

            // the matrix created here might be large, must change it to sparse format
            double[,] reshapedSortedDistances  = reshapeDt(sortedDistances, indices, N, numberOfKNN);
            double[,] symmetricSortedDistances = new double[reshapedSortedDistances.GetLength(0), reshapedSortedDistances.GetLength(1)];
            for (var i = 0; i < reshapedSortedDistances.GetLength(0); i++)
            {
                for (var j = 0; j < reshapedSortedDistances.GetLength(1); j++)
                {
                    symmetricSortedDistances[i, j] = (reshapedSortedDistances[i, j] + reshapedSortedDistances[j, i]) / 2;
                }
            }

            double temp;

            // q^S_epsilon (this is the sampling density estimate q(x) obtained from the VB kernel)
            for (var i = 0; i < symmetricSortedDistances.GetLength(0); i++)
            {
                temp = 0;
                for (var j = 0; j < symmetricSortedDistances.GetLength(1); j++)
                {
                    temp += symmetricSortedDistances[i, j];
                }
                qest[i] = temp / Math.Pow(rho[i], dim);
            }

            double[,] Dinv1 = new double[N, N];
            for (var i = 0; i < N; i++)
            {
                Dinv1[i, i] = Math.Pow(qest[i], -alpha);
            }

            double[,] DtimesDinv = new double[N, N];
            DtimesDinv           = Accord.Math.Matrix.Dot(symmetricSortedDistances, Dinv1);
            double[,] newD       = new double[N, N];
            newD = Accord.Math.Matrix.Dot(Dinv1, DtimesDinv);

            double[,] Sinv = new double[N, N];
            double temp2;

            for (var i = 0; i < N; i++)
            {
                temp2 = 0;
                for (var j = 0; j < N; j++)
                {
                    temp2 += newD[i, j];
                }
                Sinv[i, i] = Math.Pow(Math.Pow(rho[i], 2) * temp2, -0.5);
            }

            double[,] newDtimesSinv = new double[N, N];
            newDtimesSinv           = Accord.Math.Matrix.Dot(newD, Sinv);
            double[,] finalD        = new double[N, N];
            finalD = Accord.Math.Matrix.Dot(Sinv, newDtimesSinv);
            for (var i = 0; i < N; i++)
            {
                finalD[i, i] = finalD[i, i] - Math.Pow(rho[i], -2) + 1;
            }

            double[] DMAPEigVals;
            double[,] DMAPEigVecs;
            bool sort    = true;
            bool inPlace = false;
            bool scaled  = true;

            (DMAPEigVals, DMAPEigVecs) = EigenDecomposition.FindEigenValuesAndEigenvectorsSymmetricOnly(finalD, numberOfEigenvectors, inPlace, sort, scaled);
            for (var i = 0; i < numberOfEigenvectors; i++)
            {
                DMAPEigVals[i] = Math.Log(DMAPEigVals[i]) / epsilon;
            }
            DMAPEigVecs = Accord.Math.Matrix.Dot(Sinv, DMAPEigVecs);


            // normalize qest into a density
            for (var i = 0; i < N; i++)
            {
                qest[i] = qest[i] / (N * Math.Pow(4 * Math.PI * epsilon, dim / 2));
            }

            // constuct the invariant measure of the system
            double[] peq = new double[N];
            for (var i = 0; i < N; i++)
            {
                peq[i] = qest[i] * Math.Pow(Sinv[i, i], -2);
            }

            double normalizationFactor = 0;

            for (var i = 0; i < N; i++)
            {
                normalizationFactor += peq[i] / qest[i] / N;
            }

            // normalize the invariant measure
            for (var i = 0; i < N; i++)
            {
                peq[i] = peq[i] / normalizationFactor;
            }

            //normalize eigenfunctions such that: \sum_i psi(x_i)^2 p(x_i)/q(x_i) = 1
            double[] EigVec_i       = new double[N];
            double[] tempVector     = new double[N];
            double   meanTempVector = 0;

            for (var i = 0; i < numberOfEigenvectors; i++)
            {
                EigVec_i = Enumerable.Range(0, DMAPEigVecs.GetLength(0)).Select(x => DMAPEigVecs[x, i]).ToArray();
                for (var j = 0; j < N; j++)
                {
                    tempVector[j] = Math.Pow(EigVec_i[j], 2) * (peq[j] / qest[j]);
                }
                meanTempVector = FindMeanOfVector(tempVector);
                for (var j = 0; j < N; j++)
                {
                    DMAPEigVecs[j, i] = DMAPEigVecs[j, i] / Math.Sqrt(meanTempVector);
                }
            }

            DMAPeigenvalues  = DMAPEigVals;
            DMAPeigenvectors = DMAPEigVecs;
        }