public override void DoWork() //based on https://en.wikipedia.org/wiki/Viterbi_algorithm#Pseudocode { base.DoWork(); delta = new Dictionary <TState, StateWithProbability[]>(); Output = new TState[T]; foreach (var iState in StateSpace) { delta[iState] = new StateWithProbability[T]; delta[iState][0] = new StateWithProbability(iState, Math.Log(InitialProbabilitiesOfStates[iState])); } for (var t = 1; t < T; t++) { foreach (var iState in StateSpace) { delta[iState][t] = max(t, iState); } } Output[T - 1] = delta.Aggregate((a, b) => a.Value[T - 1].Probability > b.Value[T - 1].Probability ? a : b).Key; for (var i = T - 1; i > 0; i--) { Output[i - 1] = delta[Output[i]][i].State; } }
private StateWithProbability max(int t, TState iState) { var max = new StateWithProbability(default(TState), double.MinValue); foreach (var jState in StateSpace) { var value = delta[jState][t - 1].Probability + Math.Log(TransitionMatrix[jState, iState]) + Math.Log(EmissionMatrix[iState, SequenceOfObservations[t]]); if (value <= max.Probability) { continue; } max = new StateWithProbability(jState, value); } return(max); }