public override void Arcs(Intarray ids, Intarray targets, Intarray outputs, Floatarray costs, int node)
{
int n1 = node / l2.nStates();
int n2 = node % l2.nStates();
Intarray ids1 = new Intarray();
Intarray ids2 = new Intarray();
Intarray t1 = new Intarray();
Intarray t2 = new Intarray();
Intarray o1 = new Intarray();
Intarray o2 = new Intarray();
Floatarray c1 = new Floatarray();
Floatarray c2 = new Floatarray();
l1.Arcs(ids1, t1, o1, c1, n1);
l2.Arcs(ids2, t2, o2, c2, n2);
// sort & permute
Intarray p1 = new Intarray();
Intarray p2 = new Intarray();
NarrayUtil.Quicksort(p1, o1);
NarrayUtil.Permute(ids1, p1);
NarrayUtil.Permute(t1, p1);
NarrayUtil.Permute(o1, p1);
NarrayUtil.Permute(c1, p1);
NarrayUtil.Quicksort(p2, ids2);
NarrayUtil.Permute(ids2, p2);
NarrayUtil.Permute(t2, p2);
NarrayUtil.Permute(o2, p2);
NarrayUtil.Permute(c2, p2);
int k1, k2;
// l1 epsilon moves
for (k1 = 0; k1 < o1.Length() && o1.At1d(k1) == 0; k1++)
{
ids.Push(ids1.At1d(k1));
targets.Push(Combine(t1.At1d(k1), n2));
outputs.Push(0);
costs.Push(c1.At1d(k1));
}
// l2 epsilon moves
for (k2 = 0; k2 < o2.Length() && ids2.At1d(k2) == 0; k2++)
{
ids.Push(0);
targets.Push(Combine(n1, t2.At1d(k2)));
outputs.Push(o2.At1d(k2));
costs.Push(c2.At1d(k2));
}
// non-epsilon moves
while (k1 < o1.Length() && k2 < ids2.Length())
{
while (k1 < o1.Length() && o1.At1d(k1) < ids2.At1d(k2)) k1++;
if (k1 >= o1.Length()) break;
while (k2 < ids2.Length() && o1.At1d(k1) > ids2.At1d(k2)) k2++;
while (k1 < o1.Length() && k2 < ids2.Length() && o1.At1d(k1) == ids2.At1d(k2))
{
for (int j = k2; j < ids2.Length() && o1.At1d(k1) == ids2.At1d(j); j++)
{
ids.Push(ids1.At1d(k1));
targets.Push(Combine(t1.At1d(k1), t2.At1d(j)));
outputs.Push(o2.At1d(j));
costs.Push(c1.At1d(k1) + c2.At1d(j));
}
k1++;
}
}
}