public TranslationResult Merge(int prefixCount, double threshold, TranslationResult otherResult) { var mergedTargetSegment = new List <string>(); var mergedConfidences = new List <double>(); var mergedSources = new List <TranslationSources>(); var mergedAlignment = new HashSet <Tuple <int, int> >(); for (int j = 0; j < TargetSegment.Count; j++) { int[] sourceIndices = Alignment.GetColumnAlignedIndices(j).ToArray(); if (sourceIndices.Length == 0) { // target word doesn't align with anything mergedTargetSegment.Add(TargetSegment[j]); mergedConfidences.Add(WordConfidences[j]); mergedSources.Add(WordSources[j]); } else { // target word aligns with some source words if (j < prefixCount || WordConfidences[j] >= threshold) { // use target word of this result mergedTargetSegment.Add(TargetSegment[j]); mergedConfidences.Add(WordConfidences[j]); TranslationSources sources = WordSources[j]; foreach (int i in sourceIndices) { // combine sources for any words that both this result // and the other result translated the same foreach (int jOther in otherResult.Alignment.GetRowAlignedIndices(i)) { TranslationSources otherSources = otherResult.WordSources[jOther]; if (otherSources != TranslationSources.None && otherResult.TargetSegment[jOther] == TargetSegment[j]) { sources |= otherSources; } } mergedAlignment.Add(Tuple.Create(i, mergedTargetSegment.Count - 1)); } mergedSources.Add(sources); } else { // use target words of other result bool found = false; foreach (int i in sourceIndices) { foreach (int jOther in otherResult.Alignment.GetRowAlignedIndices(i)) { // look for any translated words from other result TranslationSources otherSources = otherResult.WordSources[jOther]; if (otherSources != TranslationSources.None) { mergedTargetSegment.Add(otherResult.TargetSegment[jOther]); mergedConfidences.Add(otherResult.WordConfidences[jOther]); mergedSources.Add(otherSources); mergedAlignment.Add(Tuple.Create(i, mergedTargetSegment.Count - 1)); found = true; } } } if (!found) { // the other result had no translated words, so just use this result's target word mergedTargetSegment.Add(TargetSegment[j]); mergedConfidences.Add(WordConfidences[j]); mergedSources.Add(WordSources[j]); foreach (int i in sourceIndices) { mergedAlignment.Add(Tuple.Create(i, mergedTargetSegment.Count - 1)); } } } } } var alignment = new WordAlignmentMatrix(SourceSegment.Count, mergedTargetSegment.Count); foreach (Tuple <int, int> t in mergedAlignment) { alignment[t.Item1, t.Item2] = true; } return(new TranslationResult(SourceSegment, mergedTargetSegment, mergedConfidences, mergedSources, alignment, Phrases)); }