/// <summary>Takes time linear in number of arcs.</summary> public virtual TransducerGraph PushLambdas(TransducerGraph graph, ClassicCounter lambda) { TransducerGraph result = null; result = graph.Clone(); // arcs have been copied too so we don't mess up graph ICollection <TransducerGraph.Arc> arcs = result.GetArcs(); foreach (TransducerGraph.Arc arc in arcs) { double sourceLambda = lambda.GetCount(arc.GetSourceNode()); double targetLambda = lambda.GetCount(arc.GetTargetNode()); double oldOutput = ((double)arc.GetOutput()); double newOutput = oldOutput + targetLambda - sourceLambda; arc.SetOutput(newOutput); } // do initialOutput double startLambda = lambda.GetCount(result.GetStartNode()); if (startLambda != 0.0) { // add it back to the outbound arcs from start (instead of adding it to the initialOutput) ICollection <TransducerGraph.Arc> startArcs = result.GetArcsBySource(result.GetStartNode()); foreach (TransducerGraph.Arc arc_1 in startArcs) { double oldOutput = ((double)arc_1.GetOutput()); double newOutput = oldOutput + startLambda; arc_1.SetOutput(newOutput); } } // do finalOutput foreach (object o in result.GetEndNodes()) { double endLambda = lambda.GetCount(o); if (endLambda != 0.0) { // subtract it from the inbound arcs to end (instead of subtracting it from the finalOutput) ICollection <TransducerGraph.Arc> endArcs = result.GetArcsByTarget(o); foreach (TransducerGraph.Arc arc_1 in endArcs) { double oldOutput = ((double)arc_1.GetOutput()); double newOutput = oldOutput - endLambda; arc_1.SetOutput(newOutput); } } } return(result); }