/// <summary>EP message to <c>str</c>.</summary> /// <param name="format">Incoming message from <c>format</c>.</param> /// <param name="args">Incoming message from <c>args</c>.</param> /// <returns>The outgoing EP message to the <c>str</c> argument.</returns> /// <remarks> /// <para>The outgoing message is a distribution matching the moments of <c>str</c> as the random arguments are varied. The formula is <c>proj[p(str) sum_(format,args) p(format,args) factor(str,format,args)]/p(str)</c>.</para> /// </remarks> public static StringDistribution StrAverageConditional(StringDistribution format, IList <StringDistribution> args) { Argument.CheckIfNotNull(format, "format"); Argument.CheckIfNotNull(args, "args"); Argument.CheckIfValid(args.Count > 0, "args", "There must be at least one argument provided."); // TODO: relax? if (args.Count >= 10) { throw new NotImplementedException("Up to 10 arguments currently supported."); } // Disallow special characters in args or format StringAutomaton result = DisallowBraceReplacersTransducer.ProjectSource(format); List <StringAutomaton> escapedArgs = args.Select(DisallowBraceReplacersTransducer.ProjectSource).ToList(); // Check braces for correctness and replace them with special characters. // Also, make sure that each argument placeholder is present exactly once. // Superposition of transducers is used instead of a single transducer to allow for any order of arguments. // TODO: in case of a single argument, argument escaping stage can be skipped for (int i = 0; i < args.Count; ++i) { result = GetArgumentEscapingTransducer(i, args.Count, false).ProjectSource(result); } // Now replace placeholders with arguments result = GetPlaceholderReplacingTransducer(escapedArgs, false).ProjectSource(result); return(StringDistribution.FromWorkspace(result)); }
/// <summary> /// Tests if a transducer projects each of given strings to a zero function. /// </summary> /// <param name="transducer">The transducer.</param> /// <param name="strings">The strings to test.</param> public static void TestIfTransducerRejects(StringTransducer transducer, params string[] strings) { foreach (string str in strings) { var res = transducer.ProjectSource(StringAutomaton.ConstantOn(1.0, str)); Assert.True(res.IsZero()); var res2 = transducer.ProjectSource(str); Assert.True(res2.IsZero()); } }
public void CopyElement() { StringTransducer copy = StringTransducer.CopyElement(DiscreteChar.OneOf('a', 'b')); StringInferenceTestUtilities.TestTransducerValue(copy, "a", "a", 1.0); StringInferenceTestUtilities.TestTransducerValue(copy, "b", "b", 1.0); StringInferenceTestUtilities.TestTransducerValue(copy, "a", "b", 0.0); StringInferenceTestUtilities.TestTransducerValue(copy, "b", "a", 0.0); StringInferenceTestUtilities.TestTransducerValue(copy, string.Empty, string.Empty, 0.0); StringInferenceTestUtilities.TestTransducerValue(copy, "bb", "bb", 0.0); StringInferenceTestUtilities.TestTransducerValue(copy, "bab", "bab", 0.0); StringInferenceTestUtilities.TestTransducerValue(copy, "bab", "ba", 0.0); //// Tests that projection on CopyElement(elements) shrinks the support StringAutomaton automaton = StringAutomaton.ConstantOn(2.0, "a", "ab", "ac"); automaton = automaton.Sum(StringAutomaton.ConstantOn(1.0, "a")); automaton = automaton.Sum(StringAutomaton.Constant(2.0)); automaton = automaton.Product(StringAutomaton.Constant(3.0)); for (int i = 0; i < 2; ++i) { StringInferenceTestUtilities.TestValue(automaton, 15, "a"); StringInferenceTestUtilities.TestValue(automaton, 6.0, "b"); StringInferenceTestUtilities.TestValue(automaton, i == 0 ? 6.0 : 0.0, string.Empty); StringInferenceTestUtilities.TestValue(automaton, i == 0 ? 12.0 : 0.0, "ac", "ab"); automaton = copy.ProjectSource(automaton); } }
public void Copy() { StringTransducer copy = StringTransducer.Copy(); StringInferenceTestUtilities.TestTransducerValue(copy, "important", "important", 1.0); StringInferenceTestUtilities.TestTransducerValue(copy, "important", "i", 0.0); StringInferenceTestUtilities.TestTransducerValue(copy, "important", "imp", 0.0); StringInferenceTestUtilities.TestTransducerValue(copy, "important", "t", 0.0); StringInferenceTestUtilities.TestTransducerValue(copy, "important", "mpo", 0.0); StringInferenceTestUtilities.TestTransducerValue(copy, string.Empty, string.Empty, 1.0); StringInferenceTestUtilities.TestTransducerValue(copy, "important", string.Empty, 0.0); StringInferenceTestUtilities.TestTransducerValue(copy, string.Empty, "important", 0.0); //// Test that projection on Copy() doesn't change the automaton StringAutomaton automaton = StringAutomaton.ConstantOn(2.0, "a", "ab", "ac"); automaton = automaton.Sum(StringAutomaton.ConstantOn(1.0, "a")); automaton = automaton.Sum(StringAutomaton.Constant(2.0)); automaton = automaton.Product(StringAutomaton.Constant(3.0)); StringAutomaton automatonClone = copy.ProjectSource(automaton); Assert.Equal(automaton, automatonClone); }
/// <summary> /// Computes the normalizer via transducers. /// </summary> /// <param name="automaton">The automaton.</param> /// <returns>The logarithm of the normalizer.</returns> private static double GetLogNormalizerByGetValueWithTransducers(StringAutomaton automaton) { var one = StringAutomaton.Constant(1.0); StringTransducer transducer = StringTransducer.Consume(automaton); transducer.AppendInPlace(StringTransducer.Produce(one)); return(transducer.ProjectSource(one).GetLogValue("an arbitrary string")); // Now this will be exactly the normalizer }
/// <summary> /// Tests if a projection of a given automaton onto a given transducer has the desired value on a given sequence. /// </summary> /// <param name="transducer">The transducer.</param> /// <param name="input">The automaton to project.</param> /// <param name="str">The sequence to test the projection on.</param> /// <param name="trueValue">The desired value of the projection on the sequence.</param> public static void TestTransducerProjection( StringTransducer transducer, StringAutomaton input, string str, double trueValue) { // Test ProjectSource(func) var result = transducer.ProjectSource(input); TestValue(result, trueValue, str); }
/// <summary>EP message to <c>str2</c>.</summary> /// <param name="concat">Incoming message from <c>concat</c>.</param> /// <param name="str1">Incoming message from <c>str1</c>.</param> /// <returns>The outgoing EP message to the <c>str2</c> argument.</returns> /// <remarks> /// <para>The outgoing message is a distribution matching the moments of <c>str2</c> as the random arguments are varied. The formula is <c>proj[p(str2) sum_(concat,str1) p(concat,str1) factor(concat,str1,str2)]/p(str2)</c>.</para> /// </remarks> public static StringDistribution Str2AverageConditional(StringDistribution concat, StringDistribution str1) { Argument.CheckIfNotNull(concat, "concat"); Argument.CheckIfNotNull(str1, "str1"); StringTransducer transducer = StringTransducer.Consume(str1.GetProbabilityFunction()); transducer.AppendInPlace(StringTransducer.Copy()); return(StringDistribution.FromWorkspace(transducer.ProjectSource(concat))); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="StringConcatOp"]/message_doc[@name="Str1AverageConditional(StringDistribution, StringDistribution)"]/*'/> public static StringDistribution Str1AverageConditional(StringDistribution concat, StringDistribution str2) { Argument.CheckIfNotNull(concat, "concat"); Argument.CheckIfNotNull(str2, "str2"); StringTransducer transducer = StringTransducer.Copy(); transducer.AppendInPlace(StringTransducer.Consume(str2.ToAutomaton())); return(StringDistribution.FromWeightFunction(transducer.ProjectSource(concat.ToAutomaton()))); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="StringConcatOp"]/message_doc[@name="Str1AverageConditional(StringDistribution, StringDistribution)"]/*'/> public static StringDistribution Str1AverageConditional(StringDistribution concat, StringDistribution str2) { Argument.CheckIfNotNull(concat, "concat"); Argument.CheckIfNotNull(str2, "str2"); StringTransducer transducer = StringTransducer.Copy(); transducer.AppendInPlace(StringTransducer.Consume(str2.GetWorkspaceOrPoint())); return(StringDistribution.FromWorkspace(transducer.ProjectSource(concat.GetWorkspaceOrPoint()))); }
/// <summary> /// Tests if a transducer has the desired value on a given pair of strings. /// </summary> /// <param name="transducer">The transducer.</param> /// <param name="string1">The first string.</param> /// <param name="string2">The second string.</param> /// <param name="trueValue">The desired value of the transducer on the strings.</param> public static void TestTransducerValue( StringTransducer transducer, string string1, string string2, double trueValue) { // Test ProjectSource(sequence) var result = transducer.ProjectSource(string1); TestValue(result, trueValue, string2); // Test ProjectSource(func) TestTransducerProjection(transducer, StringAutomaton.ConstantOn(1.0, string1), string2, trueValue); // Test GetValue() double value = transducer.GetValue(string1, string2); Assert.Equal(trueValue, value, LogValueEps); }
public void CopySequence2() { const int CopyCount = 10; const int LetterCount = 20; StringTransducer copy = StringTransducer.Copy(); for (int i = 0; i < CopyCount - 1; ++i) { copy.AppendInPlace(StringTransducer.Copy()); } var sequence = new string(Enumerable.Repeat('a', LetterCount).ToArray()); StringAutomaton result = copy.ProjectSource(sequence); var expectedLogValue = Math.Log(StringInferenceTestUtilities.Partitions(LetterCount, CopyCount)); Assert.Equal(expectedLogValue, result.GetLogValue(sequence), 1e-8); }