/// <summary> /// Executes Viterbi in a loop , every loop begins with new updated parameters /// </summary> public List <ViterbiResult> ExecuteViterbiAndTrain(int executionCount) { var resultsCollection = new List <ViterbiResult>(); Stopwatch timer = new Stopwatch(); timer.Restart(); for (int i = 1; i <= executionCount; i++) { ViterbiResult result = FindViterbiProbabilityScoreAndPath(); resultsCollection.Add(result); this.parameters.UpdateParameters(result); } timer.Stop(); Console.WriteLine("Timetaken: {0}", timer.ElapsedMilliseconds); return(resultsCollection); }
/// <summary> /// Updates parameters given the viterbi result. /// </summary> public abstract void UpdateParameters(ViterbiResult result);
/// <summary> /// Takes Viterbi matrix element corresponding to maximum probability and maximum probability and computes /// a)StateRepresentation( FFFLLLFFFL as in dice roll example ) /// b)All the sub sequences an starting indexes ending at all the states in the model. /// c)Probability score. /// </summary> ViterbiResult ViterbiTraceback(ViterbiMatrixElement traceBackProbabilityElement, double traceBackProbability) { var stateSequences = new Dictionary <int, List <ViterbiStateSequence> >(); var statePath = new StringBuilder(); var subSequence = new StringBuilder[this.parameters.StateIndices.Count]; var startIndex = new int[this.parameters.StateIndices.Count]; // Loop till we reach end of traceback list. while (traceBackProbabilityElement != null) { // Add to state identifiers , we will reverse it at the end. statePath.Append(traceBackProbabilityElement.StateIdentifier); foreach (KeyValuePair <int, char> item in this.parameters.StateIndices) { if (!stateSequences.ContainsKey(item.Key)) { stateSequences[item.Key] = new List <ViterbiStateSequence>(); subSequence[item.Key] = new StringBuilder(); } if (traceBackProbabilityElement.StateIdentifier == item.Value) { // Start constructing subsequences at a given state. Again , we will reverse it at the end to align with input. // Genomic indexes are 1 based. Increment the zero based index to reflect this convention. startIndex[item.Key] = traceBackProbabilityElement.EmissionValueIndex + 1;; subSequence[item.Key].Append(traceBackProbabilityElement.EmissionValue); } else { // Add to subsequence list per state once we are at the end of subsequence ( when state corresponding to matrix element is different ) if (subSequence[item.Key].Length > 0) { stateSequences[item.Key].Add( new ViterbiStateSequence { Index = startIndex[item.Key], StateSequence = new string(subSequence[item.Key].ToString().ToCharArray().Reverse().ToArray()) }); //Reset the index and sequence variable startIndex[item.Key] = 0; subSequence[item.Key].Clear(); } } // If we are going to reach end of traceback then add the current calculated subsequence. if (traceBackProbabilityElement.ContributingPredecessor == null && subSequence[item.Key].Length > 0) { stateSequences[item.Key].Add( new ViterbiStateSequence { Index = startIndex[item.Key], StateSequence = new string(subSequence[item.Key].ToString().ToCharArray().Reverse().ToArray()) }); } } traceBackProbabilityElement = traceBackProbabilityElement.ContributingPredecessor; } // Construct the result. var result = new ViterbiResult() { ProbabilityScore = traceBackProbability, StateTransitionRepresentaton = new string(statePath.ToString().ToCharArray().Reverse().ToArray()), ParametersUsed = this.parameters.Clone() }; // Add all the state subsequences. result.StateSequences = stateSequences; return(result); }