Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Main with Changes from Developer #80

Merged
merged 11 commits into from
Dec 6, 2023
2 changes: 1 addition & 1 deletion docs/G_Digraph_2_Intro.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ let karateOutput = sprintf "Successfully imported the undirected karate graph! I
(**
A conversion into an Adjacency Matrix is also very easily achievable. It can be executed as follows.
*)
let monkeyAdjacencyMatrix = DiGraph.toMatrix monkeyGraph
let monkeyAdjacencyMatrix = DiGraph.toAdjacencyMatrix id monkeyGraph
(***include-value: monkeyAdjacencyMatrix***)

(**
Expand Down
4 changes: 2 additions & 2 deletions docs/M_4_CentralityMeasures.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ It quantifies how far a node is from the farthest other node in the network in t
In other words, it represents the maximum distance between a node and any other node in the graph.
*)

let eccentricity (node:'NodeKey) =
Measures.Eccentricity.computeOfNodeWithEdgeData centralityGraph node
let eccentricity (node:int) =
Measures.Eccentricity.computeOfNodeWithEdgeData(centralityGraph,node)

renderCyGraph (fun x -> CyParam.label ($"Node: {x};Eccentricity: {eccentricity x}"))
(*** include-it-raw ***)
Expand Down
220 changes: 220 additions & 0 deletions src/Graphoscope/AdjGraph.fs
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,226 @@
AdjGraph.getSubGraphOfNodeSeq graph subNodes



///Returns if the given graph features loops
static member hasLoops (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>) =
graph
|> Seq.countIf (fun (kv) ->
let d,n = kv.Value
n|>Dictionary.containsKey kv.Key
)
|> fun x -> x<>0

///Returns if the given graph does not feature loops
static member isSimple (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>) =
graph
|> Seq.countIf (fun (kv) ->
let d,n = kv.Value
n|>Dictionary.containsKey kv.Key
)
|> fun x -> x=0

static member getNodeLabel (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>) (nk:'NodeKey) :'NodeData =
graph.Item nk
|> fun (d,n) -> d


static member filterGraphByNodeKey (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>) (nodeFilter:'NodeKey -> bool) : AdjGraph<'NodeKey, 'NodeData, 'EdgeData> =
let newGraph :AdjGraph<'NodeKey, 'NodeData, 'EdgeData> = Dictionary<_,_>()
graph
|> Seq.iter(fun kvp ->
if nodeFilter (kvp.Key) then
let d,n = kvp.Value

let nNew:Dictionary<'NodeKey,'EdgeData> =
let dicP :Dictionary<'NodeKey,'EdgeData> = new Dictionary<_,_>()
n|>Seq.iter(fun tsv -> if nodeFilter tsv.Key then dicP.Add(tsv.Key,tsv.Value))
dicP

newGraph.Add (kvp.Key,(d,nNew))
)
newGraph

static member filterGraphByNodeKeyInplace (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>) (nodeFilter:'NodeKey -> bool) : AdjGraph<'NodeKey, 'NodeData, 'EdgeData> =
graph
|> Seq.iter(fun (kvp) ->
if nodeFilter (kvp.Key) |> not then
graph.Remove kvp.Key |> ignore
else
let d,n = kvp.Value
n|>Seq.iter(fun tsv -> if nodeFilter tsv.Key |>not then n.Remove tsv.Key|>ignore)
)
graph

static member filterGraphByEdge (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>) (edgeFilter:'NodeKey -> 'NodeKey -> bool) : AdjGraph<'NodeKey, 'NodeData, 'EdgeData> =
let newGraph :AdjGraph<'NodeKey, 'NodeData, 'EdgeData> = Dictionary<_,_>()

graph
|> Seq.iter(fun (kvp) ->
let (d,n) = kvp.Value

let nNew:Dictionary<'NodeKey,'EdgeData> =
let dicS :Dictionary<'NodeKey,'EdgeData> = new Dictionary<_,_>()
n|>Seq.iter(fun tvp -> if edgeFilter kvp.Key tvp.Key then dicS.Add(tvp.Key,tvp.Value))
dicS
newGraph.Add(kvp.Key,(d,nNew))
)

newGraph

static member filterGraphByEdgeInplace (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>) (edgeFilter:'NodeKey -> 'NodeKey -> bool) : AdjGraph<'NodeKey, 'NodeData, 'EdgeData> =
graph
|> Seq.iter(fun (kvp) ->
let (d,n) = kvp.Value
(n|>Seq.iter(fun tvp -> if edgeFilter kvp.Key tvp.Key |>not then n.Remove tvp.Key|>ignore))
)

graph

static member filterGraphByContext (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>) (contextFilter: 'context -> bool) : AdjGraph<'NodeKey, 'NodeData, 'EdgeData> =
let newGraph :AdjGraph<'NodeKey, 'NodeData, 'EdgeData> = Dictionary<_,_>()
graph
|> Seq.iter(fun kvp ->
if contextFilter (kvp.Value) then
let d,n = kvp.Value

let nNew:Dictionary<'NodeKey,'EdgeData> =
let dicP :Dictionary<'NodeKey,'EdgeData> = new Dictionary<_,_>()
n|>Seq.iter(fun tsv -> if contextFilter graph.[tsv.Key] then dicP.Add(tsv.Key,tsv.Value))
dicP

newGraph.Add (kvp.Key,(d,nNew))
)
newGraph

static member filterGraphByContextInplace (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>)(contextFilter: 'context -> bool) : AdjGraph<'NodeKey, 'NodeData, 'EdgeData> =
graph
|> Seq.iter(fun (kvp) ->
if contextFilter (kvp.Value) |> not then

Check warning on line 567 in src/Graphoscope/AdjGraph.fs

View workflow job for this annotation

GitHub Actions / build-and-test-linux

This construct causes code to be less generic than indicated by the type annotations. The type variable 'context has been constrained to be type ''NodeData * Dictionary<'NodeKey,'EdgeData>'.

Check warning on line 567 in src/Graphoscope/AdjGraph.fs

View workflow job for this annotation

GitHub Actions / build-and-test-windows

This construct causes code to be less generic than indicated by the type annotations. The type variable 'context has been constrained to be type ''NodeData * Dictionary<'NodeKey,'EdgeData>'.
graph.Remove kvp.Key |> ignore
else
let d,n = kvp.Value
n|>Seq.iter(fun tsv -> if contextFilter graph.[tsv.Key] |>not then n.Remove tsv.Key|>ignore)
)
graph

static member mapNodeData (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>) (mapping:'NodeData -> 'NodeData_) : AdjGraph<'NodeKey, 'NodeData_, 'EdgeData> =
let newGraph :AdjGraph<'NodeKey, 'NodeData_, 'EdgeData> = Dictionary<_,_>()
graph
|> Seq.iter(fun kvp ->

let d,n = kvp.Value
let mappedNodeData = mapping d
let nCloned = new Dictionary<'NodeKey,'EdgeData>(n)

newGraph.Add (kvp.Key,(mappedNodeData,nCloned))
)
newGraph

static member mapNodeDataInplace (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>) (mapping:'NodeData -> 'NodeData) : AdjGraph<'NodeKey, 'NodeData, 'EdgeData> =
graph
|> Seq.iter(fun (kvp) ->
let d,n = kvp.Value
let mappedNodeData = mapping d
graph.Item kvp.Key <- (mappedNodeData,n)
)
graph

static member mapNodeKey (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>) (mapping:'NodeKey -> 'NodeKey_) : AdjGraph<'NodeKey_, 'NodeData, 'EdgeData> =
let newGraph :AdjGraph<'NodeKey_, 'NodeData, 'EdgeData> = Dictionary<_,_>()
graph
|> Seq.iter(fun kvp ->
let newKey = mapping kvp.Key
let d,n = kvp.Value

let nNew:Dictionary<'NodeKey_,'EdgeData> =
let dicS :Dictionary<'NodeKey_,'EdgeData> = new Dictionary<_,_>()
n
|>Seq.iter(fun tvp ->
let mappedNode = mapping tvp.Key
dicS.Add(mappedNode,tvp.Value)
)
dicS

newGraph.Add (newKey,(d,nNew))
)
newGraph

static member mapNodeKeyInplace (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>) (mapping:'NodeKey -> 'NodeKey) : AdjGraph<'NodeKey, 'NodeData, 'EdgeData> =
graph
|> Seq.iter(fun (kvp) ->
let newKey = mapping kvp.Key
let d,n = kvp.Value

let nNew:Dictionary<'NodeKey,'EdgeData> =
let dicS :Dictionary<'NodeKey,'EdgeData> = new Dictionary<_,_>()
n
|>Seq.iter(fun tvp ->
let mappedNode = mapping tvp.Key
dicS.Add(mappedNode,tvp.Value)
)
dicS

graph.Add (newKey,(d,nNew))
graph.Remove kvp.Key |> ignore
)
graph

static member mapEdgeData (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>) (mapping:'NodeKey -> 'NodeKey -> 'EdgeData -> 'EdgeData_) : AdjGraph<'NodeKey, 'NodeData, 'EdgeData_> =
let newGraph :AdjGraph<'NodeKey, 'NodeData, 'EdgeData_> = Dictionary<_,_>()
graph
|> Seq.iter(fun kvp ->
let (d,n) = kvp.Value

let nNew:Dictionary<'NodeKey,'EdgeData_> =
let dicS :Dictionary<'NodeKey,'EdgeData_> = new Dictionary<_,_>()
n
|>Seq.iter(fun tvp ->
let mappedEdgeData = mapping kvp.Key tvp.Key tvp.Value
dicS.Add(tvp.Key,mappedEdgeData)
)
dicS

newGraph.Add(kvp.Key,(d,nNew))
)

newGraph

static member mapEdgeDataInplace (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>) (mapping:'NodeKey -> 'NodeKey -> 'EdgeData -> 'EdgeData) : AdjGraph<'NodeKey, 'NodeData, 'EdgeData> =
graph
|> Seq.iter(fun kvp ->
let (d,n) = kvp.Value

n
|>Seq.iter(fun (tvp:KeyValuePair<'NodeKey,'EdgeData>) ->
let newEdgeData :'EdgeData = mapping (kvp.Key) (tvp.Key) (tvp.Value)
n.Item tvp.Key <- (newEdgeData)
)
)
graph

static member mapContext (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>) (contextMapping:'context -> 'context_) : AdjGraph<'NodeKey, 'NodeData_, 'EdgeData_> =
let newGraph :AdjGraph<'NodeKey, 'NodeData_, 'EdgeData_> = Dictionary<_,_>()
graph
|> Seq.iter(fun kvp ->
let (d,n) = kvp.Value
let mappedContext = contextMapping kvp.Value

Check warning on line 675 in src/Graphoscope/AdjGraph.fs

View workflow job for this annotation

GitHub Actions / build-and-test-linux

This construct causes code to be less generic than indicated by the type annotations. The type variable 'context has been constrained to be type ''NodeData * Dictionary<'NodeKey,'EdgeData>'.

Check warning on line 675 in src/Graphoscope/AdjGraph.fs

View workflow job for this annotation

GitHub Actions / build-and-test-windows

This construct causes code to be less generic than indicated by the type annotations. The type variable 'context has been constrained to be type ''NodeData * Dictionary<'NodeKey,'EdgeData>'.

newGraph.Add(kvp.Key,(mappedContext))
)

newGraph

static member mapContextInplace (graph: AdjGraph<'NodeKey, 'NodeData, 'EdgeData>)(contextMapping:'context -> 'context) : AdjGraph<'NodeKey, 'NodeData, 'EdgeData> =
graph
|> Seq.iter(fun kvp ->
let (d,n) = kvp.Value
let mappedContext = contextMapping kvp.Value
graph.Item kvp.Key <- mappedContext
)
graph


module AdjGraph =

/// <summary>
Expand Down
Loading
Loading