/// <summary> /// Adds an epsilon-loop with a specified number of intermediate states to a given state. /// </summary> /// <param name="state">The state.</param> /// <param name="loopSize">The number of intermediate states in the loop.</param> /// <param name="loopWeight">The weight of the loop.</param> private static void AddEpsilonLoop(StringAutomaton.State state, int loopSize, double loopWeight) { StringAutomaton.State currentState = state; for (int i = 0; i <= loopSize; ++i) { currentState = currentState.AddEpsilonTransition( i == 0 ? Weight.FromValue(loopWeight) : Weight.One, i == loopSize ? state : null); } }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="SingleOp"]/message_doc[@name="CharacterAverageConditional(StringDistribution)"]/*'/> public static DiscreteChar CharacterAverageConditional(StringDistribution str) { Argument.CheckIfNotNull(str, "str"); if (str.IsPointMass) { return(CharacterAverageConditional(str.Point)); } Vector resultLogProb = PiecewiseVector.Constant(char.MaxValue + 1, double.NegativeInfinity); StringAutomaton probFunc = str.GetWorkspaceOrPoint(); StringAutomaton.EpsilonClosure startEpsilonClosure = new Automaton <string, char, DiscreteChar, StringManipulator, StringAutomaton> .EpsilonClosure(probFunc, probFunc.Start); for (int stateIndex = 0; stateIndex < startEpsilonClosure.Size; ++stateIndex) { StringAutomaton.State state = startEpsilonClosure.GetStateByIndex(stateIndex); Weight stateLogWeight = startEpsilonClosure.GetStateWeightByIndex(stateIndex); foreach (var transition in state.Transitions) { if (!transition.IsEpsilon) { StringAutomaton.State destState = probFunc.States[transition.DestinationStateIndex]; StringAutomaton.EpsilonClosure destStateClosure = new Automaton <string, char, DiscreteChar, StringManipulator, StringAutomaton> .EpsilonClosure(probFunc, destState); if (!destStateClosure.EndWeight.IsZero) { Weight weight = Weight.Product(stateLogWeight, transition.Weight, destStateClosure.EndWeight); var logProbs = transition.ElementDistribution.Value.GetProbs(); logProbs.SetToFunction(logProbs, Math.Log); resultLogProb = LogSumExp(resultLogProb, logProbs, weight); } } } } if (resultLogProb.All(double.IsNegativeInfinity)) { throw new AllZeroException("An input distribution assigns zero probability to all single character strings."); } Vector resultProb = PiecewiseVector.Zero(char.MaxValue + 1); double logNormalizer = resultLogProb.LogSumExp(); resultProb.SetToFunction(resultLogProb, lp => Math.Exp(lp - logNormalizer)); return(DiscreteChar.FromVector(resultProb)); }
/// <summary>EP message to <c>character</c>.</summary> /// <param name="str">Incoming message from <c>str</c>.</param> /// <returns>The outgoing EP message to the <c>character</c> argument.</returns> /// <remarks> /// <para>The outgoing message is a distribution matching the moments of <c>character</c> as the random arguments are varied. The formula is <c>proj[p(character) sum_(str) p(str) factor(character,str)]/p(character)</c>.</para> /// </remarks> public static DiscreteChar CharacterAverageConditional(StringDistribution str) { Argument.CheckIfNotNull(str, "str"); Vector resultlogProb = PiecewiseVector.Constant(char.MaxValue + 1, double.NegativeInfinity); StringAutomaton probFunc = str.GetProbabilityFunction(); StringAutomaton.EpsilonClosure startEpsilonClosure = probFunc.Start.GetEpsilonClosure(); for (int stateIndex = 0; stateIndex < startEpsilonClosure.Size; ++stateIndex) { StringAutomaton.State state = startEpsilonClosure.GetStateByIndex(stateIndex); double stateLogWeight = startEpsilonClosure.GetStateLogWeightByIndex(stateIndex); for (int transitionIndex = 0; transitionIndex < state.Transitions.Count; ++transitionIndex) { StringAutomaton.Transition transition = state.Transitions[transitionIndex]; if (!transition.IsEpsilon) { StringAutomaton.State destState = probFunc.States[transition.DestinationStateIndex]; StringAutomaton.EpsilonClosure destStateClosure = destState.GetEpsilonClosure(); if (!double.IsNegativeInfinity(destStateClosure.EndLogWeight)) { double logWeight = stateLogWeight + transition.LogWeight + destStateClosure.EndLogWeight; resultlogProb = LogSumExp(resultlogProb, transition.ElementDistribution.GetInternalDiscrete().GetLogProbs(), logWeight); } } } } if (resultlogProb.All(double.IsNegativeInfinity)) { throw new AllZeroException("An input distribution assigns zero probability to all single character strings."); } Vector resultProb = PiecewiseVector.Zero(char.MaxValue + 1); resultProb.SetToFunction(resultlogProb, Math.Exp); return(DiscreteChar.FromVector(resultProb)); }