public static double[,] Forward(ContinuousHiddenMarkovModel model, double[][] observations, out double[] scaling)
{
int states = model.States;
double[,] A = model.Transitions;
IDistribution[] B = model.Emissions;
double[] pi = model.Probabilities;
int T = observations.Length;
var fwd = new double[T,states];
scaling = new double[T];
// 1. Initialization
for (int i = 0; i < states; i++)
scaling[0] += fwd[0, i] = pi[i]*B[i].ProbabilityFunction(observations[0]);
if (scaling[0] != 0) // Scaling
{
for (int i = 0; i < states; i++)
fwd[0, i] /= scaling[0];
}
// 2. Induction
for (int t = 1; t < T; t++)
{
double[] obs = observations[t];
for (int i = 0; i < states; i++)
{
double sum = 0.0;
for (int j = 0; j < states; j++)
sum += fwd[t - 1, j]*A[j, i];
fwd[t, i] = sum*B[i].ProbabilityFunction(obs);
scaling[t] += fwd[t, i]; // scaling coefficient
}
if (scaling[t] != 0) // Scaling
{
for (int i = 0; i < states; i++)
fwd[t, i] /= scaling[t];
}
}
return fwd;
}