internal void GetBestTagSequence(IList <FeatureVector> vectors, out int[] sysClasses, out double[] distribution) { // Since we are working with logarithmic numbers, we want the weight of the root node to be zero. var beam = new BeamSearch <IdValuePair <double> >(0D); for (int beamDepth = 0; beamDepth < vectors.Count; beamDepth++) { Debug.Assert(beam.Level[beamDepth].Count > 0); foreach (BeamNode <IdValuePair <double> > node in beam.Level[beamDepth]) { double[] probs_v_c = new double[classToClassId.Count]; for (int c_i = 0; c_i < classToClassId.Count; c_i++) { probs_v_c[c_i] = CalculateProbability_v_c(vectors[beamDepth], c_i, node, beamDepth); } NormalizationHelper.NormalizeLogs(probs_v_c, Math.E); // Prune: Idenitify N classes with highest probability: IList <int> topNClasses = SearchHelper.GetMaxNItems(topN, probs_v_c); for (int topN_i = 0; topN_i < topNClasses.Count; topN_i++) { int c_i = topNClasses[topN_i]; double prob = probs_v_c[c_i]; node.AddNextNode(new IdValuePair <double>(c_i, prob), Math.Log(prob, Math.E) + node.Weight); } } beam.Prune(topK, beam_size); } // Repackage the sequence we just received in such a way that the consuming code will find it most digestable. var results = beam.GetBestSequence(); sysClasses = new int[results.Length]; distribution = new double[results.Length]; for (int i = 0; i < results.Length; i++) { sysClasses[i] = results[i].Id; distribution[i] = results[i].Value; } }