public bool TryCalculateGraphMetrics
            (IGraph graph, BackgroundWorker backgroundWorker, out MetricDouble graphMetrics)
        {
            Debug.Assert(graph != null);

            IVertexCollection oVertices = graph.Vertices;
            Int32 iVertices = oVertices.Count;

            MetricDouble oClusteringCoefficients = new MetricDouble(iVertices, "ClusteringCoefficient");
            graphMetrics = oClusteringCoefficients;

            bool bGraphIsDirected = (graph.Directedness == GraphDirectedness.Directed);

            Int32 iCalculations = 0;

            foreach (IVertex oVertex in oVertices)
            {
                if (iCalculations % VerticesPerProgressReport == 0 &&
                    !ReportProgressAndCheckCancellationPending(iCalculations, iVertices, backgroundWorker))
                {
                    return (false);
                }

                oClusteringCoefficients.Add(oVertex.ID, CalculateClusteringCoefficient(oVertex, bGraphIsDirected));

                iCalculations++;
            }

            return (true);
        }
        public bool TryCalculateGraphMetrics
            (IGraph graph, BackgroundWorker backgroundWorker, out MetricDouble graphMetrics)
        {
            Debug.Assert(graph != null);

            IVertexCollection oVertices = graph.Vertices;
            Int32 iVertices = oVertices.Count;
            Int32 iCalculations = 0;

            // The key is an IVertex.ID and the value is the vertex's reciprocated
            // vertex pair ratio, or null.

            MetricDouble oReciprocatedVertexPairRatios = new MetricDouble(oVertices.Count, "ReciprocatedVertexPairRatio");
            graphMetrics = oReciprocatedVertexPairRatios;
            if (graph.Directedness == GraphDirectedness.Directed)
            {
                // Contains a key for each of the graph's unique edges.  The key is
                // the edge's ordered vertex ID pair.

                HashSet<Int64> oVertexIDPairs = GetVertexIDPairs(graph);

                foreach (IVertex oVertex in oVertices)
                {
                    // Check for cancellation and report progress every
                    // VerticesPerProgressReport calculations.

                    if (
                        (iCalculations % VerticesPerProgressReport == 0)
                        &&
                        !ReportProgressAndCheckCancellationPending(
                            iCalculations, iVertices, backgroundWorker)
                        )
                    {
                        return (false);
                    }

                    oReciprocatedVertexPairRatios.Add(oVertex.ID,
                        CalculateReciprocatedVertexPairRatio(
                            oVertex, oVertexIDPairs));

                    iCalculations++;
                }
            }

            return (true);
        }
        public Boolean TryCalculateGraphMetrics
        (
            IGraph graph,
            BackgroundWorker backgroundWorker,
            out MetricDouble graphMetrics
        )
        {
            Debug.Assert(graph != null);
            

            IVertexCollection oVertices = graph.Vertices;

            /** initialize PR per vertex **/
            Dictionary<Int32, Double> oldPageRanks = new Dictionary<Int32, Double>(oVertices.Count);
            Dictionary<Int32, Double> newPageRanks = new Dictionary<Int32, Double>(oVertices.Count);
            MetricDouble oMetricDouble = new MetricDouble(oVertices.Count, "PageRank");
            graphMetrics = oMetricDouble;

            foreach(IVertex oVertex in oVertices){
                System.Console.WriteLine("V{0}", oVertex.ID);
                oldPageRanks.Add(oVertex.ID, 1.0/oVertices.Count);
                newPageRanks.Add(oVertex.ID, 0);
            }
            int ii = 0;
            while (!isConverged(oldPageRanks, newPageRanks)){
                
                oldPageRanks = newPageRanks;
                if (!ReportProgressAndCheckCancellationPending(0, 100, backgroundWorker))
                {
                    return (false);
                }
                calculateVertexPageRank(oVertices, oldPageRanks, out newPageRanks);
                ii++;
            }
            System.Console.WriteLine("ii = {0}", ii);
            
            foreach (KeyValuePair<Int32, Double> p in newPageRanks) {
                oMetricDouble.Add(p.Key, p.Value);
            }
          

            return (true);
        }