Skip to content

Commit 04e52a6

Browse files
authored
add rcgraph (#220)
1 parent 710d0da commit 04e52a6

File tree

1 file changed

+79
-4
lines changed

1 file changed

+79
-4
lines changed

source/mir/graph/package.d

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ module mir.graph;
1414

1515
import mir.math.common: optmath;
1616

17-
@optmath:
18-
1917
import mir.series;
2018
import mir.rc.array;
2119
import mir.ndslice.iterator: ChopIterator;
@@ -34,13 +32,20 @@ alias RCGraph(I = uint, J = size_t) = Slice!(RCGraphIterator!(I, J));
3432
///
3533
alias 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
4044
Returns:
4145
A graph series composed of keys (sorted `.index`) and arrays of indeces (`.data`)
4246
Complexity: `O(log(V) (V + E))`
4347
+/
48+
@optmath
4449
GraphSeries!(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

Comments
 (0)