Ejemplo n.º 1
0
        internal static bool a_star2_internal(Intarray inputs,
                                              Intarray vertices1,
                                              Intarray vertices2,
                                              Intarray outputs,
                                              Floatarray costs,
                                              IGenericFst fst1,
                                              IGenericFst fst2,
                                              Floatarray g1,
                                              Floatarray g2,
                                              CompositionFst composition)
        {
            Intarray vertices        = new Intarray();
            AStarCompositionSearch a = new AStarCompositionSearch(g1, g2, composition);

            if (!a.Loop())
            {
                return(false);
            }
            if (!a.reconstruct_vertices(vertices))
            {
                return(false);
            }
            a.reconstruct_edges(inputs, outputs, costs, vertices);
            composition.SplitIndices(vertices1, vertices2, vertices);
            return(true);
        }
Ejemplo n.º 2
0
        public override IGenericFst Move2()
        {
            IGenericFst result = l2;

            l2 = null;
            return(result);
        }
Ejemplo n.º 3
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));
        }
Ejemplo n.º 4
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));
                }
            }
        }
Ejemplo n.º 5
0
        public override IGenericFst Move1()
        {
            IGenericFst result = l1;

            l1 = null;
            return(result);
        }
Ejemplo n.º 6
0
 public static void fst_write(BinaryWriter writer, IGenericFst fst)
 {
     write_header_and_symbols(writer, fst);
     for (int i = 0; i < fst.nStates(); i++)
     {
         write_node(writer, fst, i);
     }
 }
Ejemplo n.º 7
0
 public static void fst_read(IGenericFst fst, BinaryReader reader)
 {
     read_header_and_symbols(fst, reader);
     for (int i = 0; i < fst.nStates(); i++)
     {
         read_node(reader, fst, i);
     }
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Randomly sample an FST, assuming any input.
        /// </summary>
        public static double fst_sample(out string result, IGenericFst fst, int max)
        {
            Intarray tmp  = new Intarray();
            double   cost = fst_sample(tmp, fst, max);

            remove_epsilons(out result, tmp);
            return(cost);
        }
Ejemplo n.º 9
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]);
                }
            }
        }
Ejemplo n.º 10
0
        public static void a_star_backwards(Floatarray costs_for_all_nodes, IGenericFst fst)
        {
            IGenericFst reverse = FstFactory.MakeOcroFST();

            FstUtil.fst_copy_reverse(reverse, fst, true); // creates an extra vertex
            AStarSearch a = new AStarSearch(reverse);

            a.Loop();
            costs_for_all_nodes.Copy(a.g);
            costs_for_all_nodes.Pop(); // remove the extra vertex
        }
Ejemplo n.º 11
0
 protected static void write_header_and_symbols(BinaryWriter writer, IGenericFst fst)
 {
     write_int32_LE(writer, OPENFST_MAGIC);
     write_string(writer, "vector");
     write_string(writer, "standard");
     write_int32_LE(writer, MIN_VERSION);
     write_int32_LE(writer, /* flags: */ 0);
     write_int64_LE(writer, PROPERTIES);
     write_int64_LE(writer, fst.GetStart());
     write_int64_LE(writer, fst.nStates());
     write_int64_LE(writer, /* narcs (seems to be unused): */ 0L);
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Make an in-place Kleene closure of the FST.
        /// </summary>
        public static void fst_star(IGenericFst fst)
        {
            int s = fst.GetStart();

            fst.SetAccept(s);
            for (int i = 0; i < fst.nStates(); i++)
            {
                double c = fst.GetAcceptCost(i);
                if (c < 1e37)
                {
                    fst.AddTransition(i, s, 0, (float)c, 0);
                }
            }
        }
Ejemplo n.º 13
0
        protected static void read_node(BinaryReader reader, IGenericFst fst, int index)
        {
            fst.SetAccept(index, read_float(reader));
            Int64 narcs = read_int64_LE(reader);

            for (int i = 0; i < narcs; i++)
            {
                int   input  = read_int32_LE(reader);
                int   output = read_int32_LE(reader);
                float cost   = read_float(reader);
                int   target = read_int32_LE(reader);
                fst.AddTransition(index, target, output, cost, input);
            }
        }
Ejemplo n.º 14
0
        public static void fst_line(IGenericFst fst, string s)
        {
            int      n      = s.Length;
            Intarray inputs = new Intarray(n);

            for (int j = 0; j < n; j++)
            {
                inputs[j] = (int)s[j];
            }
            Floatarray costs = new Floatarray(n);

            costs.Fill(0f);
            fst.SetString(s, costs, inputs);
        }
Ejemplo n.º 15
0
        public AStarSearch(IGenericFst fst)
        {
            this.fst           = fst;
            this.accepted_from = -1;
            this.heap          = new Heap(fst.nStates() + 1);
            this.n             = fst.nStates();
            this.came_from     = new Intarray(n);
            this.came_from.Fill(-1);
            this.g = new Floatarray(n);
            // insert the start node
            int s = fst.GetStart();

            g[s]         = 0;
            came_from[s] = s;
            heap.Push(s, Convert.ToSingle(Heuristic(s)));
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Compose two FSTs.
        /// This function copies the composition of two given FSTs.
        /// That causes expansion (storing all arcs explicitly).
        /// </summary>
        public static void fst_expand_composition(IGenericFst outf, OcroFST f1, OcroFST f2)
        {
            CompositionFst composition = FstFactory.MakeCompositionFst(f1, f2);

            try
            {
                fst_copy(outf, composition);
            }
            catch (Exception ex)
            {
                composition.Move1();
                composition.Move2();
                throw ex;
            }
            composition.Move1();
            composition.Move2();
        }
Ejemplo n.º 17
0
        protected static void read_header_and_symbols(IGenericFst fst, BinaryReader reader)
        {
            if (read_int32_LE(reader) != OPENFST_MAGIC)
            {
                throw new Exception("invalid magic number");
            }
            read_magic_string(reader, "vector");
            read_magic_string(reader, "standard");
            int version = read_int32_LE(reader);

            if (version < MIN_VERSION)
            {
                throw new Exception("file has too old version");
            }
            int flags = read_int32_LE(reader);

            read_int64_LE(reader); // properties
            Int64 start   = read_int64_LE(reader);
            Int64 nstates = read_int64_LE(reader);

            if (nstates < 0)
            {
                return;   // to prevent creating 2^31 nodes in case of sudden EOF
            }
            fst.Clear();
            for (int i = 0; i < nstates; i++)
            {
                fst.NewState();
            }
            fst.SetStart((int)start);

            read_int64_LE(reader); // narcs

            if ((flags & FLAG_HAS_ISYMBOLS) > 0)
            {
                skip_symbol_table(reader);
            }
            if ((flags & FLAG_HAS_OSYMBOLS) > 0)
            {
                skip_symbol_table(reader);
            }
        }
Ejemplo n.º 18
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]);
            }
        }
Ejemplo n.º 19
0
        public CompositionFstImpl(IGenericFst l1, IGenericFst l2,
                                  int o_s, int o_f)
        {
            override_start  = o_s;
            override_finish = o_f;

            if (l1.nStates() == 0)
            {
                throw new Exception("CHECK_ARG: l1->nStates() > 0");
            }
            if (l2.nStates() == 0)
            {
                throw new Exception("CHECK_ARG: l2->nStates() > 0");
            }

            // this should be here, not in the initializers.
            // (otherwise if CHECKs throw an exception, bad things happen)
            this.l1 = l1;
            this.l2 = l2;
        }
Ejemplo n.º 20
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));
                }
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Output the segmentation into a segmentation graph.
        /// Construct a state for each of the segments, then
        /// add transitions between states (segments)
        /// from min(segments[i]) to max(segments[i])+1.
        /// </summary>
        public override void GetLattice(IGenericFst fst)
        {
            fst.Clear();

            int      final  = NarrayUtil.Max(labels) + 1;
            Intarray states = new Intarray(final + 1);

            states.Fill(-1);
            for (int i = 1; i < states.Length(); i++)
            {
                states[i] = fst.NewState();
            }
            fst.SetStart(states[1]);
            fst.SetAccept(states[final]);

            for (int i = 0; i < boxes.Length(); i++)
            {
                int start = NarrayUtil.Min(segments.At1d(i));
                int end   = NarrayUtil.Max(segments.At1d(i));
                int id    = (start << 16) + end;
                if (segments.At1d(i).Length() == 0)
                {
                    id = 0;
                }

                float yes = spaces[i, 0];
                float no  = spaces[i, 1];
                // if no space is set, assume no space is present
                if (yes == float.PositiveInfinity && no == float.PositiveInfinity)
                {
                    no = 0.0f;
                }

                for (int j = 0; j < class_costs[i].Length(); j++)
                {
                    float  cost = class_costs[i][j];
                    string str  = class_outputs[i][j];
                    int    n    = str.Length;
                    int    last = start;
                    for (int k = 0; k < n; k++)
                    {
                        int c = (int)str[k];
                        if (k < n - 1)
                        {
                            // add intermediate states/transitions for all but the last character
                            states.Push(fst.NewState());
                            fst.AddTransition(states[last], states.Last(), c, 0.0f, 0);
                            last = states.Length() - 1;
                        }
                        else
                        {
                            // for the last character, handle the spaces as well
                            if (no < 1000.0f)
                            {
                                // add the last character as a direct transition with no space
                                fst.AddTransition(states[last], states[end + 1], c, cost + no, id);
                            }
                            if (yes < 1000.0f)
                            {
                                // insert another state to handle spaces
                                states.Push(fst.NewState());
                                int space_state = states.Last();
                                fst.AddTransition(states[start], space_state, c, cost, id);
                                fst.AddTransition(space_state, states[end + 1], (int)' ', yes, 0);
                            }
                        }
                    } // for k
                }     // for j
            }         // for i
        }
Ejemplo n.º 22
0
        /// <summary>
        /// This is a weird, optional method that exposes character segmentation
        /// for those line recognizers that have it segmentation contains colored pixels,
        /// and a transition in the transducer of the form * --- 1/eps --> * --- 2/a --> *
        /// means that pixels with color 1 and 2 together form the letter "a"
        /// </summary>
        public override double RecognizeLine(Intarray segmentation_, IGenericFst result, Bytearray image_)
        {
            double rate = 0.0;

            CHECK_ARG(image_.Dim(1) < PGeti("maxheight"),
                      String.Format("input line too high ({0} x {1})", image_.Dim(0), image_.Dim(1)));
            CHECK_ARG(image_.Dim(1) * 1.0 / image_.Dim(0) < PGetf("maxaspect"),
                      String.Format("input line has bad aspect ratio ({0} x {1})", image_.Dim(0), image_.Dim(1)));
            bool use_reject = PGetb("use_reject") && !DisableJunk;
            //Console.WriteLine("IMG: imin:{0} imax:{1}", NarrayUtil.ArgMin(image_), NarrayUtil.ArgMax(image_));
            Bytearray image = new Bytearray();

            image.Copy(image_);

            SetLine(image_);

            if (PGeti("invert") > 0)
            {
                NarrayUtil.Sub(NarrayUtil.Max(image), image);
            }
            segmentation_.Copy(segmentation);
            Bytearray    available   = new Bytearray();
            Floatarray   cp          = new Floatarray();
            Floatarray   ccosts      = new Floatarray();
            Floatarray   props       = new Floatarray();
            OutputVector p           = new OutputVector();
            int          ncomponents = grouper.Object.Length();
            int          minclass    = PGeti("minclass");
            float        minprob     = PGetf("minprob");
            float        space_yes   = PGetf("space_yes");
            float        space_no    = PGetf("space_no");
            float        maxcost     = PGetf("maxcost");

            // compute priors if possible; fall back on
            // using no priors if no counts are available
            Floatarray priors     = new Floatarray();
            bool       use_priors = PGeti("use_priors") > 0;

            if (use_priors)
            {
                if (counts.Length() > 0)
                {
                    priors.Copy(counts);
                    priors /= NarrayUtil.Sum(priors);
                }
                else
                {
                    if (!counts_warned)
                    {
                        Global.Debugf("warn", "use_priors specified but priors unavailable (old model)");
                    }
                    use_priors    = false;
                    counts_warned = true;
                }
            }

            EstimateSpaceSize();

            for (int i = 0; i < ncomponents; i++)
            {
                Rect      b;
                Bytearray mask = new Bytearray();
                grouper.Object.GetMask(out b, ref mask, i, 0);
                Bytearray cv = new Bytearray();
                grouper.Object.ExtractWithMask(cv, mask, image, i, 0);
                //ImgIo.write_image_gray("extrmask_image.png", cv);
                Floatarray v = new Floatarray();
                v.Copy(cv);
                v /= 255.0f;
                float ccost = classifier.Object.XOutputs(p, v);
                if (use_reject && classifier.Object.HigherOutputIsBetter)
                {
                    ccost = 0;
                    float total = p.Sum();
                    if (total > 1e-11f)
                    {
                        //p /= total;
                    }
                    else
                    {
                        p.Values.Fill(0.0f);
                    }
                }
                int count = 0;

                Global.Debugf("dcost", "output {0}", p.Keys.Length());
                for (int index = 0; index < p.Keys.Length(); index++)
                {
                    int j = p.Keys[index];
                    if (j < minclass)
                    {
                        continue;
                    }
                    if (j == reject_class)
                    {
                        continue;
                    }
                    float value = p.Values[index];
                    if (value <= 0.0f)
                    {
                        continue;
                    }
                    if (value < minprob)
                    {
                        continue;
                    }
                    float pcost = classifier.Object.HigherOutputIsBetter ? (float)-Math.Log(value) : value;
                    Global.Debugf("dcost", "{0} {1} {2}", j, pcost + ccost, (j > 32 ? (char)j : '_'));
                    float total_cost = pcost + ccost;
                    if (total_cost < maxcost)
                    {
                        if (use_priors)
                        {
                            total_cost -= (float)-Math.Log(priors[j]);
                        }
                        grouper.Object.SetClass(i, j, total_cost);
                        count++;
                    }
                }
                Global.Debugf("dcost", "");

                if (count == 0)
                {
                    float xheight = 10.0f;
                    if (b.Height() < xheight / 2 && b.Width() < xheight / 2)
                    {
                        grouper.Object.SetClass(i, (int)'~', high_cost / 2);
                    }
                    else
                    {
                        grouper.Object.SetClass(i, (int)'#', (b.Width() / xheight) * high_cost);
                    }
                }
                if (grouper.Object.PixelSpace(i) > space_threshold)
                {
                    Global.Debugf("spaces", "space {0}", grouper.Object.PixelSpace(i));
                    grouper.Object.SetSpaceCost(i, space_yes, space_no);
                }
            }

            grouper.Object.GetLattice(result);
            return(rate);
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Recognize a text line and return a lattice representing
        /// the recognition alternatives.
        /// </summary>
        public override double RecognizeLine(IGenericFst result, Bytearray image)
        {
            Intarray segmentation_ = new Intarray();

            return(RecognizeLine(segmentation_, result, image));
        }
Ejemplo n.º 24
0
 /// <summary>
 /// Make a Kleene closure.
 /// </summary>
 public static void fst_star(IGenericFst result, IGenericFst fst)
 {
     fst_copy(result, fst);
     fst_star(result);
 }