public void BackwardTest()
{
HiddenMarkovModel hmm = Accord.Tests.Statistics.Models.Markov.
ForwardBackwardAlgorithmTest.CreateModel2();
var function = new MarkovDiscreteFunction(hmm);
// A B B A
int[] observations = { 0, 1, 1, 0 };
double logLikelihood;
double[,] actual = Accord.Statistics.Models.Fields.
ForwardBackwardAlgorithm.Backward(function.Factors[0], observations, 0, out logLikelihood);
var A = Matrix.Exp(hmm.Transitions);
var B = Matrix.Exp(hmm.Emissions);
var P = Matrix.Exp(hmm.Probabilities);
double a30 = 1;
double a31 = 1;
double a20 = A[0, 0] * B[0, 0] * a30 + A[0, 1] * B[1, 0] * a31;
double a21 = A[1, 0] * B[0, 0] * a30 + A[1, 1] * B[1, 0] * a31;
double a10 = A[0, 0] * B[0, 1] * a20 + A[0, 1] * B[1, 1] * a21;
double a11 = A[1, 0] * B[0, 1] * a20 + A[1, 1] * B[1, 1] * a21;
double a00 = A[0, 0] * B[0, 1] * a10 + A[0, 1] * B[1, 1] * a11;
double a01 = A[1, 0] * B[0, 1] * a10 + A[1, 1] * B[1, 1] * a11;
Assert.AreEqual(actual[0, 0], a00, 1e-10);
Assert.AreEqual(actual[0, 1], a01, 1e-10);
Assert.AreEqual(actual[1, 0], a10, 1e-10);
Assert.AreEqual(actual[1, 1], a11, 1e-10);
Assert.AreEqual(actual[2, 0], a20, 1e-10);
Assert.AreEqual(actual[2, 1], a21, 1e-10);
Assert.AreEqual(actual[3, 0], a30, 1e-10);
Assert.AreEqual(actual[3, 1], a31, 1e-10);
foreach (double e in actual)
Assert.IsFalse(double.IsNaN(e));
double p = 0;
for (int i = 0; i < hmm.States; i++)
p += actual[0, i] * P[i] * B[i, observations[0]];
Assert.AreEqual(0.054814695, p, 1e-8);
Assert.IsFalse(double.IsNaN(p));
p = System.Math.Exp(logLikelihood);
Assert.AreEqual(0.054814695, p, 1e-8);
Assert.IsFalse(double.IsNaN(p));
}