/// <inheritdoc/> public MultiRepresentationWeightFunction <TDictionary> Sum(IEnumerable <MultiRepresentationWeightFunction <TDictionary> > weightFunctions) { var dictionary = new Dictionary <TSequence, Weight>(MaxDictionarySize, SequenceManipulator.SequenceEqualityComparer); bool resultFitsDictionary = true; foreach (var weightFunction in weightFunctions) { if (weightFunction.IsCanonicZero()) { continue; } if (weightFunction.weightFunction is PointMassWeightFunction pointMass) { if (dictionary.TryGetValue(pointMass.Point, out Weight oldWeight)) { dictionary[pointMass.Point] = oldWeight + Weight.One; } else if (dictionary.Count < MaxDictionarySize) { dictionary.Add(pointMass.Point, Weight.One); } else { resultFitsDictionary = false; break; } } else if (weightFunction.weightFunction is TDictionary wfDictionary) { foreach (var kvp in wfDictionary.Dictionary) { if (dictionary.TryGetValue(kvp.Key, out Weight oldWeight)) { dictionary[kvp.Key] = oldWeight + kvp.Value; } else if (dictionary.Count < MaxDictionarySize) { dictionary.Add(kvp.Key, kvp.Value); } else { resultFitsDictionary = false; break; } } if (!resultFitsDictionary) { break; } } else { resultFitsDictionary = false; break; } } if (resultFitsDictionary) { if (dictionary.Count == 0) { return(Zero()); } if (dictionary.Count == 1) { var singleKvp = dictionary.Single(); if (singleKvp.Value.LogValue == 0.0) { return(FromPoint(singleKvp.Key)); } } return(FromDictionary(DictionaryWeightFunction <TDictionary> .FromDistinctWeights(dictionary))); } var automaton = Automaton <TSequence, TElement, TElementDistribution, TSequenceManipulator, TAutomaton> .Sum(weightFunctions.Select(wf => wf.AsAutomaton())); return(FromAutomaton(automaton)); }