/** * Add a state in the epsilon closure */ private static void add(State fromState, State toState, float weight, HashMap<State, Float>[] cl, Semiring semiring) { Float old = getPathWeight(fromState, toState, cl); if (old == null) { put(fromState, toState, weight, cl); } else { put(fromState, toState, semiring.plus(weight, old), cl); } }
Fst efst = entryToFSA(entry); Semiring s = efst.getSemiring(); Compose.augment(1, efst, s); ArcSort.apply(efst, new OLabelCompare()); Fst result = Compose.compose(efst, epsilonFilter, s, true); ArcSort.apply(result, new OLabelCompare()); result = Compose.compose(result, g2pmodel, s, true); Project.apply(result, ProjectType.OUTPUT); if (nbest == 1) { result = NShortestPaths.get(result, 1, false); } else { result = NShortestPaths.get(result, nbest * 10, false); result = RmEpsilon.get(result); ArrayList<Path> paths = findAllPaths(result, nbest, skipSeqs, tie);
/** * Initialize the decoder */ private void init() { skipSeqs.add(eps); skipSeqs.add(sb); skipSeqs.add(se); skipSeqs.add(skip); skipSeqs.add("-"); // keep an augmented copy (for compose) Compose.augment(0, g2pmodel, g2pmodel.getSemiring()); ArcSort.apply(g2pmodel, new ILabelCompare()); String[] isyms = g2pmodel.getIsyms(); loadClusters(isyms); // get epsilon filter for composition epsilonFilter = Compose.getFilter(g2pmodel.getIsyms(), g2pmodel.getSemiring()); ArcSort.apply(epsilonFilter, new ILabelCompare()); }
@Test public void testArcSort() { // Input label sort test Fst fst1 = createUnsorted(); Fst fst2 = createIsorted(); assertThat(fst1, not(equalTo(fst2))); apply(fst1, new ILabelCompare()); assertThat(fst1, equalTo(fst2)); // Output label sort test fst1 = createUnsorted(); fst2 = createOsorted(); assertThat(fst1, not(equalTo(fst2))); apply(fst1, new OLabelCompare()); assertThat(fst1, equalTo(fst2)); }
/** * Computes the composition of two Fsts. The two Fsts are augmented in order * to avoid multiple epsilon paths in the resulting Fst * * @param fst1 the first Fst * @param fst2 the second Fst * @param semiring the semiring to use in the operation * @return the composed Fst */ public static Fst get(Fst fst1, Fst fst2, Semiring semiring) { if ((fst1 == null) || (fst2 == null)) { return null; } if (!Arrays.equals(fst1.getOsyms(), fst2.getIsyms())) { // symboltables do not match return null; } Fst filter = getFilter(fst1.getOsyms(), semiring); augment(1, fst1, semiring); augment(0, fst2, semiring); Fst tmp = Compose.compose(fst1, filter, semiring, false); Fst res = Compose.compose(tmp, fst2, semiring, false); // Connect.apply(res); return res; }
fstdet = Determinize.get(fst); res.setOsyms(fstdet.getOsyms()); final float[] d = shortestDistance(fstdet); ExtendFinal.apply(fstdet);
calcClosure(fst, s, cl, semiring); if (s1.getFinalWeight() != semiring.zero()) { s.setFinalWeight(semiring.plus(s.getFinalWeight(), semiring.times(getPathWeight(oldState, s1, cl), s1.getFinalWeight()))); Arc newArc = new Arc(a.getIlabel(), a.getOlabel(), semiring.times(a.getWeight(), getPathWeight(oldState, s1, cl)), oldToNewStateMap[a.getNextState().getId()]); s.addArc(newArc); res.setOsyms(fst.getOsyms()); Connect.apply(res);
/** * Calculate the epsilon closure */ private static void calcClosure(Fst fst, State state, HashMap<State, Float>[] cl, Semiring semiring) { State s = state; float pathWeight; int numArcs = s.getNumArcs(); for (int j = 0; j < numArcs; j++) { Arc a = s.getArc(j); if ((a.getIlabel() == 0) && (a.getOlabel() == 0)) { if (cl[a.getNextState().getId()] == null) { calcClosure(fst, a.getNextState(), cl, semiring); } if (cl[a.getNextState().getId()] != null) { for (State pathFinalState : cl[a.getNextState().getId()] .keySet()) { pathWeight = semiring.times( getPathWeight(a.getNextState(), pathFinalState, cl), a.getWeight()); add(state, pathFinalState, pathWeight, cl, semiring); } } add(state, a.getNextState(), a.getWeight(), cl, semiring); } } }
/** * Initialization of a depth first search recursion */ private static void depthFirstSearch(Fst fst, HashSet<State> accessible, ArrayList<ArrayList<State>> paths, ArrayList<Arc>[] exploredArcs, HashSet<State> coaccessible) { State currentState = fst.getStart(); State nextState = currentState; do { if (!accessible.contains(currentState)) { nextState = depthFirstSearchNext(fst, currentState, paths, exploredArcs, accessible); } } while (currentState.getId() != nextState.getId()); int numStates = fst.getNumStates(); for (int i = 0; i < numStates; i++) { State s = fst.getState(i); if (s.getFinalWeight() != fst.getSemiring().zero()) { calcCoAccessible(fst, s, paths, coaccessible); } } }
@Test public void testProject() { System.out.println("Testing Project..."); // Project on Input label Fst fst = createFst(); Fst p = createPi(); Project.apply(fst, ProjectType.INPUT); Assert.assertTrue(fst.equals(p)); // Project on Output label fst = createFst(); p = createPo(); Project.apply(fst, ProjectType.OUTPUT); Assert.assertTrue(fst.equals(p)); System.out.println("Testing Project Completed!\n"); }
@Test public void testConnect() throws NumberFormatException, IOException, ClassNotFoundException, URISyntaxException { String path = "algorithms/connect/fstconnect.fst.ser"; URL url = getClass().getResource(path); File parent = new File(url.toURI()).getParentFile(); path = new File(parent, "A").getPath(); Fst fst = importFst(path, new TropicalSemiring()); path = new File(parent, "fstconnect.fst.ser").getPath(); Fst connectSaved = Fst.loadModel(path); apply(fst); assertThat(connectSaved, equalTo(fst)); }
@Test public void testRmEpsilon() throws NumberFormatException, IOException, ClassNotFoundException, URISyntaxException { URL url = getClass().getResource("algorithms/rmepsilon/A.fst.txt"); File parent = new File(url.toURI()).getParentFile(); String path = new File(parent, "A").getPath(); Fst fst = Convert.importFst(path, new ProbabilitySemiring()); path = new File(parent, "fstrmepsilon.fst.ser").getPath(); Fst fstRmEps = Fst.loadModel(path); Fst rmEpsilon = RmEpsilon.get(fst); assertThat(fstRmEps, equalTo(rmEpsilon)); } }
@Test public void testNShortestPaths() throws NumberFormatException, IOException, URISyntaxException { String path = "algorithms/shortestpath/A.fst"; URL url = getClass().getResource(path); File parent = new File(url.toURI()).getParentFile(); path = new File(parent, "A").getPath(); Fst fst = importFst(path, new TropicalSemiring()); path = new File(parent, "nsp").getPath(); Fst nsp = importFst(path, new TropicalSemiring()); Fst fstNsp = NShortestPaths.get(fst, 6, true); assertThat(nsp, equalTo(fstNsp)); } }
@Test public void testReverse() throws NumberFormatException, IOException, ClassNotFoundException, URISyntaxException { String path = "algorithms/reverse/A.fst"; URL url = getClass().getResource(path); File parent = new File(url.toURI()).getParentFile(); path = new File(parent, "A").getPath(); Fst fst = Convert.importFst(path, new TropicalSemiring()); path = new File(parent, "fstreverse.fst.ser").getPath(); Fst fstB = Fst.loadModel(path); Fst fstReversed = Reverse.get(fst); assertThat(fstB, equalTo(fstReversed)); }
@Test public void testDeterminize() throws NumberFormatException, IOException, ClassNotFoundException, URISyntaxException { String path = "algorithms/determinize/fstdeterminize.fst.ser"; URL url = getClass().getResource(path); File parent = new File(url.toURI()).getParentFile(); path = new File(parent, "A").getPath(); Fst fstA = Convert.importFst(path, new TropicalSemiring()); path = new File(parent, "fstdeterminize.fst.ser").getPath(); Fst determinized = Fst.loadModel(path); Fst fstDeterminized = Determinize.get(fstA); assertThat(determinized, equalTo(fstDeterminized)); } }
/** * Calculates the coaccessible states of an fst */ private static void calcCoAccessible(Fst fst, State state, ArrayList<ArrayList<State>> paths, HashSet<State> coaccessible) { // hold the coaccessible added in this loop ArrayList<State> newCoAccessibles = new ArrayList<State>(); for (ArrayList<State> path : paths) { int index = path.lastIndexOf(state); if (index != -1) { if (state.getFinalWeight() != fst.getSemiring().zero() || coaccessible.contains(state)) { for (int j = index; j > -1; j--) { if (!coaccessible.contains(path.get(j))) { newCoAccessibles.add(path.get(j)); coaccessible.add(path.get(j)); } } } } } // run again for the new coaccessibles for (State s : newCoAccessibles) { calcCoAccessible(fst, s, paths, coaccessible); } }
paths.add(new ArrayList<State>()); depthFirstSearch(fst, accessible, paths, exploredArcs, coaccessible);
@Test public void testCompose() throws NumberFormatException, IOException, URISyntaxException { URL url = getClass().getResource("algorithms/composeeps/A.fst.txt"); File parent = new File(url.toURI()).getParentFile(); String path = new File(parent, "A").getPath(); Fst fstA = importFst(path, new TropicalSemiring()); path = new File(parent, "B").getPath(); Fst fstB = importFst(path, new TropicalSemiring()); path = new File(parent, "fstcomposeeps").getPath(); Fst fstC = importFst(path, new TropicalSemiring()); Fst fstComposed = get(fstA, fstB, new TropicalSemiring()); assertThat(fstC, equalTo(fstComposed)); }
@Test public void testCompose() throws NumberFormatException, IOException, ClassNotFoundException, URISyntaxException { String path = "algorithms/compose/fstcompose.fst.ser"; URL url = getClass().getResource(path); File parent = new File(url.toURI()).getParentFile(); path = new File(parent, "A").getPath(); Fst fstA = importFst(path, new TropicalSemiring()); path = new File(parent, "B").getPath(); Fst fstB = importFst(path, new TropicalSemiring()); path = new File(parent, "fstcompose.fst.ser").getPath(); Fst composed = Fst.loadModel(path); Fst fstComposed = Compose.get(fstA, fstB, new TropicalSemiring()); assertThat(composed, equalTo(fstComposed)); } }