/** * /// Calculate the epsilon closure */ private static void CalcClosure(Fst fst, State state, Dictionary <State, float>[] cl, Semiring semiring) { var s = state; float pathWeight; var numArcs = s.GetNumArcs(); for (var j = 0; j < numArcs; j++) { var a = s.GetArc(j); if ((a.Ilabel == 0) && (a.Olabel == 0)) { if (cl[a.NextState.GetId()] == null) { CalcClosure(fst, a.NextState, cl, semiring); } if (cl[a.NextState.GetId()] != null) { foreach (var pathFinalState in cl[a.NextState.GetId()].Keys) { pathWeight = semiring.Times( GetPathWeight(a.NextState, pathFinalState, cl), a.Weight); Add(state, pathFinalState, pathWeight, cl, semiring); } } Add(state, a.NextState, a.Weight, cl, semiring); } } }
public int Compare(Pair <State, float> o1, Pair <State, float> o2) { float previous = o1.GetRight(); float d1 = _distance[o1.GetLeft().GetId()]; float next = o2.GetRight(); float d2 = _distance[o2.GetLeft().GetId()]; float a1 = _semiring.Times(next, d2); float a2 = _semiring.Times(previous, d1); if (_semiring.NaturalLess(a1, a2)) { return(1); } if (a1 == a2) { return(0); } return(-1); }
/** * /// Determinizes an fst. The result will be an equivalent fst that has the * /// property that no state has two transitions with the same input label. For * /// this algorithm, epsilon transitions are treated as regular symbols. * /// * /// @param fst the fst to determinize * /// @return the determinized fst */ public static Fst Get(Fst fst) { if (fst.Semiring == null) { // semiring not provided return(null); } // initialize the queue and new fst Semiring semiring = fst.Semiring; Fst res = new Fst(semiring); res.Isyms = fst.Isyms; res.Osyms = fst.Osyms; // stores the queue (item in index 0 is next) Queue <List <Pair <State, float> > > queue = new Queue <List <Pair <State, float> > >(); Dictionary <String, State> stateMapper = new Dictionary <String, State>(); State s = new State(semiring.Zero); string stateString = "(" + fst.Start + "," + semiring.One + ")"; queue.Enqueue(new List <Pair <State, float> >()); queue.Peek().Add(new Pair <State, float>(fst.Start, semiring.One)); res.AddState(s); stateMapper.Add(stateString, s); res.SetStart(s); while (queue.Count != 0) { List <Pair <State, float> > p = queue.Dequeue(); State pnew = GetStateLabel(p, stateMapper); //queueRemoveAt(0); List <int> labels = GetUniqueLabels(fst, p); foreach (int label in labels) { float wnew = semiring.Zero; // calc w' foreach (Pair <State, float> ps in p) { State old = ps.GetLeft(); float u = ps.GetRight(); int numArcs = old.GetNumArcs(); for (int j = 0; j < numArcs; j++) { Arc arc = old.GetArc(j); if (label == arc.Ilabel) { wnew = semiring.Plus(wnew, semiring.Times(u, arc.Weight)); } } } // calc new states // keep residual weights to variable forQueue List <Pair <State, float> > forQueue = new List <Pair <State, float> >(); foreach (Pair <State, float> ps in p) { State old = ps.GetLeft(); float u = ps.GetRight(); float wnewRevert = semiring.Divide(semiring.One, wnew); int numArcs = old.GetNumArcs(); for (int j = 0; j < numArcs; j++) { Arc arc = old.GetArc(j); if (label == arc.Ilabel) { State oldstate = arc.NextState; Pair <State, float> pair = GetPair(forQueue, oldstate, semiring.Zero); pair.SetRight(semiring.Plus( pair.GetRight(), semiring.Times(wnewRevert, semiring.Times(u, arc.Weight)))); } } } // build new state's id and new elements for queue string qnewid = ""; foreach (Pair <State, float> ps in forQueue) { State old = ps.GetLeft(); float unew = ps.GetRight(); if (!qnewid.Equals("")) { qnewid = qnewid + ","; } qnewid = qnewid + "(" + old + "," + unew + ")"; } if (stateMapper.Get(qnewid) == null) { State qnew = new State(semiring.Zero); res.AddState(qnew); stateMapper.Add(qnewid, qnew); // update new state's weight float fw = qnew.FinalWeight; foreach (Pair <State, float> ps in forQueue) { fw = semiring.Plus(fw, semiring.Times(ps.GetLeft().FinalWeight, ps.GetRight())); } qnew.FinalWeight = fw; queue.Enqueue(forQueue); } pnew.AddArc(new Arc(label, label, wnew, stateMapper[qnewid])); } } return(res); }
/** * /// Computes the composition of two Fsts. Assuming no epsilon transitions. * /// * /// Input Fsts are not modified. * /// * /// @param fst1 the first Fst * /// @param fst2 the second Fst * /// @param semiring the semiring to use in the operation * /// @param sorted * /// @return the composed Fst */ public static Fst compose(Fst fst1, Fst fst2, Semiring semiring, Boolean sorted) { if (!Arrays.AreEqual(fst1.Osyms, fst2.Isyms)) { // symboltables do not match return(null); } Fst res = new Fst(semiring); Dictionary <Pair <State, State>, State> stateMap = new Dictionary <Pair <State, State>, State>(); Queue <Pair <State, State> > queue = new Queue <Pair <State, State> >(); State s1 = fst1.Start; State s2 = fst2.Start; if ((s1 == null) || (s2 == null)) { Logger.LogInfo <Compose>("Cannot find initial state."); return(null); } Pair <State, State> p = new Pair <State, State>(s1, s2); State s = new State(semiring.Times(s1.FinalWeight, s2.FinalWeight)); res.AddState(s); res.SetStart(s); if (stateMap.ContainsKey(p)) { stateMap[p] = s; } else { stateMap.Add(p, s); } queue.Enqueue(p); while (queue.Count != 0) { p = queue.Dequeue(); s1 = p.GetLeft(); s2 = p.GetRight(); s = stateMap[p]; int numArcs1 = s1.GetNumArcs(); int numArcs2 = s2.GetNumArcs(); for (int i = 0; i < numArcs1; i++) { Arc a1 = s1.GetArc(i); for (int j = 0; j < numArcs2; j++) { Arc a2 = s2.GetArc(j); if (sorted && a1.Olabel < a2.Ilabel) { break; } if (a1.Olabel == a2.Ilabel) { State nextState1 = a1.NextState; State nextState2 = a2.NextState; Pair <State, State> nextPair = new Pair <State, State>( nextState1, nextState2); State nextState = stateMap.Get(nextPair); if (nextState == null) { nextState = new State(semiring.Times( nextState1.FinalWeight, nextState2.FinalWeight)); res.AddState(nextState); if (stateMap.ContainsKey(nextPair)) { stateMap[nextPair] = nextState; } else { stateMap.Add(nextPair, nextState); } queue.Enqueue(nextPair); } Arc a = new Arc(a1.Ilabel, a2.Olabel, semiring.Times(a1.Weight, a2.Weight), nextState); s.AddArc(a); } } } } res.Isyms = fst1.Isyms; res.Osyms = fst2.Osyms; return(res); }