/// <summary> /// Copy one FST to another. /// </summary> /// <param name="dst">The destination. Will be cleared before copying.</param> /// <param name="src">The FST to copy.</param> public static void fst_copy(IGenericFst dst, IGenericFst src) { dst.Clear(); int n = src.nStates(); for (int i = 0; i < n; i++) { dst.NewState(); } dst.SetStart(src.GetStart()); for (int i = 0; i < n; i++) { dst.SetAccept(i, src.GetAcceptCost(i)); Intarray targets = new Intarray(), outputs = new Intarray(), inputs = new Intarray(); Floatarray costs = new Floatarray(); src.Arcs(inputs, targets, outputs, costs, i); int inlen = inputs.Length(); if (inlen != targets.Length()) { throw new Exception("ASSERT: inputs.length() == targets.length()"); } if (inlen != outputs.Length()) { throw new Exception("ASSERT: inputs.length() == outputs.length()"); } if (inlen != costs.Length()) { throw new Exception("ASSERT: inputs.length() == costs.length()"); } for (int j = 0; j < inputs.Length(); j++) { dst.AddTransition(i, targets.At1d(j), outputs.At1d(j), costs.At1d(j), inputs.At1d(j)); } } }
/// <summary> /// Copy one FST to another, preserving only lowest-cost arcs. /// This is useful for visualization. /// </summary> /// <param name="dst">The destination. Will be cleared before copying.</param> /// <param name="src">The FST to copy.</param> public static void fst_copy_best_arcs_only(IGenericFst dst, IGenericFst src) { dst.Clear(); int n = src.nStates(); for (int i = 0; i < n; i++) { dst.NewState(); } dst.SetStart(src.GetStart()); for (int i = 0; i < n; i++) { dst.SetAccept(i, src.GetAcceptCost(i)); Intarray targets = new Intarray(), outputs = new Intarray(), inputs = new Intarray(); Floatarray costs = new Floatarray(); src.Arcs(inputs, targets, outputs, costs, i); int inlen = inputs.Length(); if (inlen != targets.Length()) { throw new Exception("ASSERT: inputs.length() == targets.length()"); } if (inlen != outputs.Length()) { throw new Exception("ASSERT: inputs.length() == outputs.length()"); } if (inlen != costs.Length()) { throw new Exception("ASSERT: inputs.length() == costs.length()"); } Dictionary <int, int> hash = new Dictionary <int, int>(); for (int j = 0; j < n; j++) { int t = targets[j]; int best_so_far = -1; if (hash.ContainsKey(t)) { best_so_far = hash[t]; } if (best_so_far == -1 || costs[j] < costs[best_so_far]) { hash[t] = j; } } Intarray keys = new Intarray(); //hash.keys(keys); keys.Clear(); foreach (int key in hash.Keys) { keys.Push(key); } for (int k = 0; k < keys.Length(); k++) { int j = hash[keys[k]]; dst.AddTransition(i, targets[j], outputs[j], costs[j], inputs[j]); } } }
/// <summary> /// Reverse the FST's arcs, adding a new start vertex (former accept). /// </summary> public static void fst_copy_reverse(IGenericFst dst, IGenericFst src, bool no_accept = false) { dst.Clear(); int n = src.nStates(); for (int i = 0; i <= n; i++) { dst.NewState(); } if (!no_accept) { dst.SetAccept(src.GetStart()); } dst.SetStart(n); for (int i = 0; i < n; i++) { dst.AddTransition(n, i, 0, src.GetAcceptCost(i), 0); Intarray targets = new Intarray(), outputs = new Intarray(), inputs = new Intarray(); Floatarray costs = new Floatarray(); src.Arcs(inputs, targets, outputs, costs, i); if (inputs.Length() != targets.Length()) { throw new Exception("ASSERT: inputs.length() == targets.length()"); } if (inputs.Length() != outputs.Length()) { throw new Exception("ASSERT: inputs.length() == outputs.length()"); } if (inputs.Length() != costs.Length()) { throw new Exception("ASSERT: inputs.length() == costs.length()"); } for (int j = 0; j < inputs.Length(); j++) { dst.AddTransition(targets.At1d(j), i, outputs.At1d(j), costs.At1d(j), inputs.At1d(j)); } } }
protected static void read_node(BinaryReader reader, IGenericFst fst, int index) { fst.SetAccept(index, read_float(reader)); Int64 narcs = read_int64_LE(reader); for (int i = 0; i < narcs; i++) { int input = read_int32_LE(reader); int output = read_int32_LE(reader); float cost = read_float(reader); int target = read_int32_LE(reader); fst.AddTransition(index, target, output, cost, input); } }
/// <summary> /// Make an in-place Kleene closure of the FST. /// </summary> public static void fst_star(IGenericFst fst) { int s = fst.GetStart(); fst.SetAccept(s); for (int i = 0; i < fst.nStates(); i++) { double c = fst.GetAcceptCost(i); if (c < 1e37) { fst.AddTransition(i, s, 0, (float)c, 0); } } }
/// <summary> /// Output the segmentation into a segmentation graph. /// Construct a state for each of the segments, then /// add transitions between states (segments) /// from min(segments[i]) to max(segments[i])+1. /// </summary> public override void GetLattice(IGenericFst fst) { fst.Clear(); int final = NarrayUtil.Max(labels) + 1; Intarray states = new Intarray(final + 1); states.Fill(-1); for (int i = 1; i < states.Length(); i++) { states[i] = fst.NewState(); } fst.SetStart(states[1]); fst.SetAccept(states[final]); for (int i = 0; i < boxes.Length(); i++) { int start = NarrayUtil.Min(segments.At1d(i)); int end = NarrayUtil.Max(segments.At1d(i)); int id = (start << 16) + end; if (segments.At1d(i).Length() == 0) { id = 0; } float yes = spaces[i, 0]; float no = spaces[i, 1]; // if no space is set, assume no space is present if (yes == float.PositiveInfinity && no == float.PositiveInfinity) { no = 0.0f; } for (int j = 0; j < class_costs[i].Length(); j++) { float cost = class_costs[i][j]; string str = class_outputs[i][j]; int n = str.Length; int last = start; for (int k = 0; k < n; k++) { int c = (int)str[k]; if (k < n - 1) { // add intermediate states/transitions for all but the last character states.Push(fst.NewState()); fst.AddTransition(states[last], states.Last(), c, 0.0f, 0); last = states.Length() - 1; } else { // for the last character, handle the spaces as well if (no < 1000.0f) { // add the last character as a direct transition with no space fst.AddTransition(states[last], states[end + 1], c, cost + no, id); } if (yes < 1000.0f) { // insert another state to handle spaces states.Push(fst.NewState()); int space_state = states.Last(); fst.AddTransition(states[start], space_state, c, cost, id); fst.AddTransition(space_state, states[end + 1], (int)' ', yes, 0); } } } // for k } // for j } // for i }