Ejemplo n.º 1
0
        /// <summary>Samples a single position in the sequence.</summary>
        /// <remarks>
        /// Samples a single position in the sequence.
        /// Does not modify the sequence passed in.
        /// returns the score of the new label for the position to sample
        /// </remarks>
        /// <param name="sequence">the sequence to start with</param>
        /// <param name="pos">the position to sample.</param>
        /// <param name="temperature">the temperature to control annealing</param>
        private Pair <int, double> SamplePositionHelper(ISequenceModel model, int[] sequence, int pos, double temperature)
        {
            double[] distribution = model.ScoresOf(sequence, pos);
            if (temperature != 1.0)
            {
                if (temperature == 0.0)
                {
                    // set the max to 1.0
                    int argmax = ArrayMath.Argmax(distribution);
                    Arrays.Fill(distribution, double.NegativeInfinity);
                    distribution[argmax] = 0.0;
                }
                else
                {
                    // take all to a power
                    // use the temperature to increase/decrease the entropy of the sampling distribution
                    ArrayMath.MultiplyInPlace(distribution, 1.0 / temperature);
                }
            }
            ArrayMath.LogNormalize(distribution);
            ArrayMath.ExpInPlace(distribution);
            int    newTag  = ArrayMath.SampleFromDistribution(distribution, random);
            double newProb = distribution[newTag];

            return(new Pair <int, double>(newTag, newProb));
        }
Ejemplo n.º 2
0
 public _IThreadsafeProcessor_269(SequenceGibbsSampler _enclosing, ISequenceModel model, int[] sequence, double temperature)
 {
     this._enclosing  = _enclosing;
     this.model       = model;
     this.sequence    = sequence;
     this.temperature = temperature;
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Collects numSamples samples of sequences, from the distribution over sequences defined
        /// by the sequence model passed on construction.
        /// </summary>
        /// <remarks>
        /// Collects numSamples samples of sequences, from the distribution over sequences defined
        /// by the sequence model passed on construction.
        /// All samples collected are sampleInterval samples apart, in an attempt to reduce
        /// autocorrelation.
        /// </remarks>
        /// <returns>a Counter containing the sequence samples, as arrays of type int, and their scores</returns>
        public virtual IList <int[]> CollectSamples(ISequenceModel model, int numSamples, int sampleInterval, int[] initialSequence)
        {
            if (verbose > 0)
            {
                log.Info("Collecting samples");
            }
            listener.SetInitialSequence(initialSequence);
            IList <int[]> result = new List <int[]>();

            int[] sequence = initialSequence;
            for (int i = 0; i < numSamples; i++)
            {
                sequence = Copy(sequence);
                // so we don't change the initial, or the one we just stored
                SampleSequenceRepeatedly(model, sequence, sampleInterval);
                // modifies tagSequence
                result.Add(sequence);
                // save it to return later
                if (verbose > 0)
                {
                    log.Info(".");
                }
                System.Console.Error.Flush();
            }
            if (verbose > 1)
            {
                log.Info();
                PrintSamples(result, System.Console.Error);
            }
            if (verbose > 0)
            {
                log.Info("done.");
            }
            return(result);
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LayerSnapshotCommand"/> class.
 /// </summary>
 /// <param name="sequenceModel">The timeline model.</param>
 /// <param name="layer">The layer where the snapshot is being took.</param>
 /// <param name="currentMemento">The current state of the layer.</param>
 /// <param name="newMemento">The new state of the layer.</param>
 public LayerSnapshotCommand(ISequenceModel sequenceModel, Track layer, IList <TimelineElement> currentMemento, IList <TimelineElement> newMemento)
 {
     this.sequenceModel  = sequenceModel;
     this.layer          = layer;
     this.currentMemento = currentMemento;
     this.newMemento     = newMemento;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ToggleLinkElementCommand"/> class.
 /// </summary>
 /// <param name="sequenceModel">The timeline model.</param>
 /// <param name="layer">The layer of the element.</param>
 /// <param name="element">The element being linked/unliked.</param>
 /// <param name="linkPosition">The <see cref="LinkPosition"/> of the link.</param>
 public ToggleLinkElementCommand(ISequenceModel sequenceModel, Track layer, TimelineElement element, LinkPosition linkPosition)
 {
     this.sequenceModel = sequenceModel;
     this.layer         = layer;
     this.element       = element;
     this.linkPosition  = linkPosition;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="RemoveElementCommand"/> class.
 /// </summary>
 /// <param name="sequenceModel">The timeline model.</param>
 /// <param name="layer">The layer where the element is being removed.</param>
 /// <param name="editMode">The current <see cref="EditMode"/>.</param>
 /// <param name="timelineElement">The element being removed.</param>
 public RemoveElementCommand(ISequenceModel sequenceModel, Track layer, EditMode editMode, TimelineElement timelineElement)
 {
     this.sequenceModel   = sequenceModel;
     this.layer           = layer;
     this.editMode        = editMode;
     this.timelineElement = timelineElement;
     this.memento         = new List <TimelineElement>();
 }
Ejemplo n.º 7
0
        public void InvokeCurrentSequenceChanged(ISequenceModel sequenceModel)
        {
            EventHandler <DataEventArgs <ISequenceModel> > handler = this.CurrentSequenceChanged;

            if (handler != null)
            {
                handler(this, new DataEventArgs <ISequenceModel>(sequenceModel));
            }
        }
Ejemplo n.º 8
0
        private void InvokeCurrentSequenceChanged(ISequenceModel previousSequence)
        {
            EventHandler <Infrastructure.DataEventArgs <ISequenceModel> > handler = this.CurrentSequenceChanged;

            if (handler != null)
            {
                handler(this, new Infrastructure.DataEventArgs <ISequenceModel>(previousSequence));
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Samples the complete sequence once in the backward direction
        /// Destructively modifies the sequence in place.
        /// </summary>
        /// <param name="sequence">the sequence to start with.</param>
        public virtual double SampleSequenceBackward(ISequenceModel model, int[] sequence, double temperature)
        {
            double returnScore = double.NegativeInfinity;

            for (int pos = sequence.Length - 1; pos >= 0; pos--)
            {
                returnScore = SamplePosition(model, sequence, pos, temperature);
            }
            return(returnScore);
        }
Ejemplo n.º 10
0
 public static int[] GetRandomSequence(ISequenceModel model)
 {
     int[] result = new int[model.Length()];
     for (int i = 0; i < result.Length; i++)
     {
         int[] classes = model.GetPossibleValues(i);
         result[i] = classes[random.NextInt(classes.Length)];
     }
     return(result);
 }
Ejemplo n.º 11
0
        /// <summary>Samples a single position in the sequence.</summary>
        /// <remarks>
        /// Samples a single position in the sequence.
        /// Destructively modifies the sequence in place.
        /// returns the score of the new sequence
        /// </remarks>
        /// <param name="sequence">the sequence to start with</param>
        /// <param name="pos">the position to sample.</param>
        /// <param name="temperature">the temperature to control annealing</param>
        public virtual double SamplePosition(ISequenceModel model, int[] sequence, int pos, double temperature)
        {
            int oldTag = sequence[pos];
            Pair <int, double> newPosProb = SamplePositionHelper(model, sequence, pos, temperature);
            int newTag = newPosProb.First();

            //    System.out.println("Sampled " + oldTag + "->" + newTag);
            sequence[pos] = newTag;
            listener.UpdateSequenceElement(sequence, pos, oldTag);
            return(newPosProb.Second());
        }
Ejemplo n.º 12
0
        /// <summary>Samples the sequence repeatedly, making numSamples passes over the entire sequence.</summary>
        public virtual double SampleSequenceRepeatedly(ISequenceModel model, int[] sequence, int numSamples)
        {
            sequence = Copy(sequence);
            // so we don't change the initial, or the one we just stored
            listener.SetInitialSequence(sequence);
            double returnScore = double.NegativeInfinity;

            for (int iter = 0; iter < numSamples; iter++)
            {
                returnScore = SampleSequenceForward(model, sequence);
            }
            return(returnScore);
        }
 public FactoredSequenceModel(ISequenceModel model1, ISequenceModel model2)
 {
     //if (model1.leftWindow() != model2.leftWindow()) throw new RuntimeException("Two models must have same window size");
     if (model1.GetPossibleValues(0).Length != model2.GetPossibleValues(0).Length)
     {
         throw new Exception("Two models must have the same number of classes");
     }
     if (model1.Length() != model2.Length())
     {
         throw new Exception("Two models must have the same sequence length");
     }
     this.model1 = model1;
     this.model2 = model2;
 }
Ejemplo n.º 14
0
        public void ShouldPassPreviousSequenceAsSequenceChangedArgument()
        {
            var sequenceRegistry = this.CreateSequenceRegistry();

            bool wasRaised = false;

            ISequenceModel eventSequence = null;

            ISequenceModel anotherSequence = new SequenceModel(new MockEventAggregator());

            sequenceRegistry.CurrentSequenceModel = this.sequenceModel;

            sequenceRegistry.CurrentSequenceChanged += (s, a) => { eventSequence = a.Data; };

            sequenceRegistry.CurrentSequenceModel = anotherSequence;

            Assert.AreSame(this.sequenceModel, eventSequence);
        }
Ejemplo n.º 15
0
        private void UpdateSequences(object sender, EventArgs e)
        {
            Project project = this.projectService.GetCurrentProject();

            this.sequences.Clear();

            foreach (var sequence in project.Timelines)
            {
                this.CreateSequence(sequence, this.GetSequenceDuration(sequence));
            }

            if (this.sequences.Values.Count > 0)
            {
                this.CurrentSequenceModel = this.sequences.Values.First();
            }

            this.eventAggregator.GetEvent <OperationExecutedInTimelineEvent>().Publish(null);
        }
Ejemplo n.º 16
0
 /// <summary>Samples each label in turn from left to right.</summary>
 /// <returns>an array containing the int tags of the best sequence</returns>
 public virtual int[] BestSequence(ISequenceModel ts)
 {
     // Also allocate space for rightWindow, just in case sequence model uses
     // it, even though this implementation doesn't. Probably it shouldn't,
     // or the left-to-right sampling is invalid, but our test classes do.
     int[] sample = new int[ts.Length() + ts.LeftWindow() + ts.RightWindow()];
     for (int pos = ts.LeftWindow(); pos < sample.Length - ts.RightWindow(); pos++)
     {
         double[] scores = ts.ScoresOf(sample, pos);
         for (int i = 0; i < scores.Length; i++)
         {
             scores[i] = Math.Exp(scores[i]);
         }
         ArrayMath.Normalize(scores);
         int l = ArrayMath.SampleFromDistribution(scores);
         sample[pos] = ts.GetPossibleValues(pos)[l];
     }
     return(sample);
 }
Ejemplo n.º 17
0
        /// <summary>
        /// Finds the best sequence by collecting numSamples samples, scoring them, and then choosing
        /// the highest scoring sample.
        /// </summary>
        /// <returns>the array of type int representing the highest scoring sequence</returns>
        public virtual int[] FindBestUsingSampling(ISequenceModel model, int numSamples, int sampleInterval, int[] initialSequence)
        {
            IList samples = CollectSamples(model, numSamples, sampleInterval, initialSequence);

            int[]  best      = null;
            double bestScore = double.NegativeInfinity;

            foreach (object sample in samples)
            {
                int[]  sequence = (int[])sample;
                double score    = model.ScoreOf(sequence);
                if (score > bestScore)
                {
                    best      = sequence;
                    bestScore = score;
                    log.Info("found new best (" + bestScore + ")");
                    log.Info(ArrayMath.ToString(best));
                }
            }
            return(best);
        }
Ejemplo n.º 18
0
        public ISequenceModel CreateSequence(Sequence sequence, TimeCode duration)
        {
            var newSequence = this.container.Resolve <ISequenceModel>();

            if (this.sequences.ContainsKey(sequence))
            {
                this.sequences[sequence] = newSequence;
            }
            else
            {
                this.sequences.Add(sequence, newSequence);
            }

            newSequence.Duration      = duration;
            this.CurrentSequenceModel = newSequence;

            foreach (var track in sequence.Tracks)
            {
                newSequence.AddTrack(track);
            }

            return(newSequence);
        }
 private static int[] BestSequenceNew(ISequenceModel ts)
 {
     return BestSequenceNew(ts, null).First();
 }
 public static Pair<int[], Double> BestSequenceWithLinearConstraints(ISequenceModel ts, double[][] linearConstraints)
 {
     return BestSequenceNew(ts, linearConstraints);
 }
        private static Pair <int[], double> BestSequence(ISequenceModel ts, double[][] linearConstraints)
        {
            // Set up tag options
            int length      = ts.Length();
            int leftWindow  = ts.LeftWindow();
            int rightWindow = ts.RightWindow();
            int padLength   = length + leftWindow + rightWindow;

            if (linearConstraints != null && linearConstraints.Length != padLength)
            {
                throw new Exception("linearConstraints.length (" + linearConstraints.Length + ") does not match padLength (" + padLength + ") of SequenceModel" + ", length==" + length + ", leftW=" + leftWindow + ", rightW=" + rightWindow);
            }
            int[][] tags   = new int[padLength][];
            int[]   tagNum = new int[padLength];
            for (int pos = 0; pos < padLength; pos++)
            {
                if (Thread.Interrupted())
                {
                    // Allow interrupting
                    throw new RuntimeInterruptedException();
                }
                tags[pos]   = ts.GetPossibleValues(pos);
                tagNum[pos] = tags[pos].Length;
            }
            int[] tempTags = new int[padLength];
            // Set up product space sizes
            int[] productSizes = new int[padLength];
            int   curProduct   = 1;

            for (int i = 0; i < leftWindow + rightWindow; i++)
            {
                curProduct *= tagNum[i];
            }
            for (int pos_1 = leftWindow + rightWindow; pos_1 < padLength; pos_1++)
            {
                if (Thread.Interrupted())
                {
                    // Allow interrupting
                    throw new RuntimeInterruptedException();
                }
                if (pos_1 > leftWindow + rightWindow)
                {
                    curProduct /= tagNum[pos_1 - leftWindow - rightWindow - 1];
                }
                // shift off
                curProduct *= tagNum[pos_1];
                // shift on
                productSizes[pos_1 - rightWindow] = curProduct;
            }
            // Score all of each window's options
            double[][] windowScore = new double[padLength][];
            for (int pos_2 = leftWindow; pos_2 < leftWindow + length; pos_2++)
            {
                if (Thread.Interrupted())
                {
                    // Allow interrupting
                    throw new RuntimeInterruptedException();
                }
                windowScore[pos_2] = new double[productSizes[pos_2]];
                Arrays.Fill(tempTags, tags[0][0]);
                for (int product = 0; product < productSizes[pos_2]; product++)
                {
                    if (Thread.Interrupted())
                    {
                        // Allow interrupting
                        throw new RuntimeInterruptedException();
                    }
                    int p     = product;
                    int shift = 1;
                    for (int curPos = pos_2 + rightWindow; curPos >= pos_2 - leftWindow; curPos--)
                    {
                        tempTags[curPos] = tags[curPos][p % tagNum[curPos]];
                        p /= tagNum[curPos];
                        if (curPos > pos_2)
                        {
                            shift *= tagNum[curPos];
                        }
                    }
                    // Here now you get ts.scoresOf() for all classifications at a position at once, whereas the old code called ts.scoreOf() on each item.
                    // CDM May 2007: The way this is done gives incorrect results if there are repeated values in the values of ts.getPossibleValues(pos) -- in particular if the first value of the array is repeated later.  I tried replacing it with the modulo version, but that only worked for left-to-right, not bidirectional inference, but I still think that if you sorted things out, you should be able to do it with modulos and the result would be conceptually simpler and robust to repeated values.  But in the meantime, I fixed the POS tagger to not give repeated values (which was a bug in the tagger).
                    if (tempTags[pos_2] == tags[pos_2][0])
                    {
                        // get all tags at once
                        double[] scores = ts.ScoresOf(tempTags, pos_2);
                        // fill in the relevant windowScores
                        for (int t = 0; t < tagNum[pos_2]; t++)
                        {
                            windowScore[pos_2][product + t * shift] = scores[t];
                        }
                    }
                }
            }
            // Set up score and backtrace arrays
            double[][] score = new double[padLength][];
            int[][]    trace = new int[padLength][];
            for (int pos_3 = 0; pos_3 < padLength; pos_3++)
            {
                if (Thread.Interrupted())
                {
                    // Allow interrupting
                    throw new RuntimeInterruptedException();
                }
                score[pos_3] = new double[productSizes[pos_3]];
                trace[pos_3] = new int[productSizes[pos_3]];
            }
            // Do forward Viterbi algorithm
            // loop over the classification spot
            //log.info();
            for (int pos_4 = leftWindow; pos_4 < length + leftWindow; pos_4++)
            {
                //log.info(".");
                // loop over window product types
                for (int product = 0; product < productSizes[pos_4]; product++)
                {
                    if (Thread.Interrupted())
                    {
                        // Allow interrupting
                        throw new RuntimeInterruptedException();
                    }
                    // check for initial spot
                    if (pos_4 == leftWindow)
                    {
                        // no predecessor type
                        score[pos_4][product] = windowScore[pos_4][product];
                        if (linearConstraints != null)
                        {
                            score[pos_4][product] += linearConstraints[pos_4][product % tagNum[pos_4]];
                        }
                        trace[pos_4][product] = -1;
                    }
                    else
                    {
                        // loop over possible predecessor types
                        score[pos_4][product] = double.NegativeInfinity;
                        trace[pos_4][product] = -1;
                        int sharedProduct = product / tagNum[pos_4 + rightWindow];
                        int factor        = productSizes[pos_4] / tagNum[pos_4 + rightWindow];
                        for (int newTagNum = 0; newTagNum < tagNum[pos_4 - leftWindow - 1]; newTagNum++)
                        {
                            int    predProduct = newTagNum * factor + sharedProduct;
                            double predScore   = score[pos_4 - 1][predProduct] + windowScore[pos_4][product];
                            if (linearConstraints != null)
                            {
                                predScore += linearConstraints[pos_4][product % tagNum[pos_4]];
                            }
                            if (predScore > score[pos_4][product])
                            {
                                score[pos_4][product] = predScore;
                                trace[pos_4][product] = predProduct;
                            }
                        }
                    }
                }
            }
            // Project the actual tag sequence
            double bestFinalScore     = double.NegativeInfinity;
            int    bestCurrentProduct = -1;

            for (int product_1 = 0; product_1 < productSizes[leftWindow + length - 1]; product_1++)
            {
                if (score[leftWindow + length - 1][product_1] > bestFinalScore)
                {
                    bestCurrentProduct = product_1;
                    bestFinalScore     = score[leftWindow + length - 1][product_1];
                }
            }
            int lastProduct = bestCurrentProduct;

            for (int last = padLength - 1; last >= length - 1 && last >= 0; last--)
            {
                tempTags[last] = tags[last][lastProduct % tagNum[last]];
                lastProduct   /= tagNum[last];
            }
            for (int pos_5 = leftWindow + length - 2; pos_5 >= leftWindow; pos_5--)
            {
                int bestNextProduct = bestCurrentProduct;
                bestCurrentProduct           = trace[pos_5 + 1][bestNextProduct];
                tempTags[pos_5 - leftWindow] = tags[pos_5 - leftWindow][bestCurrentProduct / (productSizes[pos_5] / tagNum[pos_5 - leftWindow])];
            }
            return(new Pair <int[], double>(tempTags, bestFinalScore));
        }
 /// <summary>using this constructor results in a weighted addition of the two models' scores.</summary>
 /// <param name="model1"/>
 /// <param name="model2"/>
 /// <param name="wt1">weight of model1</param>
 /// <param name="wt2">weight of model2</param>
 public FactoredSequenceModel(ISequenceModel model1, ISequenceModel model2, double wt1, double wt2)
     : this(model1, model2)
 {
     this.model1Wt = wt1;
     this.model2Wt = wt2;
 }
 public virtual int[] BestSequence(ISequenceModel ts)
 {
     return BestSequence(ts, (1024 * 128));
 }
 /// <summary>
 /// Runs the Viterbi algorithm on the sequence model
 /// in order to find the best sequence.
 /// </summary>
 /// <remarks>
 /// Runs the Viterbi algorithm on the sequence model
 /// in order to find the best sequence.
 /// This sequence finder only works on SequenceModel's with rightWindow == 0.
 /// </remarks>
 /// <returns>An array containing the int tags of the best sequence</returns>
 public virtual int[] BestSequence(ISequenceModel ts)
 {
     return(Counters.Argmax(KBestSequences(ts, 1)));
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="TestableLayerSnapshotCommand"/> class.
 /// </summary>
 /// <param name="sequenceModel">The timeline model.</param>
 /// <param name="layer">The layer where the snapshot is being took.</param>
 /// <param name="currentMemento">The current state of the layer.</param>
 /// <param name="newMemento">The new state of the layer.</param>
 public TestableLayerSnapshotCommand(ISequenceModel sequenceModel, Track layer, IList <TimelineElement> currentMemento, IList <TimelineElement> newMemento) : base(sequenceModel, layer, currentMemento, newMemento)
 {
 }
Ejemplo n.º 26
0
        public static DFSA <string, int> GetGraph(ISequenceModel ts, IIndex <string> classIndex)
        {
            DFSA <string, int> viterbiSearchGraph = new DFSA <string, int>(null);
            // Set up tag options
            int length      = ts.Length();
            int leftWindow  = ts.LeftWindow();
            int rightWindow = ts.RightWindow();

            System.Diagnostics.Debug.Assert((rightWindow == 0));
            int padLength = length + leftWindow + rightWindow;

            // NOTE: tags[i][j]  : i is index into pos, and j into product
            int[][] tags   = new int[padLength][];
            int[]   tagNum = new int[padLength];
            for (int pos = 0; pos < padLength; pos++)
            {
                tags[pos]   = ts.GetPossibleValues(pos);
                tagNum[pos] = tags[pos].Length;
            }
            // Set up Viterbi search graph:
            DFSAState <string, int>[][] graphStates = null;
            DFSAState <string, int>     startState  = null;
            DFSAState <string, int>     endState    = null;

            if (viterbiSearchGraph != null)
            {
                int stateId = -1;
                startState = new DFSAState <string, int>(++stateId, viterbiSearchGraph, 0.0);
                viterbiSearchGraph.SetInitialState(startState);
                graphStates = new DFSAState[length][];
                for (int pos_1 = 0; pos_1 < length; ++pos_1)
                {
                    //System.err.printf("%d states at pos %d\n",tags[pos].length,pos);
                    graphStates[pos_1] = new DFSAState[tags[pos_1].Length];
                    for (int product = 0; product < tags[pos_1].Length; ++product)
                    {
                        graphStates[pos_1][product] = new DFSAState <string, int>(++stateId, viterbiSearchGraph);
                    }
                }
                // Accepting state:
                endState = new DFSAState <string, int>(++stateId, viterbiSearchGraph, 0.0);
                endState.SetAccepting(true);
            }
            int[] tempTags = new int[padLength];
            // Set up product space sizes
            int[] productSizes = new int[padLength];
            int   curProduct   = 1;

            for (int i = 0; i < leftWindow; i++)
            {
                curProduct *= tagNum[i];
            }
            for (int pos_2 = leftWindow; pos_2 < padLength; pos_2++)
            {
                if (pos_2 > leftWindow + rightWindow)
                {
                    curProduct /= tagNum[pos_2 - leftWindow - rightWindow - 1];
                }
                // shift off
                curProduct *= tagNum[pos_2];
                // shift on
                productSizes[pos_2 - rightWindow] = curProduct;
            }
            double[][] windowScore = new double[padLength][];
            // Score all of each window's options
            for (int pos_3 = leftWindow; pos_3 < leftWindow + length; pos_3++)
            {
                windowScore[pos_3] = new double[productSizes[pos_3]];
                Arrays.Fill(tempTags, tags[0][0]);
                for (int product = 0; product < productSizes[pos_3]; product++)
                {
                    int p     = product;
                    int shift = 1;
                    for (int curPos = pos_3; curPos >= pos_3 - leftWindow; curPos--)
                    {
                        tempTags[curPos] = tags[curPos][p % tagNum[curPos]];
                        p /= tagNum[curPos];
                        if (curPos > pos_3)
                        {
                            shift *= tagNum[curPos];
                        }
                    }
                    if (tempTags[pos_3] == tags[pos_3][0])
                    {
                        // get all tags at once
                        double[] scores = ts.ScoresOf(tempTags, pos_3);
                        // fill in the relevant windowScores
                        for (int t = 0; t < tagNum[pos_3]; t++)
                        {
                            windowScore[pos_3][product + t * shift] = scores[t];
                        }
                    }
                }
            }
            // loop over the classification spot
            for (int pos_4 = leftWindow; pos_4 < length + leftWindow; pos_4++)
            {
                // loop over window product types
                for (int product = 0; product < productSizes[pos_4]; product++)
                {
                    if (pos_4 == leftWindow)
                    {
                        // all nodes in the first spot link to startState:
                        int curTag = tags[pos_4][product % tagNum[pos_4]];
                        //System.err.printf("pos=%d, product=%d, tag=%d score=%.3f\n",pos,product,curTag,windowScore[pos][product]);
                        DFSATransition <string, int> tr = new DFSATransition <string, int>(string.Empty, startState, graphStates[pos_4][product], classIndex.Get(curTag), string.Empty, -windowScore[pos_4][product]);
                        startState.AddTransition(tr);
                    }
                    else
                    {
                        int sharedProduct = product / tagNum[pos_4 + rightWindow];
                        int factor        = productSizes[pos_4] / tagNum[pos_4 + rightWindow];
                        for (int newTagNum = 0; newTagNum < tagNum[pos_4 - leftWindow - 1]; newTagNum++)
                        {
                            int predProduct = newTagNum * factor + sharedProduct;
                            int predTag     = tags[pos_4 - 1][predProduct % tagNum[pos_4 - 1]];
                            int curTag      = tags[pos_4][product % tagNum[pos_4]];
                            //log.info("pos: "+pos);
                            //log.info("product: "+product);
                            //System.err.printf("pos=%d-%d, product=%d-%d, tag=%d-%d score=%.3f\n",pos-1,pos,predProduct,product,predTag,curTag,
                            //  windowScore[pos][product]);
                            DFSAState <string, int>      sourceState = graphStates[pos_4 - leftWindow][predTag];
                            DFSAState <string, int>      destState   = (pos_4 - leftWindow + 1 == graphStates.Length) ? endState : graphStates[pos_4 - leftWindow + 1][curTag];
                            DFSATransition <string, int> tr          = new DFSATransition <string, int>(string.Empty, sourceState, destState, classIndex.Get(curTag), string.Empty, -windowScore[pos_4][product]);
                            graphStates[pos_4 - leftWindow][predTag].AddTransition(tr);
                        }
                    }
                }
            }
            return(viterbiSearchGraph);
        }
 public static Pair <int[], double> BestSequenceWithLinearConstraints(ISequenceModel ts, double[][] linearConstraints)
 {
     return(BestSequence(ts, linearConstraints));
 }
        private static Pair<int[], Double> BestSequenceNew(ISequenceModel ts, double[][] linearConstraints)
        {
            int length = ts.Length();
            int leftWindow = ts.LeftWindow();
            int rightWindow = ts.RightWindow();
            int padLength = length + leftWindow + rightWindow;
            if (linearConstraints != null && linearConstraints.Length != padLength)
                throw new Exception(@"linearConstraints.length (" + linearConstraints.Length + @") does not match padLength (" + padLength + @") of SequenceModel" + @", length==" + length + @", leftW=" + leftWindow + @", rightW=" + rightWindow);
            int[][] tags = new int[padLength][];
            int[] tagNum = new int[padLength];
            if (DEBUG)
            {
                Console.Error.WriteLine(@"Doing bestSequence length " + length + @"; leftWin " + leftWindow + @"; rightWin " + rightWindow + @"; padLength " + padLength);
            }

            for (int pos = 0; pos < padLength; pos++)
            {
                tags[pos] = ts.GetPossibleValues(pos);
                tagNum[pos] = tags[pos].Length;
                if (DEBUG)
                {
                    Console.Error.WriteLine(@"There are " + tagNum[pos] + @" values at position " + pos + @": " + Arrays.ToString(tags[pos]));
                }
            }

            int[] tempTags = new int[padLength];
            int[] productSizes = new int[padLength];
            int curProduct = 1;
            for (int i = 0; i < leftWindow + rightWindow; i++)
            {
                curProduct *= tagNum[i];
            }

            for (int pos = leftWindow + rightWindow; pos < padLength; pos++)
            {
                if (pos > leftWindow + rightWindow)
                {
                    curProduct /= tagNum[pos - leftWindow - rightWindow - 1];
                }

                curProduct *= tagNum[pos];
                productSizes[pos - rightWindow] = curProduct;
            }

            double[][] windowScore = new double[padLength][];
            for (int pos = leftWindow; pos < leftWindow + length; pos++)
            {
                if (DEBUG)
                {
                    Console.Error.WriteLine(@"scoring word " + pos + @" / " + (leftWindow + length) + @", productSizes =  " + productSizes[pos] + @", tagNum = " + tagNum[pos] + @"...");
                }

                windowScore[pos] = new double[productSizes[pos]];
                Arrays.Fill(tempTags, tags[0][0]);
                if (DEBUG)
                {
                    Console.Error.WriteLine(@"windowScore[" + pos + @"] has size (productSizes[pos]) " + windowScore[pos].Length);
                }

                for (int product = 0; product < productSizes[pos]; product++)
                {
                    int p = product;
                    int shift = 1;
                    for (int curPos = pos + rightWindow; curPos >= pos - leftWindow; curPos--)
                    {
                        tempTags[curPos] = tags[curPos][p % tagNum[curPos]];
                        p /= tagNum[curPos];
                        if (curPos > pos)
                        {
                            shift *= tagNum[curPos];
                        }
                    }

                    if (tempTags[pos] == tags[pos][0])
                    {
                        double[] scores = ts.ScoresOf(tempTags, pos);
                        if (DEBUG)
                        {
                            Console.Error.WriteLine(@"Matched at array index [product] " + product + @"; tempTags[pos] == tags[pos][0] == " + tempTags[pos]);
                        }

                        if (DEBUG)
                        {
                            Console.Error.WriteLine(@"For pos " + pos + @" scores.length is " + scores.Length + @"; tagNum[pos] = " + tagNum[pos] + @"; windowScore[pos].length = " + windowScore[pos].Length);
                        }

                        if (DEBUG)
                        {
                            Console.Error.WriteLine(@"scores: " + Arrays.ToString(scores));
                        }

                        for (int t = 0; t < tagNum[pos]; t++)
                        {
                            if (DEBUG)
                            {
                                Console.Error.WriteLine(@"Setting value of windowScore[" + pos + @"][" + product + @"+" + t + @"*" + shift + @"] = " + scores[t]);
                            }

                            windowScore[pos][product + t * shift] = scores[t];
                        }
                    }
                }
            }

            double[][] score = new double[padLength][];
            int[][] trace = new int[padLength][];
            for (int pos = 0; pos < padLength; pos++)
            {
                score[pos] = new double[productSizes[pos]];
                trace[pos] = new int[productSizes[pos]];
            }

            for (int pos = leftWindow; pos < length + leftWindow; pos++)
            {
                for (int product = 0; product < productSizes[pos]; product++)
                {
                    if (pos == leftWindow)
                    {
                        score[pos][product] = windowScore[pos][product];
                        if (linearConstraints != null)
                        {
                            if (DEBUG && linearConstraints[pos][product % tagNum[pos]] != 0)
                                Console.Error.WriteLine(@"Applying linear constraints=" + linearConstraints[pos][product % tagNum[pos]] + @" to preScore=" + windowScore[pos][product] + @" at pos=" + pos + @" for tag=" + (product % tagNum[pos]));
                            score[pos][product] += linearConstraints[pos][product % tagNum[pos]];
                        }

                        trace[pos][product] = -1;
                    }
                    else
                    {
                        score[pos][product] = Double.NegativeInfinity;
                        trace[pos][product] = -1;
                        int sharedProduct = product / tagNum[pos + rightWindow];
                        int factor = productSizes[pos] / tagNum[pos + rightWindow];
                        for (int newTagNum = 0; newTagNum < tagNum[pos - leftWindow - 1]; newTagNum++)
                        {
                            int predProduct = newTagNum * factor + sharedProduct;
                            double predScore = score[pos - 1][predProduct] + windowScore[pos][product];
                            if (linearConstraints != null)
                            {
                                if (DEBUG && pos == 2 && linearConstraints[pos][product % tagNum[pos]] != 0)
                                {
                                    Console.Error.WriteLine(@"Applying linear constraints=" + linearConstraints[pos][product % tagNum[pos]] + @" to preScore=" + predScore + @" at pos=" + pos + @" for tag=" + (product % tagNum[pos]));
                                    Console.Error.WriteLine(@"predScore:" + predScore + @" = score[" + (pos - 1) + @"][" + predProduct + @"]:" + score[pos - 1][predProduct] + @" + windowScore[" + pos + @"][" + product + @"]:" + windowScore[pos][product]);
                                }

                                predScore += linearConstraints[pos][product % tagNum[pos]];
                            }

                            if (predScore > score[pos][product])
                            {
                                score[pos][product] = predScore;
                                trace[pos][product] = predProduct;
                            }
                        }
                    }
                }
            }

            double bestFinalScore = Double.NegativeInfinity;
            int bestCurrentProduct = -1;
            for (int product = 0; product < productSizes[leftWindow + length - 1]; product++)
            {
                if (score[leftWindow + length - 1][product] > bestFinalScore)
                {
                    bestCurrentProduct = product;
                    bestFinalScore = score[leftWindow + length - 1][product];
                }
            }

            int lastProduct = bestCurrentProduct;
            for (int last = padLength - 1; last >= length - 1 && last >= 0; last--)
            {
                tempTags[last] = tags[last][lastProduct % tagNum[last]];
                lastProduct /= tagNum[last];
            }

            for (int pos = leftWindow + length - 2; pos >= leftWindow; pos--)
            {
                int bestNextProduct = bestCurrentProduct;
                bestCurrentProduct = trace[pos + 1][bestNextProduct];
                tempTags[pos - leftWindow] = tags[pos - leftWindow][bestCurrentProduct / (productSizes[pos] / tagNum[pos - leftWindow])];
            }

            return new Pair<int[], Double>(tempTags, bestFinalScore);
        }
        private static int[] BestSequenceOld(ISequenceModel ts)
        {
            int length = ts.Length();
            int leftWindow = ts.LeftWindow();
            int rightWindow = ts.RightWindow();
            int padLength = length + leftWindow + rightWindow;
            int[][] tags = new int[padLength][];
            int[] tagNum = new int[padLength];
            for (int pos = 0; pos < padLength; pos++)
            {
                tags[pos] = ts.GetPossibleValues(pos);
                tagNum[pos] = tags[pos].Length;
            }

            int[] tempTags = new int[padLength];
            int[] productSizes = new int[padLength];
            int curProduct = 1;
            for (int i = 0; i < leftWindow + rightWindow; i++)
                curProduct *= tagNum[i];
            for (int pos = leftWindow + rightWindow; pos < padLength; pos++)
            {
                if (pos > leftWindow + rightWindow)
                    curProduct /= tagNum[pos - leftWindow - rightWindow - 1];
                curProduct *= tagNum[pos];
                productSizes[pos - rightWindow] = curProduct;
            }

            double[][] windowScore = new double[padLength][];
            for (int pos = leftWindow; pos < leftWindow + length; pos++)
            {
                windowScore[pos] = new double[productSizes[pos]];
                Arrays.Fill(tempTags, tags[0][0]);
                for (int product = 0; product < productSizes[pos]; product++)
                {
                    int p = product;
                    for (int curPos = pos + rightWindow; curPos >= pos - leftWindow; curPos--)
                    {
                        tempTags[curPos] = tags[curPos][p % tagNum[curPos]];
                        p /= tagNum[curPos];
                    }

                    windowScore[pos][product] = ts.ScoreOf(tempTags, pos);
                }
            }

            double[][] score = new double[padLength][];
            int[][] trace = new int[padLength][];
            for (int pos = 0; pos < padLength; pos++)
            {
                score[pos] = new double[productSizes[pos]];
                trace[pos] = new int[productSizes[pos]];
            }

            for (int pos = leftWindow; pos < length + leftWindow; pos++)
            {
                for (int product = 0; product < productSizes[pos]; product++)
                {
                    if (pos == leftWindow)
                    {
                        score[pos][product] = windowScore[pos][product];
                        trace[pos][product] = -1;
                    }
                    else
                    {
                        score[pos][product] = Double.NegativeInfinity;
                        trace[pos][product] = -1;
                        int sharedProduct = product / tagNum[pos + rightWindow];
                        int factor = productSizes[pos] / tagNum[pos + rightWindow];
                        for (int newTagNum = 0; newTagNum < tagNum[pos - leftWindow - 1]; newTagNum++)
                        {
                            int predProduct = newTagNum * factor + sharedProduct;
                            double predScore = score[pos - 1][predProduct] + windowScore[pos][product];
                            if (predScore > score[pos][product])
                            {
                                score[pos][product] = predScore;
                                trace[pos][product] = predProduct;
                            }
                        }
                    }
                }
            }

            double bestFinalScore = Double.NegativeInfinity;
            int bestCurrentProduct = -1;
            for (int product = 0; product < productSizes[leftWindow + length - 1]; product++)
            {
                if (score[leftWindow + length - 1][product] > bestFinalScore)
                {
                    bestCurrentProduct = product;
                    bestFinalScore = score[leftWindow + length - 1][product];
                }
            }

            int lastProduct = bestCurrentProduct;
            for (int last = padLength - 1; last >= length - 1; last--)
            {
                tempTags[last] = tags[last][lastProduct % tagNum[last]];
                lastProduct /= tagNum[last];
            }

            for (int pos = leftWindow + length - 2; pos >= leftWindow; pos--)
            {
                int bestNextProduct = bestCurrentProduct;
                bestCurrentProduct = trace[pos + 1][bestNextProduct];
                tempTags[pos - leftWindow] = tags[pos - leftWindow][bestCurrentProduct / (productSizes[pos] / tagNum[pos - leftWindow])];
            }

            return tempTags;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="AddElementCommand"/> class.
 /// </summary>
 /// <param name="sequenceModel">The timeline model.</param>
 /// <param name="layer">The layer where the element is beign added.</param>
 /// <param name="element">The element beign added.</param>
 public AddElementCommand(ISequenceModel sequenceModel, Track layer, TimelineElement element)
 {
     this.sequenceModel = sequenceModel;
     this.layer         = layer;
     this.element       = element;
 }
        /// <summary>
        /// Runs the Viterbi algorithm on the sequence model, and then proceeds to efficiently
        /// backwards decode the best k label sequence assignments.
        /// </summary>
        /// <remarks>
        /// Runs the Viterbi algorithm on the sequence model, and then proceeds to efficiently
        /// backwards decode the best k label sequence assignments.
        /// This sequence finder only works on SequenceModel's with rightWindow == 0.
        /// </remarks>
        /// <param name="ts">The SequenceModel to find the best k label sequence assignments of</param>
        /// <param name="k">The number of top-scoring assignments to find.</param>
        /// <returns>A Counter with k entries that map from a sequence assignment (int array) to a double score</returns>
        public virtual ICounter <int[]> KBestSequences(ISequenceModel ts, int k)
        {
            // Set up tag options
            int length      = ts.Length();
            int leftWindow  = ts.LeftWindow();
            int rightWindow = ts.RightWindow();

            if (rightWindow != 0)
            {
                throw new ArgumentException("KBestSequenceFinder only works with rightWindow == 0 not " + rightWindow);
            }
            int padLength = length + leftWindow + rightWindow;

            int[][] tags   = new int[padLength][];
            int[]   tagNum = new int[padLength];
            for (int pos = 0; pos < padLength; pos++)
            {
                tags[pos]   = ts.GetPossibleValues(pos);
                tagNum[pos] = tags[pos].Length;
            }
            int[] tempTags = new int[padLength];
            // Set up product space sizes
            int[] productSizes = new int[padLength];
            int   curProduct   = 1;

            for (int i = 0; i < leftWindow; i++)
            {
                curProduct *= tagNum[i];
            }
            for (int pos_1 = leftWindow; pos_1 < padLength; pos_1++)
            {
                if (pos_1 > leftWindow + rightWindow)
                {
                    curProduct /= tagNum[pos_1 - leftWindow - rightWindow - 1];
                }
                // shift off
                curProduct *= tagNum[pos_1];
                // shift on
                productSizes[pos_1 - rightWindow] = curProduct;
            }
            double[][] windowScore = new double[padLength][];
            // Score all of each window's options
            for (int pos_2 = leftWindow; pos_2 < leftWindow + length; pos_2++)
            {
                windowScore[pos_2] = new double[productSizes[pos_2]];
                Arrays.Fill(tempTags, tags[0][0]);
                for (int product = 0; product < productSizes[pos_2]; product++)
                {
                    int p     = product;
                    int shift = 1;
                    for (int curPos = pos_2; curPos >= pos_2 - leftWindow; curPos--)
                    {
                        tempTags[curPos] = tags[curPos][p % tagNum[curPos]];
                        p /= tagNum[curPos];
                        if (curPos > pos_2)
                        {
                            shift *= tagNum[curPos];
                        }
                    }
                    if (tempTags[pos_2] == tags[pos_2][0])
                    {
                        // get all tags at once
                        double[] scores = ts.ScoresOf(tempTags, pos_2);
                        // fill in the relevant windowScores
                        for (int t = 0; t < tagNum[pos_2]; t++)
                        {
                            windowScore[pos_2][product + t * shift] = scores[t];
                        }
                    }
                }
            }
            // Set up score and backtrace arrays
            double[][][] score         = new double[padLength][][];
            int[][][][]  trace         = new int[padLength][][][];
            int[][]      numWaysToMake = new int[padLength][];
            for (int pos_3 = 0; pos_3 < padLength; pos_3++)
            {
                score[pos_3] = new double[productSizes[pos_3]][];
                trace[pos_3] = new int[productSizes[pos_3]][][];
                // the 2 is for backtrace, and which of the k best for that backtrace
                numWaysToMake[pos_3] = new int[productSizes[pos_3]];
                Arrays.Fill(numWaysToMake[pos_3], 1);
                for (int product = 0; product < productSizes[pos_3]; product++)
                {
                    if (pos_3 > leftWindow)
                    {
                        // loop over possible predecessor types
                        int sharedProduct = product / tagNum[pos_3];
                        int factor        = productSizes[pos_3] / tagNum[pos_3];
                        numWaysToMake[pos_3][product] = 0;
                        for (int newTagNum = 0; newTagNum < tagNum[pos_3 - leftWindow - 1] && numWaysToMake[pos_3][product] < k; newTagNum++)
                        {
                            int predProduct = newTagNum * factor + sharedProduct;
                            numWaysToMake[pos_3][product] += numWaysToMake[pos_3 - 1][predProduct];
                        }
                        if (numWaysToMake[pos_3][product] > k)
                        {
                            numWaysToMake[pos_3][product] = k;
                        }
                    }
                    score[pos_3][product] = new double[numWaysToMake[pos_3][product]];
                    Arrays.Fill(score[pos_3][product], double.NegativeInfinity);
                    trace[pos_3][product] = new int[numWaysToMake[pos_3][product]][];
                    Arrays.Fill(trace[pos_3][product], new int[] { -1, -1 });
                }
            }
            // Do forward Viterbi algorithm
            // this is the hottest loop, so cache loop control variables hoping for a little speed....
            // loop over the classification spot
            for (int pos_4 = leftWindow; pos_4 < posMax; pos_4++)
            {
                // loop over window product types
                for (int product = 0; product < productMax; product++)
                {
                    // check for initial spot
                    double[] scorePos = score[pos_4][product];
                    int[][]  tracePos = trace[pos_4][product];
                    if (pos_4 == leftWindow)
                    {
                        // no predecessor type
                        scorePos[0] = windowScore[pos_4][product];
                    }
                    else
                    {
                        // loop over possible predecessor types/k-best
                        int sharedProduct = product / tagNum[pos_4 + rightWindow];
                        int factor        = productSizes[pos_4] / tagNum[pos_4 + rightWindow];
                        for (int newTagNum = 0; newTagNum < maxTagNum; newTagNum++)
                        {
                            int      predProduct  = newTagNum * factor + sharedProduct;
                            double[] scorePosPrev = score[pos_4 - 1][predProduct];
                            for (int k1 = 0; k1 < scorePosPrev.Length; k1++)
                            {
                                double predScore = scorePosPrev[k1] + windowScore[pos_4][product];
                                if (predScore > scorePos[0])
                                {
                                    // new value higher then lowest value we should keep
                                    int k2 = Arrays.BinarySearch(scorePos, predScore);
                                    k2 = k2 < 0 ? -k2 - 2 : k2 - 1;
                                    // open a spot at k2 by shifting off the lowest value
                                    System.Array.Copy(scorePos, 1, scorePos, 0, k2);
                                    System.Array.Copy(tracePos, 1, tracePos, 0, k2);
                                    scorePos[k2] = predScore;
                                    tracePos[k2] = new int[] { predProduct, k1 };
                                }
                            }
                        }
                    }
                }
            }
            // Project the actual tag sequence
            int[]    whichDerivation     = new int[k];
            int[]    bestCurrentProducts = new int[k];
            double[] bestFinalScores     = new double[k];
            Arrays.Fill(bestFinalScores, double.NegativeInfinity);
            // just the last guy
            for (int product_1 = 0; product_1 < productSizes[padLength - 1]; product_1++)
            {
                double[] scorePos = score[padLength - 1][product_1];
                for (int k1 = scorePos.Length - 1; k1 >= 0 && scorePos[k1] > bestFinalScores[0]; k1--)
                {
                    int k2 = Arrays.BinarySearch(bestFinalScores, scorePos[k1]);
                    k2 = k2 < 0 ? -k2 - 2 : k2 - 1;
                    // open a spot at k2 by shifting off the lowest value
                    System.Array.Copy(bestFinalScores, 1, bestFinalScores, 0, k2);
                    System.Array.Copy(whichDerivation, 1, whichDerivation, 0, k2);
                    System.Array.Copy(bestCurrentProducts, 1, bestCurrentProducts, 0, k2);
                    bestCurrentProducts[k2] = product_1;
                    whichDerivation[k2]     = k1;
                    bestFinalScores[k2]     = scorePos[k1];
                }
            }
            ClassicCounter <int[]> kBestWithScores = new ClassicCounter <int[]>();

            for (int k1_1 = k - 1; k1_1 >= 0 && bestFinalScores[k1_1] > double.NegativeInfinity; k1_1--)
            {
                int lastProduct = bestCurrentProducts[k1_1];
                for (int last = padLength - 1; last >= length - 1 && last >= 0; last--)
                {
                    tempTags[last] = tags[last][lastProduct % tagNum[last]];
                    lastProduct   /= tagNum[last];
                }
                for (int pos_5 = leftWindow + length - 2; pos_5 >= leftWindow; pos_5--)
                {
                    int bestNextProduct = bestCurrentProducts[k1_1];
                    bestCurrentProducts[k1_1]    = trace[pos_5 + 1][bestNextProduct][whichDerivation[k1_1]][0];
                    whichDerivation[k1_1]        = trace[pos_5 + 1][bestNextProduct][whichDerivation[k1_1]][1];
                    tempTags[pos_5 - leftWindow] = tags[pos_5 - leftWindow][bestCurrentProducts[k1_1] / (productSizes[pos_5] / tagNum[pos_5 - leftWindow])];
                }
                kBestWithScores.SetCount(Arrays.CopyOf(tempTags, tempTags.Length), bestFinalScores[k1_1]);
            }
            return(kBestWithScores);
        }
        public virtual int[] BestSequence(ISequenceModel ts, int size)
        {
            // Set up tag options
            int length      = ts.Length();
            int leftWindow  = ts.LeftWindow();
            int rightWindow = ts.RightWindow();
            int padLength   = length + leftWindow + rightWindow;

            int[][] tags   = new int[padLength][];
            int[]   tagNum = new int[padLength];
            for (int pos = 0; pos < padLength; pos++)
            {
                tags[pos]   = ts.GetPossibleValues(pos);
                tagNum[pos] = tags[pos].Length;
            }
            Beam newBeam = new Beam(beamSize, ScoredComparator.AscendingComparator);

            BeamBestSequenceFinder.TagSeq initSeq = new BeamBestSequenceFinder.TagSeq();
            newBeam.Add(initSeq);
            for (int pos_1 = 0; pos_1 < padLength; pos_1++)
            {
                if (Thread.Interrupted())
                {
                    // Allow interrupting
                    throw new RuntimeInterruptedException();
                }
                //System.out.println("scoring word " + pos + " / " + (leftWindow + length) + ", tagNum = " + tagNum[pos] + "...");
                //System.out.flush();
                Beam oldBeam = newBeam;
                if (pos_1 < leftWindow + rightWindow && exhaustiveStart)
                {
                    newBeam = new Beam(100000, ScoredComparator.AscendingComparator);
                }
                else
                {
                    newBeam = new Beam(beamSize, ScoredComparator.AscendingComparator);
                }
                // each hypothesis gets extended and beamed
                foreach (object anOldBeam in oldBeam)
                {
                    if (Thread.Interrupted())
                    {
                        // Allow interrupting
                        throw new RuntimeInterruptedException();
                    }
                    // System.out.print("#"); System.out.flush();
                    BeamBestSequenceFinder.TagSeq tagSeq = (BeamBestSequenceFinder.TagSeq)anOldBeam;
                    for (int nextTagNum = 0; nextTagNum < tagNum[pos_1]; nextTagNum++)
                    {
                        BeamBestSequenceFinder.TagSeq nextSeq = tagSeq.Tclone();
                        if (pos_1 >= leftWindow + rightWindow)
                        {
                            nextSeq.ExtendWith(tags[pos_1][nextTagNum], ts, size);
                        }
                        else
                        {
                            nextSeq.ExtendWith(tags[pos_1][nextTagNum]);
                        }
                        //System.out.println("Created: "+nextSeq.score()+" %% "+arrayToString(nextSeq.tags(), nextSeq.size()));
                        newBeam.Add(nextSeq);
                    }
                }
                //		System.out.println("Beam size: "+newBeam.size()+" of "+beamSize);
                //System.out.println("Best is: "+((Scored)newBeam.iterator().next()).score());
                // System.out.println(" done");
                if (recenter)
                {
                    double max = double.NegativeInfinity;
                    foreach (object aNewBeam1 in newBeam)
                    {
                        BeamBestSequenceFinder.TagSeq tagSeq = (BeamBestSequenceFinder.TagSeq)aNewBeam1;
                        if (tagSeq.score > max)
                        {
                            max = tagSeq.score;
                        }
                    }
                    foreach (object aNewBeam in newBeam)
                    {
                        BeamBestSequenceFinder.TagSeq tagSeq = (BeamBestSequenceFinder.TagSeq)aNewBeam;
                        tagSeq.score -= max;
                    }
                }
            }
            try
            {
                BeamBestSequenceFinder.TagSeq bestSeq = (BeamBestSequenceFinder.TagSeq)newBeam.GetEnumerator().Current;
                int[] seq = bestSeq.Tags();
                return(seq);
            }
            catch (NoSuchElementException)
            {
                log.Info("Beam empty -- no best sequence.");
                return(null);
            }
        }
 public virtual void ExtendWith(int tag, ISequenceModel ts, int s)
 {
     ExtendWith(tag);
     int[] tags = TmpTags(ts.LeftWindow() + 1 + ts.RightWindow(), s);
     score += ts.ScoreOf(tags, Size() - ts.RightWindow() - 1);
 }
 public virtual void ExtendWith(int tag, ISequenceModel ts, int s)
 {
     ExtendWith(tag);
     int[] tags = TmpTags(ts.LeftWindow() + 1 + ts.RightWindow(), s);
     score += ts.ScoreOf(tags, Size() - ts.RightWindow() - 1);
 }
        public virtual int[] BestSequence(ISequenceModel ts, int size)
        {
            int length = ts.Length();
            int leftWindow = ts.LeftWindow();
            int rightWindow = ts.RightWindow();
            int padLength = length + leftWindow + rightWindow;
            int[][] tags = new int[padLength][];
            int[] tagNum = new int[padLength];
            for (int pos = 0; pos < padLength; pos++)
            {
                tags[pos] = ts.GetPossibleValues(pos);
                tagNum[pos] = tags[pos].Length;
            }

            var newBeam = new Beam<TagSeq>(beamSize, ScoredComparator.ASCENDING_COMPARATOR);
            TagSeq initSeq = new TagSeq();
            newBeam.Add(initSeq);
            for (int pos = 0; pos < padLength; pos++)
            {
                var oldBeam = newBeam;
                if (pos < leftWindow + rightWindow && exhaustiveStart)
                {
                    newBeam = new Beam<TagSeq>(100000, ScoredComparator.ASCENDING_COMPARATOR);
                }
                else
                {
                    newBeam = new Beam<TagSeq>(beamSize, ScoredComparator.ASCENDING_COMPARATOR);
                }

                for (IEnumerator beamI = oldBeam.GetEnumerator(); beamI.MoveNext(); )
                {
                    Console.Out.Write(@"#");
                    Console.Out.Flush();
                    TagSeq tagSeq = (TagSeq)beamI.Current;
                    for (int nextTagNum = 0; nextTagNum < tagNum[pos]; nextTagNum++)
                    {
                        TagSeq nextSeq = tagSeq.Tclone();
                        if (pos >= leftWindow + rightWindow)
                        {
                            nextSeq.ExtendWith(tags[pos][nextTagNum], ts, size);
                        }
                        else
                        {
                            nextSeq.ExtendWith(tags[pos][nextTagNum]);
                        }

                        newBeam.Add(nextSeq);
                    }
                }

                Console.Out.WriteLine(@" done");
                if (recenter)
                {
                    double max = Double.NegativeInfinity;
                    for (IEnumerator beamI = newBeam.GetEnumerator(); beamI.MoveNext(); )
                    {
                        TagSeq tagSeq = (TagSeq)beamI.Current;
                        if (tagSeq.score > max)
                        {
                            max = tagSeq.score;
                        }
                    }

                    for (IEnumerator beamI = newBeam.GetEnumerator(); beamI.MoveNext(); )
                    {
                        TagSeq tagSeq = (TagSeq)beamI.Current;
                        tagSeq.score -= max;
                    }
                }
            }

            try
            {
                var enumerator = newBeam.GetEnumerator();
                if (enumerator.MoveNext())
                {
                    TagSeq bestSeq = enumerator.Current;
                    int[] seq = bestSeq.Tags();
                    return seq;
                }
                else
                    return null;
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(@"Beam empty -- no best sequence.");
                return null;
            }
        }
 public virtual int[] BestSequence(ISequenceModel ts)
 {
     if (useOld)
     {
         return BestSequenceOld(ts);
     }
     else
     {
         return BestSequenceNew(ts);
     }
 }
 // end class TagSeq
 public virtual int[] BestSequence(ISequenceModel ts)
 {
     return(BestSequence(ts, (1024 * 128)));
 }
 /// <summary>
 /// Runs the Viterbi algorithm on the sequence model given by the TagScorer
 /// in order to find the best sequence.
 /// </summary>
 /// <param name="ts">The SequenceModel to be used for scoring</param>
 /// <returns>An array containing the int tags of the best sequence</returns>
 public virtual int[] BestSequence(ISequenceModel ts)
 {
     return(BestSequence(ts, null).First());
 }