The FGraph is an adaptation of a functional graph.
In programming, a functional graph typically refers to a data structure or representation used to model and analyze the flow of data or the dependencies between functions in a functional programming paradigm.
Functional programming emphasizes the use of pure functions and avoids mutable state, making functional graphs particularly useful for understanding and optimizing the execution of functional programs.
It is compromised of a Dictionary, containing the nodeIndex as Key and the so called FContext as Value. The structure is visualised here:
Begin by creating an empty graph,meaning a data structure with no nodes or edges.
Then populate the graph with single elements, individual nodes are added one by one, and edges can be introduced to establish connections between them.
open Graphoscope
open FGraph
let graphToFill =
FGraph.empty
|> FGraph.addNode 1 "1"
|> FGraph.addNode 2 "2"
|> FGraph.addEdge 1 2 1.
"You have created a graph with 2 nodes and 1 edges"
|
Another way of creating a graph is by filling it with collections of nodes and edges as seen below:
let graphToFill' =
let nodes = List.init 100 (fun x -> x,$"{x}")
let edges = List.init 45 (fun x -> x,x*2,1.)
FGraph.empty
|> FGraph.addNodes nodes
|> FGraph.addEdges edges
"You have created a graph with 100 nodes and 45 edges"
|
To remove Nodes or Edges you can just use the remove functions provided:
let graphWithRemovedElements =
graphToFill'
|> FGraph.removeEdge 1 2
|> FGraph.removeNode 0
"You have reduced the graph to 99 nodes and 43 edges"
|
This directed network contains observed grooming episodes between free ranging rhesus macaques (Macaca mulatta)
in Cayo Santiago during a two month period in 1963. Cayo Santiago is an island off the coast of Puerto Rico, also
known as Isla de los monos (Island of the monkeys). A node represents a monkey and a directed edge A → B denotes
that the rhesus macaque A groomed rhesus macaque B. The integer edge weights indicate how often this behaviour was observed.
open Graphoscope
open FSharpAux.IO
open FSharpAux.IO.SchemaReader.Attribute
First we model the input domain as a reccord type and read a sequence of MonkeyEdges
type MonkeyEdge = {
[<Field(0)>] Source : int
[<Field(1)>] Target : int
[<Field(2)>] Groomed : int
}
let monkeyEdges =
Seq.fromFileWithCsvSchema<MonkeyEdge>("D:/Source/Graphoscope/tests/Graphoscope.Tests/ReferenceGraphs/out.moreno_rhesus_rhesus.txt",' ',false,skipLines=2 )
Convert a MonkeyEdge record to a sequence of graph elements (sourceKey * sourceData * targetKey * targetData * edgeData)
let monkeyGraph =
monkeyEdges
|> Seq.map (fun mke ->
mke.Source, sprintf "Monkey_%i" mke.Source,mke.Target,sprintf "Monkey_%i" mke.Target,float mke.Groomed)
|> FGraph.ofSeq
let's use Cytoscape.NET for visualization:
open Cytoscape.NET
let vizGraph =
CyGraph.initEmpty ()
|> CyGraph.withElements [
for (sk,s,tk,t,el) in (FGraph.toSeq monkeyGraph) do
let sk, tk = (string sk), (string tk)
yield Elements.node sk [ CyParam.label s ]
yield Elements.node tk [ CyParam.label t ]
yield Elements.edge (sprintf "%s_%s" sk tk) sk tk [ CyParam.label el ]
]
|> CyGraph.withStyle "node"
[
CyParam.content =. CyParam.label
CyParam.color "#A00975"
]
No value returned by any evaluator
|
namespace Graphoscope
Multiple items
module FGraph
from Graphoscope
--------------------
type FGraph =
new: unit -> FGraph
static member addEdge: nk1: 'NodeKey -> nk2: 'NodeKey -> ed: 'EdgeData -> g: FGraph<'NodeKey,'NodeData,'EdgeData> -> FGraph<'NodeKey,'NodeData,'EdgeData> (requires comparison)
static member addEdges: edgeSeq: seq<'NodeKey * 'NodeKey * 'EdgeData> -> g: FGraph<'NodeKey,'NodeData,'EdgeData> -> FGraph<'NodeKey,'NodeData,'EdgeData> (requires comparison)
static member addElement: nk1: 'NodeKey -> nd1: 'NodeData -> nk2: 'NodeKey -> nd2: 'NodeData -> ed: 'EdgeData -> g: FGraph<'NodeKey,'NodeData,'EdgeData> -> FGraph<'NodeKey,'NodeData,'EdgeData> (requires comparison)
static member addNode: nk: 'NodeKey -> nd: 'NodeData -> g: FGraph<'NodeKey,'NodeData,'EdgeData> -> FGraph<'NodeKey,'NodeData,'EdgeData> (requires comparison)
static member addNodes: nodeSeq: seq<'NodeKey * 'NodeData> -> g: FGraph<'NodeKey,'NodeData,'EdgeData> -> FGraph<'NodeKey,'NodeData,'EdgeData> (requires comparison)
static member clone: graph: FGraph<'NodeKey,'NodeData,'EdgeData> -> FGraph<'NodeKey,'NodeData,'EdgeData> (requires comparison)
static member containsEdge: v1: 'NodeKey -> v2: 'NodeKey -> g: FGraph<'NodeKey,'NodeData,'EdgeData> -> bool (requires comparison)
static member containsNode: vk: 'NodeKey -> g: FGraph<'NodeKey,'NodeData,'EdgeData> -> bool (requires comparison)
static member countEdges: g: FGraph<'NodeKey,'NodeData,'EdgeData> -> int (requires comparison)
...
--------------------
type FGraph<'NodeKey,'NodeData,'EdgeData (requires comparison)> = System.Collections.Generic.Dictionary<'NodeKey,FContext<'NodeKey,'NodeData,'EdgeData>>
--------------------
new: unit -> FGraph
val graphToFill: FGraph<int,string,float>
val empty<'NodeKey,'NodeData,'EdgeData (requires comparison)> : FGraph<'NodeKey,'NodeData,'EdgeData> (requires comparison)
<summary>
Returns a new, empty graph
</summary>
<returns>Empty FGraph</returns>
static member FGraph.addNode: nk: 'NodeKey -> nd: 'NodeData -> g: FGraph<'NodeKey,'NodeData,'EdgeData> -> FGraph<'NodeKey,'NodeData,'EdgeData> (requires comparison)
static member FGraph.addEdge: nk1: 'NodeKey -> nk2: 'NodeKey -> ed: 'EdgeData -> g: FGraph<'NodeKey,'NodeData,'EdgeData> -> FGraph<'NodeKey,'NodeData,'EdgeData> (requires comparison)
val graphToFillOutput: string
val sprintf: format: Printf.StringFormat<'T> -> 'T
<summary>Print to a string using the given format.</summary>
<param name="format">The formatter.</param>
<returns>The formatted result.</returns>
<example>See <c>Printf.sprintf</c> (link: <see cref="M:Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThen``1" />) for examples.</example>
static member FGraph.countNodes: g: FGraph<'NodeKey,'NodeData,'EdgeData> -> int (requires comparison)
static member FGraph.countEdges: g: FGraph<'NodeKey,'NodeData,'EdgeData> -> int (requires comparison)
val graphToFill': FGraph<int,string,float>
val nodes: (int * string) list
Multiple items
module List
from Microsoft.FSharp.Collections
<summary>Contains operations for working with values of type <see cref="T:Microsoft.FSharp.Collections.list`1" />.</summary>
<namespacedoc><summary>Operations for collections such as lists, arrays, sets, maps and sequences. See also
<a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/fsharp-collection-types">F# Collection Types</a> in the F# Language Guide.
</summary></namespacedoc>
--------------------
type List<'T> =
| op_Nil
| op_ColonColon of Head: 'T * Tail: 'T list
interface IReadOnlyList<'T>
interface IReadOnlyCollection<'T>
interface IEnumerable
interface IEnumerable<'T>
member GetReverseIndex: rank: int * offset: int -> int
member GetSlice: startIndex: int option * endIndex: int option -> 'T list
static member Cons: head: 'T * tail: 'T list -> 'T list
member Head: 'T
member IsEmpty: bool
member Item: index: int -> 'T with get
...
<summary>The type of immutable singly-linked lists.</summary>
<remarks>Use the constructors <c>[]</c> and <c>::</c> (infix) to create values of this type, or
the notation <c>[1;2;3]</c>. Use the values in the <c>List</c> module to manipulate
values of this type, or pattern match against the values directly.
</remarks>
<exclude />
val init: length: int -> initializer: (int -> 'T) -> 'T list
<summary>Creates a list by calling the given generator on each index.</summary>
<param name="length">The length of the list to generate.</param>
<param name="initializer">The function to generate an element from an index.</param>
<exception cref="T:System.ArgumentException">Thrown when the input length is negative.</exception>
<returns>The list of generated elements.</returns>
<example id="init-1"><code lang="fsharp">
List.init 4 (fun v -> v + 5)
</code>
Evaluates to <c>[5; 6; 7; 8]</c></example>
<example id="init-2"><code lang="fsharp">
List.init -5 (fun v -> v + 5)
</code>
Throws <c>ArgumentException</c></example>
val x: int
val edges: (int * int * float) list
static member FGraph.addNodes: nodeSeq: seq<'NodeKey * 'NodeData> -> g: FGraph<'NodeKey,'NodeData,'EdgeData> -> FGraph<'NodeKey,'NodeData,'EdgeData> (requires comparison)
static member FGraph.addEdges: edgeSeq: seq<'NodeKey * 'NodeKey * 'EdgeData> -> g: FGraph<'NodeKey,'NodeData,'EdgeData> -> FGraph<'NodeKey,'NodeData,'EdgeData> (requires comparison)
val graphToFill2Output: string
val graphWithRemovedElements: FGraph<int,string,float>
static member FGraph.removeEdge: nkSource: 'NodeKey -> nkTarget: 'NodeKey -> g: FGraph<'NodeKey,'NodeData,'EdgeData> -> FGraph<'NodeKey,'NodeData,'EdgeData> (requires comparison)
static member FGraph.removeNode: nk: 'NodeKey -> g: FGraph<'NodeKey,'NodeData,'EdgeData> -> FGraph<'NodeKey,'NodeData,'EdgeData> (requires comparison)
val removing: string
namespace FSharpAux
namespace FSharpAux.IO
module SchemaReader
from FSharpAux.IO
module Attribute
from FSharpAux.IO.SchemaReader
<summary>
Attributes to be added to fields of a schema record
</summary>
type MonkeyEdge =
{
Source: int
Target: int
Groomed: int
}
Multiple items
type FieldAttribute =
inherit Attribute
new: indexTag: FieldIndex -> FieldAttribute + 5 overloads
member IndexTag: FieldIndex
<summary>
An attribute to be added to fields of a schema record type to indicate the
column used in the data format for the schema as index
</summary>
--------------------
new: indexTag: SchemaReader.FieldIndex -> FieldAttribute
new: index: int -> FieldAttribute
new: index: string -> FieldAttribute
new: indices: int[] -> FieldAttribute
new: indices: string[] -> FieldAttribute
new: indexFrom: int * indexTo: int -> FieldAttribute
MonkeyEdge.Source: int
Multiple items
val int: value: 'T -> int (requires member op_Explicit)
<summary>Converts the argument to signed 32-bit integer. This is a direct conversion for all
primitive numeric types. For strings, the input is converted using <c>Int32.Parse()</c>
with InvariantCulture settings. Otherwise the operation requires an appropriate
static conversion method on the input type.</summary>
<param name="value">The input value.</param>
<returns>The converted int</returns>
<example id="int-example"><code lang="fsharp"></code></example>
--------------------
[<Struct>]
type int = int32
<summary>An abbreviation for the CLI type <see cref="T:System.Int32" />.</summary>
<category>Basic Types</category>
--------------------
type int<'Measure> =
int
<summary>The type of 32-bit signed integer numbers, annotated with a unit of measure. The unit
of measure is erased in compiled code and when values of this type
are analyzed using reflection. The type is representationally equivalent to
<see cref="T:System.Int32" />.</summary>
<category>Basic Types with Units of Measure</category>
MonkeyEdge.Target: int
MonkeyEdge.Groomed: int
val monkeyEdges: seq<MonkeyEdge>
Multiple items
module Seq
from Microsoft.FSharp.Collections
<summary>Contains operations for working with values of type <see cref="T:Microsoft.FSharp.Collections.seq`1" />.</summary>
--------------------
type Seq =
static member CSV: separator: string -> header: bool -> flatten: bool -> data: seq<'a> -> seq<string>
static member CSVwith: valFunc: ('a -> ('a -> obj)[]) -> strFunc: (string -> bool -> obj -> obj -> string) -> separator: string -> header: bool -> flatten: bool -> data: seq<'a> -> seq<string>
static member fromFile: filePath: string -> seq<string>
static member fromFileWithCsvSchema: filePath: string * separator: char * firstLineHasHeader: bool * ?skipLines: int * ?skipLinesBeforeHeader: int * ?schemaMode: SchemaModes -> seq<'schema>
static member fromFileWithSep: separator: char -> filePath: string -> seq<string[]>
static member stringFunction: separator: string -> flatten: bool -> input: 'a -> (obj -> string)
static member valueFunction: dataEntry: 'a -> ('a -> obj)[]
static member write: path: string -> data: seq<'a> -> unit
static member writeOrAppend: path: string -> data: seq<'a> -> unit
static member Seq.fromFileWithCsvSchema: filePath: string * separator: char * firstLineHasHeader: bool * ?skipLines: int * ?skipLinesBeforeHeader: int * ?schemaMode: SchemaReader.Csv.SchemaModes -> seq<'schema>
val monkeyGraph: FGraph<int,string,float>
val map: mapping: ('T -> 'U) -> source: seq<'T> -> seq<'U>
<summary>Builds a new collection whose elements are the results of applying the given function
to each of the elements of the collection. The given function will be applied
as elements are demanded using the <c>MoveNext</c> method on enumerators retrieved from the
object.</summary>
<remarks>The returned sequence may be passed between threads safely. However,
individual IEnumerator values generated from the returned sequence should not be accessed concurrently.</remarks>
<param name="mapping">A function to transform items from the input sequence.</param>
<param name="source">The input sequence.</param>
<returns>The result sequence.</returns>
<exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
<example id="item-1"><code lang="fsharp">
let inputs = ["a"; "bbb"; "cc"]
inputs |> Seq.map (fun x -> x.Length)
</code>
Evaluates to a sequence yielding the same results as <c>seq { 1; 3; 2 }</c></example>
val mke: MonkeyEdge
Multiple items
val float: value: 'T -> float (requires member op_Explicit)
<summary>Converts the argument to 64-bit float. This is a direct conversion for all
primitive numeric types. For strings, the input is converted using <c>Double.Parse()</c>
with InvariantCulture settings. Otherwise the operation requires an appropriate
static conversion method on the input type.</summary>
<param name="value">The input value.</param>
<returns>The converted float</returns>
<example id="float-example"><code lang="fsharp"></code></example>
--------------------
[<Struct>]
type float = System.Double
<summary>An abbreviation for the CLI type <see cref="T:System.Double" />.</summary>
<category>Basic Types</category>
--------------------
type float<'Measure> =
float
<summary>The type of double-precision floating point numbers, annotated with a unit of measure.
The unit of measure is erased in compiled code and when values of this type
are analyzed using reflection. The type is representationally equivalent to
<see cref="T:System.Double" />.</summary>
<category index="6">Basic Types with Units of Measure</category>
static member FGraph.ofSeq: edgelist: seq<'NodeKey * 'NodeData * 'NodeKey * 'NodeData * 'EdgeData> -> FGraph<'NodeKey,'NodeData,'EdgeData> (requires comparison)
namespace Cytoscape
namespace Cytoscape.NET
val vizGraph: CyGraph.CyGraph
module CyGraph
from Cytoscape.NET
val initEmpty: unit -> CyGraph.CyGraph
val withElements: elems: seq<CytoscapeModel.Element> -> cy: CyGraph.CyGraph -> CyGraph.CyGraph
val sk: int
val s: string
val tk: int
val t: string
val el: float
static member FGraph.toSeq: graph: FGraph<'NodeKey,'NodeData,'EdgeData> -> seq<'NodeKey * 'NodeData * 'NodeKey * 'NodeData * 'EdgeData> (requires comparison)
val sk: string
val tk: string
Multiple items
val string: value: 'T -> string
<summary>Converts the argument to a string using <c>ToString</c>.</summary>
<remarks>For standard integer and floating point values the and any type that implements <c>IFormattable</c><c>ToString</c> conversion uses <c>CultureInfo.InvariantCulture</c>. </remarks>
<param name="value">The input value.</param>
<returns>The converted string.</returns>
<example id="string-example"><code lang="fsharp"></code></example>
--------------------
type string = System.String
<summary>An abbreviation for the CLI type <see cref="T:System.String" />.</summary>
<category>Basic Types</category>
module Elements
from Cytoscape.NET
val node: id: string -> dataAttributes: CyParam.CyStyleParam list -> Elements.Node
module CyParam
from Cytoscape.NET
val label: v: 'a -> CyParam.CyStyleParam
val edge: id: string -> sourceId: string -> targetId: string -> dataAttributes: CyParam.CyStyleParam list -> Elements.Edge
val withStyle: selector: string -> cyStyles: seq<CyParam.CyStyleParam> -> cy: CyGraph.CyGraph -> CyGraph.CyGraph
val content: v: 'a -> CyParam.CyStyleParam
val color: v: 'a -> CyParam.CyStyleParam
val withZoom: zoom: CytoscapeModel.Zoom -> cy: CyGraph.CyGraph -> CyGraph.CyGraph
namespace Cytoscape.NET.CytoscapeModel
Multiple items
type Zoom =
inherit DynamicObj
new: unit -> Zoom
static member Init: ?Level: float * ?Position: (int * int) * ?RenderedPosition: (int * int) * ?ZoomingEnabled: bool -> Zoom
static member Update: ?Level: float * ?Position: (int * int) * ?RenderedPosition: (int * int) * ?ZoomingEnabled: bool -> (Zoom -> Zoom)
--------------------
new: unit -> CytoscapeModel.Zoom
static member CytoscapeModel.Zoom.Init: ?Level: float * ?Position: (int * int) * ?RenderedPosition: (int * int) * ?ZoomingEnabled: bool -> CytoscapeModel.Zoom
val withSize: width: int * height: int -> cy: CyGraph.CyGraph -> CyGraph.CyGraph
type HTML =
static member CreateGraphHTML: graphData: string * zooming: string * divId: string * cytoscapeReference: CytoscapeJSReference * ?Width: int * ?Height: int -> XmlNode list
static member CreateGraphScript: graphData: string * zooming: string * cytoscapeReference: CytoscapeJSReference -> XmlNode
static member Doc: graphHTML: XmlNode list * cytoscapeReference: CytoscapeJSReference * ?AdditionalHeadTags: XmlNode list -> XmlNode
static member show: cy: Cytoscape * ?DisplayOpts: DisplayOptions -> unit
static member toEmbeddedHTML: ?DisplayOpts: DisplayOptions -> (Cytoscape -> string)
static member toGraphHTML: ?DisplayOpts: DisplayOptions -> (Cytoscape -> string)
static member toGraphHTMLNodes: ?DisplayOpts: DisplayOptions -> (Cytoscape -> XmlNode list)
<summary>
HTML template for Cytoscape
</summary>
static member HTML.toGraphHTML: ?DisplayOpts: DisplayOptions -> (CytoscapeModel.Cytoscape -> string)