Accord.Statistics.Models.Markov.Hybrid.HybridMarkovModel.Decode C# (CSharp) Method

Decode() public method

Calculates the most likely sequence of hidden states that produced the given observation sequence.
Decoding problem. Given the HMM M = (A, B, pi) and the observation sequence O = {o1,o2, ..., oK}, calculate the most likely sequence of hidden states Si that produced this observation sequence O. This can be computed efficiently using the Viterbi algorithm.
public Decode ( double observations, double &logLikelihood ) : int[]
observations double /// A sequence of observations.
logLikelihood double /// The state optimized probability.
return int[]
        public int[] Decode(double[][] observations, out double logLikelihood)
        {
            if (observations == null)
                throw new ArgumentNullException("observations");

            if (observations.Length == 0)
            {
                logLikelihood = Double.NegativeInfinity;
                return new int[0];
            }


            // Viterbi-forward algorithm.
            int T = observations.Length;
            int states = States;
            int maxState;
            double maxWeight;
            double weight;

            int[,] s = new int[states, T];
            double[,] lnFwd = new double[states, T];
            double[][] output = new double[states][];


            // Base
            output[0] = Function(-1, observations[0]);
            for (int i = 0; i < states; i++)
                lnFwd[i, 0] = output[0][i];

            // Induction
            for (int t = 1; t < T; t++)
            {
                double[] observation = observations[t];

                for (int i = 0; i < States; i++)
                    output[i] = Function(i, observation);

                for (int j = 0; j < states; j++)
                {
                    maxState = 0;
                    maxWeight = lnFwd[0, t - 1] + output[0][j];

                    for (int i = 1; i < states; i++)
                    {
                        weight = lnFwd[i, t - 1] + output[i][j];

                        if (weight > maxWeight)
                        {
                            maxState = i;
                            maxWeight = weight;
                        }
                    }

                    lnFwd[j, t] = maxWeight;
                    s[j, t] = maxState;
                }
            }


            // Find maximum value for time T-1
            maxState = 0;
            maxWeight = lnFwd[0, T - 1];

            for (int i = 1; i < states; i++)
            {
                if (lnFwd[i, T - 1] > maxWeight)
                {
                    maxState = i;
                    maxWeight = lnFwd[i, T - 1];
                }
            }


            // Trackback
            int[] path = new int[T];
            path[T - 1] = maxState;

            for (int t = T - 2; t >= 0; t--)
                path[t] = s[path[t + 1], t + 1];


            // Returns the sequence probability as an out parameter
            logLikelihood = maxWeight;

            // Returns the most likely (Viterbi path) for the given sequence
            return path;
        }