Example #1
0
        /// <summary>
        /// Randomly sample an FST, assuming any input.
        /// </summary>
        /// <param name="result">The array of output symbols, excluding epsilons.</param>
        /// <param name="fst">The FST.</param>
        /// <param name="max">The maximum length of the result.</param>
        /// <returns>total cost</returns>
        public static double fst_sample(Intarray result, IGenericFst fst, int max = 1000)
        {
            double total_cost = 0;
            int    current    = fst.GetStart();

            for (int counter = 0; counter < max; counter++)
            {
                Intarray   inputs  = new Intarray();
                Intarray   outputs = new Intarray();
                Intarray   targets = new Intarray();
                Floatarray costs   = new Floatarray();

                fst.Arcs(inputs, targets, outputs, costs, current);

                // now we need to deal with the costs uniformly, so:
                costs.Push(fst.GetAcceptCost(current));
                int choice = sample_by_costs(costs);
                if (choice == costs.Length() - 1)
                {
                    break;
                }
                result.Push(outputs[choice]);
                total_cost += costs[choice];
                current     = targets[choice];
            }
            return(total_cost + fst.GetAcceptCost(current));
        }
Example #2
0
        /// <summary>
        /// Copy one FST to another.
        /// </summary>
        /// <param name="dst">The destination. Will be cleared before copying.</param>
        /// <param name="src">The FST to copy.</param>
        public static void fst_copy(IGenericFst dst, IGenericFst src)
        {
            dst.Clear();
            int n = src.nStates();

            for (int i = 0; i < n; i++)
            {
                dst.NewState();
            }
            dst.SetStart(src.GetStart());
            for (int i = 0; i < n; i++)
            {
                dst.SetAccept(i, src.GetAcceptCost(i));
                Intarray   targets = new Intarray(), outputs = new Intarray(), inputs = new Intarray();
                Floatarray costs = new Floatarray();
                src.Arcs(inputs, targets, outputs, costs, i);
                int inlen = inputs.Length();
                if (inlen != targets.Length())
                {
                    throw new Exception("ASSERT: inputs.length() == targets.length()");
                }
                if (inlen != outputs.Length())
                {
                    throw new Exception("ASSERT: inputs.length() == outputs.length()");
                }
                if (inlen != costs.Length())
                {
                    throw new Exception("ASSERT: inputs.length() == costs.length()");
                }
                for (int j = 0; j < inputs.Length(); j++)
                {
                    dst.AddTransition(i, targets.At1d(j), outputs.At1d(j), costs.At1d(j), inputs.At1d(j));
                }
            }
        }
Example #3
0
        /// <summary>
        /// Copy one FST to another, preserving only lowest-cost arcs.
        /// This is useful for visualization.
        /// </summary>
        /// <param name="dst">The destination. Will be cleared before copying.</param>
        /// <param name="src">The FST to copy.</param>
        public static void fst_copy_best_arcs_only(IGenericFst dst, IGenericFst src)
        {
            dst.Clear();
            int n = src.nStates();

            for (int i = 0; i < n; i++)
            {
                dst.NewState();
            }
            dst.SetStart(src.GetStart());
            for (int i = 0; i < n; i++)
            {
                dst.SetAccept(i, src.GetAcceptCost(i));
                Intarray   targets = new Intarray(), outputs = new Intarray(), inputs = new Intarray();
                Floatarray costs = new Floatarray();
                src.Arcs(inputs, targets, outputs, costs, i);
                int inlen = inputs.Length();
                if (inlen != targets.Length())
                {
                    throw new Exception("ASSERT: inputs.length() == targets.length()");
                }
                if (inlen != outputs.Length())
                {
                    throw new Exception("ASSERT: inputs.length() == outputs.length()");
                }
                if (inlen != costs.Length())
                {
                    throw new Exception("ASSERT: inputs.length() == costs.length()");
                }
                Dictionary <int, int> hash = new Dictionary <int, int>();
                for (int j = 0; j < n; j++)
                {
                    int t           = targets[j];
                    int best_so_far = -1;
                    if (hash.ContainsKey(t))
                    {
                        best_so_far = hash[t];
                    }
                    if (best_so_far == -1 || costs[j] < costs[best_so_far])
                    {
                        hash[t] = j;
                    }
                }
                Intarray keys = new Intarray();
                //hash.keys(keys);
                keys.Clear();
                foreach (int key in hash.Keys)
                {
                    keys.Push(key);
                }

                for (int k = 0; k < keys.Length(); k++)
                {
                    int j = hash[keys[k]];
                    dst.AddTransition(i, targets[j], outputs[j], costs[j], inputs[j]);
                }
            }
        }
Example #4
0
        public bool Step()
        {
            int node = heap.Pop();

            if (node == n)
            {
                return(true);  // accept has popped up
            }
            // get outbound arcs
            Intarray   inputs  = new Intarray();
            Intarray   targets = new Intarray();
            Intarray   outputs = new Intarray();
            Floatarray costs   = new Floatarray();

            fst.Arcs(inputs, targets, outputs, costs, node);
            for (int i = 0; i < targets.Length(); i++)
            {
                int t = targets[i];
                if (came_from[t] == -1 || g[node] + costs[i] < g[t])
                {
                    // relax the edge
                    came_from[t] = node;
                    g[t]         = g[node] + costs[i];
                    heap.Push(t, g[t] + Convert.ToSingle(Heuristic(t)));
                }
            }
            if (accepted_from == -1 ||
                g[node] + fst.GetAcceptCost(node) < g_accept)
            {
                // relax the accept edge
                accepted_from = node;
                g_accept      = g[node] + fst.GetAcceptCost(node);
                heap.Push(n, g_accept);
            }
            return(false);
        }
Example #5
0
        protected static void write_node(BinaryWriter writer, IGenericFst fst, int index)
        {
            Intarray   inputs  = new Intarray();
            Intarray   targets = new Intarray();
            Intarray   outputs = new Intarray();
            Floatarray costs   = new Floatarray();

            fst.Arcs(inputs, targets, outputs, costs, index);
            int narcs = targets.Length();

            write_float(writer, fst.GetAcceptCost(index));
            write_int64_LE(writer, narcs);
            for (int i = 0; i < narcs; i++)
            {
                write_int32_LE(writer, inputs[i]);
                write_int32_LE(writer, outputs[i]);
                write_float(writer, costs[i]);
                write_int32_LE(writer, targets[i]);
            }
        }
Example #6
0
        /// <summary>
        /// Reverse the FST's arcs, adding a new start vertex (former accept).
        /// </summary>
        public static void fst_copy_reverse(IGenericFst dst, IGenericFst src, bool no_accept = false)
        {
            dst.Clear();
            int n = src.nStates();

            for (int i = 0; i <= n; i++)
            {
                dst.NewState();
            }
            if (!no_accept)
            {
                dst.SetAccept(src.GetStart());
            }
            dst.SetStart(n);
            for (int i = 0; i < n; i++)
            {
                dst.AddTransition(n, i, 0, src.GetAcceptCost(i), 0);
                Intarray   targets = new Intarray(), outputs = new Intarray(), inputs = new Intarray();
                Floatarray costs = new Floatarray();
                src.Arcs(inputs, targets, outputs, costs, i);
                if (inputs.Length() != targets.Length())
                {
                    throw new Exception("ASSERT: inputs.length() == targets.length()");
                }
                if (inputs.Length() != outputs.Length())
                {
                    throw new Exception("ASSERT: inputs.length() == outputs.length()");
                }
                if (inputs.Length() != costs.Length())
                {
                    throw new Exception("ASSERT: inputs.length() == costs.length()");
                }
                for (int j = 0; j < inputs.Length(); j++)
                {
                    dst.AddTransition(targets.At1d(j), i, outputs.At1d(j), costs.At1d(j), inputs.At1d(j));
                }
            }
        }
Example #7
0
        public override void Arcs(Intarray ids, Intarray targets, Intarray outputs, Floatarray costs, int node)
        {
            int        n1   = node / l2.nStates();
            int        n2   = node % l2.nStates();
            Intarray   ids1 = new Intarray();
            Intarray   ids2 = new Intarray();
            Intarray   t1   = new Intarray();
            Intarray   t2   = new Intarray();
            Intarray   o1   = new Intarray();
            Intarray   o2   = new Intarray();
            Floatarray c1   = new Floatarray();
            Floatarray c2   = new Floatarray();

            l1.Arcs(ids1, t1, o1, c1, n1);
            l2.Arcs(ids2, t2, o2, c2, n2);

            // sort & permute
            Intarray p1 = new Intarray();
            Intarray p2 = new Intarray();

            NarrayUtil.Quicksort(p1, o1);
            NarrayUtil.Permute(ids1, p1);
            NarrayUtil.Permute(t1, p1);
            NarrayUtil.Permute(o1, p1);
            NarrayUtil.Permute(c1, p1);

            NarrayUtil.Quicksort(p2, ids2);
            NarrayUtil.Permute(ids2, p2);
            NarrayUtil.Permute(t2, p2);
            NarrayUtil.Permute(o2, p2);
            NarrayUtil.Permute(c2, p2);

            int k1, k2;

            // l1 epsilon moves
            for (k1 = 0; k1 < o1.Length() && o1.At1d(k1) == 0; k1++)
            {
                ids.Push(ids1.At1d(k1));
                targets.Push(Combine(t1.At1d(k1), n2));
                outputs.Push(0);
                costs.Push(c1.At1d(k1));
            }
            // l2 epsilon moves
            for (k2 = 0; k2 < o2.Length() && ids2.At1d(k2) == 0; k2++)
            {
                ids.Push(0);
                targets.Push(Combine(n1, t2.At1d(k2)));
                outputs.Push(o2.At1d(k2));
                costs.Push(c2.At1d(k2));
            }
            // non-epsilon moves
            while (k1 < o1.Length() && k2 < ids2.Length())
            {
                while (k1 < o1.Length() && o1.At1d(k1) < ids2.At1d(k2))
                {
                    k1++;
                }
                if (k1 >= o1.Length())
                {
                    break;
                }
                while (k2 < ids2.Length() && o1.At1d(k1) > ids2.At1d(k2))
                {
                    k2++;
                }
                while (k1 < o1.Length() && k2 < ids2.Length() && o1.At1d(k1) == ids2.At1d(k2))
                {
                    for (int j = k2; j < ids2.Length() && o1.At1d(k1) == ids2.At1d(j); j++)
                    {
                        ids.Push(ids1.At1d(k1));
                        targets.Push(Combine(t1.At1d(k1), t2.At1d(j)));
                        outputs.Push(o2.At1d(j));
                        costs.Push(c1.At1d(k1) + c2.At1d(j));
                    }
                    k1++;
                }
            }
        }