public static void scale_fst(OcroFST fst, float scale) { if (Math.Abs(scale - 1.0f) < 1e-6f) { return; } for (int i = 0; i < fst.nStates(); i++) { Floatarray cost = fst.Costs(i); cost *= scale; float accept = fst.AcceptCost(i); if (accept >= 0.0f && accept < 1e37f) { fst.SetAcceptCost(i, accept * scale); } } }
/// <summary> /// Call relax() for each arc going out of the given node. /// </summary> public void Traverse(int n1, int n2, float cost, int trail_index) { //logger.format("traversing %d %d", n1, n2); Intarray o1 = fst1.Outputs(n1); Intarray i1 = fst1.Inputs(n1); Intarray t1 = fst1.Targets(n1); Floatarray c1 = fst1.Costs(n1); Intarray o2 = fst2.Outputs(n2); Intarray i2 = fst2.Inputs(n2); Intarray t2 = fst2.Targets(n2); Floatarray c2 = fst2.Costs(n2); // for optimization int[] O1 = o1.data; int[] O2 = o2.data; int[] I1 = i1.data; int[] I2 = i2.data; int[] T1 = t1.data; int[] T2 = t2.data; float[] C1 = c1.data; float[] C2 = c2.data; // Relax outbound arcs in the composition int k1, k2; // relaxing fst1 RHO moves // these can be rho->rho or x->rho moves for (k1 = 0; k1 < o1.Length() && O1[k1] == FstUtil.L_RHO; k1++) { for (int j = 0; j < o2.Length(); j++) { if (I2[j] <= FstUtil.L_EPSILON) { continue; } // if it's rho->rho, then pick up the label, // if it's x->rho leave it alone int inn = I1[k1] == FstUtil.L_RHO ? I2[j] : I1[k1]; Relax(n1, n2, // from pair T1[k1], T2[j], // to pair C1[k1] + C2[j], // cost k1, j, // arc ids inn, I2[j], O2[j], // input, intermediate, output cost, trail_index); } } // relaxing fst2 RHO moves // these can be rho->rho or rho->x moves for (k2 = 0; k2 < o2.Length() && I2[k2] == FstUtil.L_RHO; k2++) { for (int j = 0; j < o1.Length(); j++) { if (O1[j] <= FstUtil.L_EPSILON) { continue; } // if it's rho->rho, then pick up the label, // if it's rho->x leave it alone int outn = O2[k2] == FstUtil.L_RHO ? O1[j] : O2[k2]; Relax(n1, n2, // from pair T1[j], T2[k2], // to pair C1[j] + C2[k2], // cost j, k2, // arc ids I1[j], O1[j], outn, // input, intermediate, output cost, trail_index); } } // relaxing fst1 EPSILON moves for (k1 = 0; k1 < o1.Length() && O1[k1] == FstUtil.L_EPSILON; k1++) { Relax(n1, n2, // from pair T1[k1], n2, // to pair C1[k1], // cost k1, -1, // arc ids I1[k1], 0, 0, // input, intermediate, output cost, trail_index); } // relaxing fst2 EPSILON moves for (k2 = 0; k2 < o2.Length() && I2[k2] == FstUtil.L_EPSILON; k2++) { Relax(n1, n2, // from pair n1, T2[k2], // to pair C2[k2], // cost -1, k2, // arc ids 0, 0, O2[k2], // input, intermediate, output cost, trail_index); } // relaxing non-epsilon moves while (k1 < o1.Length() && k2 < i2.Length()) { while (k1 < o1.Length() && O1[k1] < I2[k2]) { k1++; } if (k1 >= o1.Length()) { break; } while (k2 < i2.Length() && O1[k1] > I2[k2]) { k2++; } while (k1 < o1.Length() && k2 < i2.Length() && O1[k1] == I2[k2]) { for (int j = k2; j < i2.Length() && O1[k1] == I2[j]; j++) { Relax(n1, n2, // from pair T1[k1], T2[j], // to pair C1[k1] + C2[j], // cost k1, j, // arc ids I1[k1], O1[k1], O2[j], // input, intermediate, output cost, trail_index); } k1++; } } }
public static void scale_fst(OcroFST fst, float scale) { if(Math.Abs(scale-1.0f)<1e-6f) return; for (int i = 0; i < fst.nStates(); i++) { Floatarray cost = fst.Costs(i); cost *= scale; float accept = fst.AcceptCost(i); if (accept >= 0.0f && accept < 1e37f) fst.SetAcceptCost(i, accept * scale); } }