/// <summary>
/// This looks at the transition from state pair
/// (f1,f2) -> (t1,t2), withthe given cost.
/// </summary>
public void Relax(int f1, int f2, // input state pair
int t1, int t2, // output state pair
float cost, // transition cost
int arc_id1, // (unused)
int arc_id2, // (unused)
int input, // input label
int intermediate, // (unused)
int output, // output label
float base_cost, // cost of the path so far
int trail_index)
{
//logger.format("relaxing %d %d -> %d %d (bcost %f, cost %f)", f1, f2, t1, t2, base_cost, cost);
if (!nbest.AddReplacingId(t1 * fst2.nStates() + t2,
all_costs.Length(),
-base_cost - cost))
{
return;
}
//logger.format("nbest changed");
//nbest.log(logger);
if (input > 0)
{
// The candidate for the next beam is stored in all_XX arrays.
// (can we store it in the stree instead?)
all_inputs.Push(input);
all_targets1.Push(t1);
all_targets2.Push(t2);
all_outputs.Push(output);
all_costs.Push(cost);
parent_trails.Push(trail_index);
}
else
{
// Beam control hack
// -----------------
// if a node is important (changes nbest) AND its input is 0,
// then it's added to the CURRENT beam.
//logger.format("pushing control point from trail %d to %d, %d",
//trail_index, t1, t2);
int new_node = stree.Add(beam[trail_index], t1, t2, input, output, (float)cost);
beam.Push(new_node);
beamcost.Push(base_cost + cost);
// This is a stub entry indicating that the node should not
// be added to the next generation beam.
all_inputs.Push(0);
all_targets1.Push(-1);
all_targets2.Push(-1);
all_outputs.Push(0);
all_costs.Push(0);
parent_trails.Push(-1);
}
}