(* Electrical synapses graph structure *) signature NODE_GRAPH = sig type index = int type rangemap = {localStart: int, localEnd: int, globalStart: int} list val nodeGraph : (string * SparseMatrix.matrix * rangemap) -> (index, real, unit) Graph.graph val junctionMatrix : ((index, real, unit) Graph.graph) -> SparseMatrix.matrix end structure NodeGraph: NODE_GRAPH = struct type index = int type rangemap = {localStart: int, localEnd: int, globalStart: int} list exception Index fun nodeGraph (modelname, S, rangemap) = let fun mapIndex m i = case List.find (fn {localStart,localEnd,globalStart} => (i >= localStart andalso i < localEnd)) m of SOME ({localStart,localEnd,globalStart}) => globalStart + (i-localStart) | NONE => raise Index val [N,_] = SparseMatrix.shape S val G as Graph.GRAPH g = DirectedGraph.graph(modelname,(),N) : (index,real,unit) Graph.graph val idxs = List.tabulate (N, fn (i) => i) val gidxs = List.tabulate (N, fn (i) => mapIndex rangemap i) val _ = ListPair.app (#add_node g) (gidxs,idxs) val add_edge = #add_edge g val _ = List.app (fn (s) => let val sl = SparseMatrix.slice (S,1,s) in SparseMatrix.sliceAppi (fn (t,v) => add_edge (mapIndex rangemap s, mapIndex rangemap t,v)) sl end) idxs in G end fun junctionMatrix (Graph.GRAPH g) = let fun nodeCoeffs n = let val out = (#out_edges g) n val self = Real.- (~1.0, foldl (fn ((s,t,v),ax) => Real.+(v,ax)) 0.0 out) in (n, (n,self) :: (map (fn (s,t,v) => (t,v)) out)) end val lst = ref [] in ((#forall_nodes g) (fn (n,_) => (lst := ((nodeCoeffs n) :: !lst))); SparseMatrix.fromLists (!lst)) end end