/// <summary>
        /// Layouts a connected graph with Multidimensional Scaling, using
        /// shortest-path distances as Euclidean target distances.
        /// </summary>
        /// <param name="geometryGraph">A graph.</param>
        /// <param name="settings">The settings for the algorithm.</param>
        /// <param name="x">Coordinate vector.</param>
        /// <param name="y">Coordinate vector.</param>
        internal static void LayoutGraphWithMds(GeometryGraph geometryGraph, MdsLayoutSettings settings, out double[] x, out double[] y)
        {
            x = new double[geometryGraph.Nodes.Count];
            y = new double[geometryGraph.Nodes.Count];
            if (geometryGraph.Nodes.Count == 0)
            {
                return;
            }
            if (geometryGraph.Nodes.Count == 1)
            {
                x[0] = y[0] = 0;
                return;
            }
            int    k        = Math.Min(settings.PivotNumber, geometryGraph.Nodes.Count);
            int    iter     = settings.GetNumberOfIterationsWithMajorization(geometryGraph.Nodes.Count);
            double exponent = settings.Exponent;

            var            pivotArray     = new int[k];
            PivotDistances pivotDistances = new PivotDistances(geometryGraph, false, pivotArray);

            pivotDistances.Run();
            double[][] c = pivotDistances.Result;
            MultidimensionalScaling.LandmarkClassicalScaling(c, out x, out y, pivotArray);
            ScaleToAverageEdgeLength(geometryGraph, x, y);

            if (iter > 0)
            {
                AllPairsDistances apd = new AllPairsDistances(geometryGraph, false);
                apd.Run();
                double[][] d = apd.Result;
                double[][] w = MultidimensionalScaling.ExponentialWeightMatrix(d, exponent);
                // MultidimensionalScaling.DistanceScaling(d, x, y, w, iter);
                MultidimensionalScaling.DistanceScalingSubset(d, x, y, w, iter);
            }
        }
         void SetNodePositionsAndMovedBoundaries() {
            
            int pivotNumber = Math.Min(graph.Nodes.Count,settings.PivotNumber);
            double scaleX = settings.ScaleX;
            double scaleY = settings.ScaleY;
          
            int[] pivotArray = new int[pivotNumber];
            PivotDistances pivotDistances = new PivotDistances(graph, false, pivotArray);
            pivotDistances.Run();
            double[][] c = pivotDistances.Result;
            double[] x, y;
            MultidimensionalScaling.LandmarkClassicalScaling(c, out x, out y, pivotArray);

            Standardize(x);
            double[] p = Centrality.PageRank(graph, .85, false);
            // double[] q = Centrality.PageRank(graph, .85, true);
            Standardize(p);
            // Standardize(q);

            int index = 0;
            foreach (Node node in graph.Nodes) {
                node.Center = new Point((int) (x[index]*scaleX), (int) (Math.Sqrt(p[index])*scaleY));
                index++;
            }

            OverlapRemoval.RemoveOverlaps(graph.Nodes.ToArray(), settings.NodeSeparation);
        }
        /// <summary>
        /// Layouts a connected graph with Multidimensional Scaling, using
        /// shortest-path distances as Euclidean target distances.
        /// </summary>
        /// <param name="geometryGraph">A graph.</param>
        /// <param name="settings">The settings for the algorithm.</param>
        /// <param name="x">Coordinate vector.</param>
        /// <param name="y">Coordinate vector.</param>
        internal static void LayoutGraphWithMds(GeometryGraph geometryGraph, MdsLayoutSettings settings, out double[] x, out double[] y) {            
            x = new double[geometryGraph.Nodes.Count];
            y = new double[geometryGraph.Nodes.Count];
            if (geometryGraph.Nodes.Count == 0) return;
            if (geometryGraph.Nodes.Count == 1)
            {
                x[0] = y[0] = 0;
                return;
            }
            int k = Math.Min(settings.PivotNumber, geometryGraph.Nodes.Count);
            int iter = settings.GetNumberOfIterationsWithMajorization(geometryGraph.Nodes.Count);
            double exponent = settings.Exponent;

            var pivotArray = new int[k];
            PivotDistances pivotDistances = new PivotDistances(geometryGraph, false, pivotArray);
            pivotDistances.Run();
            double[][] c = pivotDistances.Result;
            MultidimensionalScaling.LandmarkClassicalScaling(c, out x, out y, pivotArray);
            ScaleToAverageEdgeLength(geometryGraph, x, y);
            
            if (iter > 0) {
                AllPairsDistances apd = new AllPairsDistances(geometryGraph, false);
                apd.Run();
                double[][] d = apd.Result;
                double[][] w = MultidimensionalScaling.ExponentialWeightMatrix(d, exponent);
                // MultidimensionalScaling.DistanceScaling(d, x, y, w, iter);
                MultidimensionalScaling.DistanceScalingSubset(d, x, y, w, iter);
            }
        }