anchor.diff:  
           louvainInPlace_ 0 g2 modularityIncreaseThreshold 0.
      
  +    let private louvainMethodResolution (g1:ArrayAdjacencyGraph<'Vertex,'Label,float>) (randomized:bool) (modularityIncreaseThreshold: float) (resolution: float) : (ArrayAdjacencyGraph<'Vertex,'Label*int,float>) = 
  +        
  +        //Create the vertices for the output graph and a new one for further computation
  +        let vertices,vertices2 : Dictionary<'Vertex,'Label*int>*Dictionary<'Vertex,int*int>=
  +            let vertices = g1.LabelMap().Keys
  +            let newDictionary = System.Collections.Generic.Dictionary<'Vertex,'Label*int>()
  +            let newDictionary2 = System.Collections.Generic.Dictionary<'Vertex,int*int>()
  +            let mutable counter = 0
  +            for vertex in vertices do
  +                let newLabel = (g1.GetLabel vertex),counter
  +                newDictionary.Add (vertex,newLabel)
  +                newDictionary2.Add (vertex,(counter,counter))
  +                counter <- counter+1
  +            newDictionary,newDictionary2
  +        
  +        //Create the edges for the output graph
  +        let edges =
  +            g1.AdjacencyGraph()
  +        
  +        //Create the edges for the computation graph
  +        let edges2 =
  +            let newEdges = System.Collections.Generic.Dictionary<int,(int*int*float)[]>()
  +            for v in edges do
  +                let key     = vertices2.Item (v.Key) |> fst
  +                let edges   = v.Value |> Array.map (fun (s,t,w) -> ((vertices2.Item s |> fst),(vertices2.Item t |> fst),w))
  +                newEdges.Add (key,edges)
  +            newEdges
  +
  +        //Update the vertices for the computation graph
  +        let verticesUpdated =
  +            let newVertices = System.Collections.Generic.Dictionary<int,int*int>()
  +            for i in vertices2 do
  +                let v = i.Value
  +                let key = fst v
  +                newVertices.Add (key,v)
  +            newVertices
  +
  +        let currentResolution =
  +            if resolution <= 0. then
  +                failwith "The resolution has to be at least 1."
  +            else
  +                resolution
  +
  +
  +        //The output graph
  +        let g : (ArrayAdjacencyGraph<'Vertex,'Label*int,float>) = ArrayAdjacencyGraph(edges,vertices)
  +        //The computation graph
  +        let g2 :(ArrayAdjacencyGraph<int,int*int,float>)        = ArrayAdjacencyGraph(edges2,verticesUpdated)
  +
  +
  +        let louvainCycleInPlace (graph:ArrayAdjacencyGraph<int,int*int,float>) (randomized:bool) (modularityIncreaseThreshold: float) (numberOfLoops:int) (previousModularity:float) :(int*ArrayAdjacencyGraph<int,int*int,float>*float)=
  +                
  +            //Array of all vertices in the graph
  +            let verti =
  +                graph.GetVertices()
  +            
  +            //Shuffles the verti array if radomize is true
  +            if randomized then
  +                Randomize.shuffle verti|>ignore
  +
  +            //Total weight of all edges combined
  +            let totalWeight =
  +        
  +                let result = Array.zeroCreate (graph.AdjacencyGraph()).Count
  +                let mutable i = 0
  +                for group in (graph.AdjacencyGraph()) do
  +                    result.[i] <- group.Value
  +                    i <- i+1
  +                result
  +                |> Array.concat
  +                |> Array.sumBy (fun (source,target,weight) -> (weight))
  +
  +               
  +            //Array of all neighbouring vertices, returned as (vertex,edgeweight) array. The index of the element is the same as the vertex in verti.
  +            let neighbours =
  +                [|
  +                    for i in verti do
  +                        graph.GetConnectedEdges i
  +                        |> Array.map(fun (s, t, w) ->
  +                            if s=i then (t,w)
  +                            else (s,w))
  +                        |> Array.sortBy fst
  +                        
  +                |]
  +            
  +            //weighted Degree of the vertex. The index of the element is the same as the vertex in verti.
  +            let ki =
  +                neighbours
  +                |> Array.map(Array.sumBy snd)
  +                                                                              
  +            //The weight of all self-referencing loops of the vertices. The index of the element is the same as the vertex in verti.
  +            let selfLoops =                                                
  +                [|
  +                    for vertex in verti do 
  +                        graph.GetConnectedEdges(vertex)
  +                        |>Array.sumBy(fun (s,t,w) -> if s=vertex&&t=vertex then w/2. else 0.) 
  +                |]
  +            
  +            //A Dictionary, where the key is the community and the value is a tupel of the weighted degree of the community and the sum of all internal edges.
  +            let communitySumtotalSumintern =
  +                let output = System.Collections.Generic.Dictionary<int,float*float>() 
  +                for i=0 to graph.VertexCount-1 do
  +                    let vertex = verti.[i]
  +                    let originalLabel,label = graph.GetLabel vertex
  +                    let communityWeightTotalStart =  ki.[i]
  +                    let selfLoopsStart = selfLoops.[i] 
  +                    output.Add(label,(communityWeightTotalStart,selfLoopsStart))
  +                output       
  +            
  +            //Function to calculate the modularity of the graph.
  +            let modularityQuality resolution =
  +                let mutable q = 0.
  +                for i in communitySumtotalSumintern do
  +                    let (totalSumC,sumIntern) = i.Value
  +                    if totalSumC > 0. then 
  +                        let calculation = resolution*((sumIntern/2.)/(totalWeight/2.))-((totalSumC/totalWeight)**2.)
  +                        q <- (q+(calculation))
  +                q
  +            //Function to calculate the modularity of the graph.
  +            let modularityQuality' startValue =
  +                if startValue <> 0. then failwith "Wrong startValue"
  +                let mutable q = startValue
  +                for i in communitySumtotalSumintern do
  +                    let (totalSumC,sumIntern) = i.Value
  +                    if totalSumC > 0. then 
  +                        let calculation = (sumIntern - (totalSumC*totalSumC) / totalWeight)
  +                        q <- (q+(calculation))
  +                (q/totalWeight)
  +
  +            //Minimal increase in modularity Quality that has to be achieved. If the increase in modularity is lower, then the first phase of the louvain Algorithm ends and a new iteration can begin.
  +            let increaseMin = modularityIncreaseThreshold //0.000001
  +
  +            //Runs once over all vertices in the graph and move the vertex into the community to which the modularity gain is maximal. In case of no positive gain, the original community is kept.
  +            let rec louvainOneLevel (counter:int) (nbOfMoves:int) =
  +                
  +                //Do until
  +                if counter = graph.VertexCount then 
  +
  +                    nbOfMoves > 0
  +
  +                else            
  +                       
  +                    //Vertex that is looked at.
  +                    let node                                 = verti.[counter]
  +                    
  +                    //The weighted degree of the node.
  +                    let ki                                   = ki.[counter] 
  +
  +                    //The weight of all self-referencing loops of the vertex.
  +                    let selfloopNode                         = selfLoops.[counter]
  +                    
  +                    //Community of the node before potential improvement.
  +                    let (fixedCommunity,originalCommunity)   = (graph.GetLabel node)
  +
  +                    //Weighted degree of the community,the sum of all internal edges.
  +                    let (originalCommunityTotalSum,originalCommunitySumIntern)       = Dictionary.getValue originalCommunity communitySumtotalSumintern
  +                              
  +                    //Remove node from its original community.                   
  +                    graph.SetLabel(node,(fixedCommunity,-1)) |> ignore
  +
  +                    //All neighbors of the node with their edgeWeight.         
  +                    let neighbors           = 
  +                       
  +                        neighbours.[counter]
  +                        |> Array.filter (fun (vertex,weight) -> vertex <> node) 
  +                   
  +                    //This if condition prevents problems If the node is isolated and has 0 edges. 
  +                    if neighbors = Array.empty then  
  +                           
  +                        graph.SetLabel(node,(fixedCommunity, originalCommunity))|> ignore
  +                        louvainOneLevel (counter+1) (nbOfMoves)
  +                   
  +                    else
  +                                      
  +                        //All communities the node is connected to with their edgeweight.
  +                        let connectedCommunities     = 
  +                                                  
  +                            neighbors
  +                            |> Array.map (fun (vertex,weight) -> (((graph.GetLabel vertex)|>snd),weight)) 
  +                           
  +                        //All communities the node is connected to with their edgeweight, removing duplicates. 
  +                        let connectedCommunitiesCondensed =
  +                           
  +                            GroupingFunctions.sumGroupBy fst snd connectedCommunities        
  +                           
  +                        //All weights to the original community of the node.
  +                        let weightofConnectionToOldCommunity         =   
  +                           
  +                            GroupingFunctions.findWeightofConnectionToOldCommunity connectedCommunitiesCondensed originalCommunity
  +
  +                        //Removing the node from its community, updating community values communityWeightTotal and sumIntern.
  +                        let communityWeightTotalUpdate =  (originalCommunityTotalSum-ki)
  +                        let sumInternUpdate            =  (originalCommunitySumIntern-((2.*(weightofConnectionToOldCommunity))+(selfloopNode)))                  
  +
  +                        communitySumtotalSumintern.Item originalCommunity <- (communityWeightTotalUpdate,sumInternUpdate)
  +
  +                        let connectedCommunitiesCondensedNew =
  +                            Array.append [|originalCommunity,weightofConnectionToOldCommunity|] connectedCommunitiesCondensed
  +                            |> Array.distinct
  +
  +                        //Calculating the best possible community for the node, based on modularity gain. 
  +                        //Outputs the bestCommunity, the gain acived by moving the node to that community and the weight of the connection to that new Community.  
  +                        let (bestCommunity,modularityGain,connectionToBestCommunity) =                        
  +
  +                            let calculations = 
  +                                connectedCommunitiesCondensedNew
  +                                |> Array.map (fun (community,connectionToCommunity) -> 
  +                                        (
  +                                        community,
  +                                        (currentResolution*connectionToCommunity-((Dictionary.getValue community communitySumtotalSumintern|>fst)*ki/totalWeight)),
  +                                        connectionToCommunity
  +                                        )
  +                                    )
  +
  +                            calculations
  +                            |> Array.maxBy (fun (community,modularityGain,connectionToCommunity) -> modularityGain)
  +                        
  +                        //If there is a gain in modularity bigger than 0.
  +                        if modularityGain < 0.  then 
  +                           
  +                            //Resetting the community to its original state.                       
  +                            graph.SetLabel (node,(fixedCommunity,originalCommunity)) |> ignore
  +                            communitySumtotalSumintern.Item originalCommunity <- (originalCommunityTotalSum,originalCommunitySumIntern)
  +                       
  +                            louvainOneLevel (counter+1) (nbOfMoves)
  +
  +                        else                                           
  +                            let (communityNewSum,communityNewIn) = Dictionary.getValue bestCommunity communitySumtotalSumintern
  +
  +                            //Moving the node to its new community.
  +                            let sumInternBestCommunity              =      (communityNewIn+((2.*(connectionToBestCommunity)+(selfloopNode))))
  +                            let communityWeightTotalBestCommunity   =      (communityNewSum+ki)
  +                           
  +                            graph.SetLabel (node,(fixedCommunity,bestCommunity)) |> ignore
  +                            communitySumtotalSumintern.Item bestCommunity <- (communityWeightTotalBestCommunity,sumInternBestCommunity)
  +
  +                            (if bestCommunity <> originalCommunity then (nbOfMoves+1) else nbOfMoves)
  +                            |> louvainOneLevel (counter+1) 
  +         
  +            //A loop that executes louvainOneLevel as long as none of the exit conditions are met.
  +            //The exit conditions are
  +            // 1) No improvement was preformed 
  +            // 2) The increase in modularityQuality by preforming the louvainOneLevel results in a score lower than the increaseMin.
  +            let rec loop nbOfMoves currentQuality improvement :(int*ArrayAdjacencyGraph<int,int*int,float>*float)=
  +‚
  +                let qualityNew = modularityQuality currentResolution
  +                   
  +                let build (shouldIBuild:bool) :int*ArrayAdjacencyGraph<int,(int*int),float>*float=
  +
  +                    if not shouldIBuild then
  +                        failwith "ERROR"
  +                    else
  +                       
  +                       //Returns a Map oldCommunity -> updatedCommunity; Returns a dictionary where the key is the vertex and the value is the new community
  +                        let (vertexToLabelMap,vertexNewLabel) :((Map<int,int>)*(Dictionary<int,int>))=
  +                            let labelMap =
  +                                graph.GetLabels()
  +                                |> Array.map snd
  +                                |> Array.distinct
  +                                |> Array.mapi (fun i label -> (label,i))
  +                                |> Map.ofArray
  +                            let labelMap2 = 
  +                                [|
  +                                    for (oldCommunity,newCommunity) in graph.GetLabels() do
  +                                        oldCommunity,labelMap.[newCommunity]
  +                                |]
  +                                |> Map.ofArray
  +
  +                            let vertexDict = System.Collections.Generic.Dictionary<int,int>()
  +                            for i in verti do
  +                                vertexDict.Add (i,(labelMap.[(graph.GetLabel i)|>snd]))
  +
  +                            labelMap2,vertexDict                         
  +                        
  +                        //Updates the second set of labels in the outputgraph
  +                        for i in g.GetVertices() do
  +                            let (originalLabel,currentLabel) = g.GetLabel(i)
  +                            let updateLabel     = vertexToLabelMap.[currentLabel]
  +                            g.SetLabel(i,(originalLabel,updateLabel))
  +                            |> ignore
  +                        
  +                        //Returns the vertices for the next iteration of the louvain algorithm.
  +                        let vert = 
  +                            vertexToLabelMap
  +                            |> Map.toArray
  +                            |> Array.map snd
  +                            |> Array.distinct
  +                            |> Array.map (fun x -> (x,(x,x)))
  +                            |> Array.toList
  +                        
  +                        //Return the edgeList for the next iteration of the louvain algorithm.
  +                        let edgeListUpdated :(int*int*float)[]=
  +
  +                            let getLabel vertex =
  +                                Dictionary.getValue vertex vertexNewLabel
  +   
  +                            let edgesToLabelEdges :(int*int*float)[] = 
  +                                let result = Array.zeroCreate (graph.AdjacencyGraph()).Count
  +                                let mutable i = 0
  +                                for group in (graph.AdjacencyGraph()) do
  +                                    result.[i] <- group.Value
  +                                    i <- i+1
  +                                result
  +                                |> Array.concat
  +                                |> Array.map (fun (s,t,w) -> ((getLabel s),(getLabel t),w))
  +
  +                            let output = System.Collections.Generic.Dictionary<int*int,float>()
  +                            for (s,t,w) in edgesToLabelEdges do
  +                                if output.ContainsKey (s,t) then 
  +                                    let value = Dictionary.getValue ((s,t)) output
  +                                    if s=t then 
  +                                        output.Item ((s,t)) <- (value+w)
  +                                    else
  +                                        output.Item ((s,t)) <- (value+(w/2.))
  +    
  +                                elif output.ContainsKey (t,s) then
  +                                    let value = Dictionary.getValue ((t,s)) output
  +                                    if s=t then 
  +                                        output.Item ((t,s)) <- (value+w)
  +                                    else
  +                                        output.Item ((t,s)) <- (value+(w/2.))
  +    
  +                                else
  +                                    if s=t then 
  +                                        output.Add ((s,t),w)
  +                                    else
  +                                        output.Add ((s,t),(w/2.))
  +
  +                            let result = Array.zeroCreate output.Count
  +                            let mutable i = 0
  +                            for group in output do
  +                                let (s,t)   = group.Key
  +                                let (w)     = group.Value
  +                                result.[i] <- (s,t,w)
  +                                i <- i + 1
  +                            result
  +                           
  +                        nbOfMoves,                                    
  +                        ArrayAdjacencyGraph(
  +                            (vert),
  +                            (edgeListUpdated |> Array.toList)
  +                        ),
  +                        qualityNew
  +                
  +                //Start of the cycle
  +                if nbOfMoves = 0 then 
  +                 
  +                    let hasImProved = louvainOneLevel 0 0
  +
  +                    loop (nbOfMoves+1) currentQuality hasImProved
  +           
  +                elif numberOfLoops > 0 && currentQuality < previousModularity then
  +                        
  +                    nbOfMoves,
  +                    graph,
  +                    qualityNew
  +                   
  +                elif improvement then 
  +                      
  +                    if (qualityNew-currentQuality) > increaseMin then 
  +                         
  +                            loop (nbOfMoves+1) (qualityNew) (louvainOneLevel 0 0)
  +
  +                    else                    
  +                        build true
  +                elif improvement = false && nbOfMoves = 1 then 
  +                                  
  +                    nbOfMoves,
  +                    graph,
  +                    qualityNew
  +
  +                else 
  +                    build true
  +                    
  +            //Start the louvainApplication
  +            loop 0 (modularityQuality currentResolution) false
  +
  +        //The louvainLoop combines the two phases of the louvain Algorithm. As long as improvments can be performed, the louvainApplication is executed.
  +        let rec louvainInPlace_ nbOfLoops (newG:ArrayAdjacencyGraph<int,int*int,float>) (modularityIncreaseThreshold: float) (modulartiy:float) =
  +        
  +            let (nbOfMoves,newGraph,newModularity) = 
  +            
  +                louvainCycleInPlace newG randomized modularityIncreaseThreshold nbOfLoops modulartiy           
  +
  +            if nbOfMoves < 2 || ((nbOfLoops>0) && (newModularity<modulartiy)) then 
  +            
  +                g
  +
  +            else 
  +
  +                louvainInPlace_ (nbOfLoops+1) newGraph modularityIncreaseThreshold newModularity
  +
  +
  +        louvainInPlace_ 0 g2 modularityIncreaseThreshold 0.
  +
  +
  +
  +
  +
       /// Takes an ArrayAdjacencyGraph and returns a new graph whose Labels have been transformed into tupels, where the second part is the community accorging to modularity-optimization. 
       /// Parameters:
       ///
  
positive.code:                         let calculation = (sumIntern - (totalSumC*totalSumC) / totalWeight)
                          q <- (q+(calculation))
                  (q/totalWeight)
  
              //Minimal increase in modularity Quality that has to be achieved. If the increase in modularity is lower, then the first phase of the louvain Algorithm ends and a new iteration can begin.
              let increaseMin = modularityIncreaseThreshold //0.000001
  
  
negative.code:     /// The value has to be between 0. and 1. to get a meaningful result. The smaller the value, the longer the calculation takes.
      let louvainRandom (graph:ArrayAdjacencyGraph<'Vertex,'Label,float>) (modularityIncreaseThreshold: float) :(ArrayAdjacencyGraph<'Vertex,'Label*int,float>)=
          louvainMethod graph true modularityIncreaseThreshold
  
  
      let louvainResolution (graph:ArrayAdjacencyGraph<'Vertex,'Label,float>) (randomized: bool) (modularityIncreaseThreshold: float) (resolution: float) :(ArrayAdjacencyGraph<'Vertex,'Label*int,float>) =
          louvainMethodResolution graph randomized modularityIncreaseThreshold resolution
  