public ViterbiCalculator(IMLDataSet oseq, HiddenMarkovModel hmm)
        {
            if (oseq.Count < 1)
            {
                throw new EncogError("Must not have empty sequence");
            }

            this.delta          = EngineArray.AllocateDouble2D((int)oseq.Count, hmm.StateCount);
            this.psy            = EngineArray.AllocateInt2D((int)oseq.Count, hmm.StateCount);
            this._stateSequence = new int[oseq.Count];

            for (int i = 0; i < hmm.StateCount; i++)
            {
                this.delta[0][i] = -Math.Log(hmm.GetPi(i))
                                   - Math.Log(hmm.StateDistributions[i].Probability(
                                                  oseq[0]));
                this.psy[0][i] = 0;
            }

            int t = 1;

            for (int index = 1; index < oseq.Count; index++)
            {
                IMLDataPair observation = oseq[index];

                for (int i = 0; i < hmm.StateCount; i++)
                {
                    ComputeStep(hmm, observation, t, i);
                }

                t++;
            }

            this.lnProbability = Double.PositiveInfinity;
            for (int i = 0; i < hmm.StateCount; i++)
            {
                double thisProbability = this.delta[oseq.Count - 1][i];

                if (this.lnProbability > thisProbability)
                {
                    this.lnProbability             = thisProbability;
                    _stateSequence[oseq.Count - 1] = i;
                }
            }
            this.lnProbability = -this.lnProbability;

            for (int t2 = (int)(oseq.Count - 2); t2 >= 0; t2--)
            {
                _stateSequence[t2] = this.psy[t2 + 1][_stateSequence[t2 + 1]];
            }
        }