@@ -14,8 +14,6 @@ module mir.graph;
1414
1515import mir.math.common: optmath;
1616
17- @optmath:
18-
1917import mir.series;
2018import mir.rc.array;
2119import mir.ndslice.iterator: ChopIterator;
@@ -34,13 +32,20 @@ alias RCGraph(I = uint, J = size_t) = Slice!(RCGraphIterator!(I, J));
3432// /
3533alias RCGraphSeries (T, I = uint , J = size_t ) = Series! (RCI ! T, RCGraphIterator! (I, J));
3634
35+ private static immutable exc_msg = " graphSeries: graph should contains keys for all vertixes" ;
36+ version (D_Exceptions)
37+ {
38+ private static immutable exception = new Exception (exc_msg);
39+ }
40+
3741/+ +
38- Param :
42+ Params :
3943 aaGraph = graph that is represented as associative array
4044Returns:
4145 A graph series composed of keys (sorted `.index`) and arrays of indeces (`.data`)
4246Complexity: `O(log(V) (V + E))`
4347+/
48+ @optmath
4449GraphSeries! (T, I, J) graphSeries(I = uint , J = size_t , T, Range )(in Range [T] aaGraph)
4550{
4651 import mir.array.allocation: array;
@@ -62,7 +67,13 @@ GraphSeries!(T, I, J) graphSeries(I = uint, J = size_t, T, Range)(in Range[T] aa
6267 {
6368 import mir.ndslice.sorting: transitionIndex;
6469 auto index = keys .transitionIndex(elem);
65- assert (index < keys .length, " graphSeries: aaGraph should contains keys for all vertixes" );
70+ if (index >= keys .length)
71+ {
72+ version (D_Exceptions)
73+ throw exception;
74+ else
75+ assert (0 , exc_msg);
76+ }
6677 data[dataIndex++ ] = cast (I) index;
6778 }
6879 }
@@ -87,3 +98,67 @@ pure version(mir_test) unittest
8798 [1 ], // c
8899 ]);
89100}
101+
102+ /+ +
103+ Params:
104+ graph = graph that is represented a series
105+ Returns:
106+ A graph as an arrays of indeces
107+ Complexity: `O(log(V) (V + E))`
108+ +/
109+ @optmath
110+ RCGraph! (I, J) rcgraph(I = uint , J = size_t , KeyIterator, RangeIterator)(Series! (KeyIterator, RangeIterator) graph)
111+ {
112+ import mir.array.allocation: array;
113+ import mir.ndslice.sorting;
114+ import mir.ndslice;
115+ auto scopeGraph = graph.lightScope;
116+ auto keys = scopeGraph.index;
117+ auto graphData = scopeGraph.data;
118+ size_t dataLength;
119+ foreach (ref v; graphData)
120+ dataLength += v.length;
121+ auto data = rcslice! I(dataLength);
122+ auto components = rcslice! J(keys .length + 1 );
123+ size_t dataIndex;
124+
125+ foreach (i; 0 .. keys .length)
126+ {
127+ components[i] = cast (J) dataIndex;
128+ foreach (ref elem; graphData[i])
129+ {
130+ import mir.ndslice.sorting: transitionIndex;
131+ auto index = keys .transitionIndex(elem);
132+ if (index >= keys .length)
133+ {
134+ version (D_Exceptions)
135+ throw exception;
136+ else
137+ assert (0 , exc_msg);
138+ }
139+ data[dataIndex++ ] = cast (I) index;
140+ }
141+ }
142+ components[keys .length] = dataIndex;
143+ return data._iterator.chopped(components);
144+ }
145+
146+ // /
147+ @safe pure @nogc version(mir_test)
148+ unittest
149+ {
150+ static immutable keys = [" a" , " b" , " c" ];
151+ static immutable data = [
152+ [" b" , " c" ],
153+ [" a" ],
154+ [" b" ],
155+ ];
156+
157+ static immutable graphValue = [
158+ [1 , 2 ], // a
159+ [0 ], // b
160+ [1 ], // c
161+ ];
162+
163+ assert (series(keys , data).rcgraph == graphValue);
164+ }
0 commit comments