public double b(int i, int d, int t)//t - правая граница { Debug.WriteLine("b(" + i + "," + d + "," + t + "): "); if (t - d <= 0 && t <= 0 || t - d > O.Length) { Debug.WriteLine("b(" + i + "," + d + "," + t + "): " + 0); return(0);//или t > O.Length } else { double prod = 1; double[] fi = HMM_QPN.integral(Model.Ro[i], Model.Ro[i].Length, d); //TODO: Хранить фи int m = 1; int k = d; if (t - d > 0) { m = 1; Debug.WriteLine("m: t - d > 0 " + m); } else { m = 1 - t + d; Debug.WriteLine("m: t - d <= 0 " + m); } if (t <= O.Length) { k = d; Debug.WriteLine("k:t <= O.Length " + k); } else { k = O.Length - t + d; Debug.WriteLine("k: t > O.Length " + k); } Debug.WriteLine("from " + m + "; to " + k); for (int theta = m; theta <= k; theta++) { int I = MultiplicativeGroupIndicator(O[t - d + theta], Model.q); Debug.Write(" position: " + (t - d + theta) + " I(" + O[t - d + theta] + ", " + Model.q + "): " + I); Debug.Write(" fi: " + fi[theta - 1]); Debug.Write(" Per: " + (double)Model.Per[i]); Debug.Write(" d: " + (double)d); double mult = (I == 1) ? (double)fi[theta - 1] * (double)Model.Per[i] * (double)d * (double)Model.B[i, O[t - d + theta] - 1] : (1 - (double)fi[theta - 1] * (double)Model.Per[i] * d); if (I == 1) { Debug.Write(" B: " + (double)Model.B[i, O[t - d + theta] - 1]); } Debug.WriteLine(" mult(" + theta + "): " + mult); prod *= mult; } Debug.WriteLine("b(" + i + "," + d + "," + t + "): " + prod); return(prod); } }
/// <summary> /// Функция вычисления вероятности наблюдения частичной последовательности O_{t-d+1:t} в состоянии i, где d = O.length /// </summary> /// <param name="O">частичная последовательность</param> /// <param name="i">состояние</param> /// <param name="t">момент времени соответствующий концу частичной последовательности внутри целой</param> /// <param name="d">длинна квазипериода</param> /// <returns></returns> private static double b(HMM_QPN Model, int[] O, int i, int t, int d) { if (t <= 0) { return(1); } else { double prod = 1; if (O == null || O.Length == 0) { return(1); } else { //int o = O.Length; if (d == 0) { return(1); } int q = Model.B.GetLength(1) + 1;//мощность поля Галуа double[] fi = HMM_QPN.integral(Model.Ro[i], Model.Ro[i].Length, d); int theta; for (theta = 0; theta < O.Length; theta++) { try { int I = MultiplicativeGroupIndicator(O[theta], q);//-1 из-за того что в реализации массив нумеруется с 0 prod *= (I == 1) ? fi[d - O.Length + theta] * Model.Per[i] * d * Model.B[i, O[theta] - 1] : (1 - fi[theta] * Model.Per[i] * d); } catch { } } ; return(prod); } } }
public static double Likelihood(HMM_QPN Model, int[] res, out double[,] norm_alpha_par, out double[,] alpha_par, out double[] norm_coeff, out double prob)// считает вероятность того, что последовательность наблюдений res получена с помощью модели Model //res numeruetsya ot 1 { #region Описание переменных int n = Model.A.GetLength(0); //число состояний int T = res.Length - 1; //длина последовательности наблюдений double[,] alpha = new double[n, T + 1]; //прямая переменная double[,] auxiliary_alpha = new double[n, T + 1]; double[,] norm_alpha = new double[n, T + 1]; //нормированная прямая переменная double[] c = new double[T + 1]; //коэффициенты нормировки int max_period = 0; //максимальная длительность по всем состояниям (у Рабинера D) #endregion #region Определение максимальной длительности по всем состояниям int i = 0; for (i = 0; i < n; i++)//определяем max_period { double[] f_values = Model.ValueFromDistribution(Model.F[i]); int max_in_state = (int)HMM_QPN.MaxElementOfArray(f_values); if (max_in_state > max_period) { max_period = max_in_state; } } #endregion //преобразуем p_i(d) к виду ряда распределения где d принадлежит от 1 до D(то есть) max_period,а вероятность =0 если такой длины нет #region Матрица плотностей длительностей состояний float[,] length_density = new float[n, max_period + 1];//матрица плотностей длительности состояний. //Второй индекс соответствует длине, значение - вероятности for (i = 0; i < n; i++) { for (int d = 1; d <= max_period; d++) { length_density[i, d] = 0;//занулили все элементы матрицы } for (int j = 0; j < Model.F[i].Length; j++) { length_density[i, Model.F[i][j].value] = Model.F[i][j].probability;//изменили те элементы, для которых вероятность нулю не равна } } #endregion #region Старый вариант формул //#region Для t=1 ////для t=1 //c[1] = 0; //for (i=0; i<n; i++) //{ // if (length_density[i, 1] > 0) // { // float[] fi = new float[1]; // fi = HMM_QPN.integral(Model.Ro[i], Model.Ro[i].Length, 1); // alpha[i, 1] = SymbolFinalProbability(Model, fi[0], 1, i, res[1]) * Model.Pi[i] * length_density[i, 1]; // auxiliary_alpha[i, 1] = SymbolFinalProbability(Model, fi[0], 1, i, res[1]) * Model.Pi[i] * length_density[i, 1]; // } // else // { // alpha[i, 1] = 0; // auxiliary_alpha[i, 1] =0; // } // c[1] += auxiliary_alpha[i, 1]; //} //c[1] =(c[1]!=0)?1 / c[1]:0;//вычислили нормировочный коэффициент //for (i = 0; i < n; i++) //{ // norm_alpha[i, 1] = auxiliary_alpha[i, 1] * c[1]; //} //#endregion //#region Для 1<t<=D ////вторая строчка формулы //int t=2; //for (t = 2; (t <= max_period)&&(t<=T); t++) //{ // c[t] = 0; // for (i = 0; i < n; i++) // { // //первое слагаемое формулы 2 // float term1 = 0; // if (length_density[i, t] > 0) // { // float[] fi = new float[t]; // fi = HMM_QPN.integral(Model.Ro[i], Model.Ro[i].Length, t); // float prod_tilda_b1 = 1;//переменная для произведения b c волной // for (int s = 1; s <= t; s++) // { // prod_tilda_b1 *= SymbolFinalProbability(Model, fi[s - 1], t, i, res[s]); // } // term1 = Model.Pi[i] * length_density[i, t] * prod_tilda_b1; // } // float term2 = 0; // float norm_term2 = 0; // for (int d = 1; d <= t - 1; d++) // for (int j = 0; j < n; j++) // { // float prod_tilda_b2 = 1; // if (length_density[i, d] > 0) // { // float[] fi2 = new float[d]; // fi2 = HMM_QPN.integral(Model.Ro[i], Model.Ro[i].Length, d); // for (int s = t - d + 1; s <= t; s++) // { // prod_tilda_b2 *= SymbolFinalProbability(Model, fi2[s - t + d - 1],d, i, res[s]); // } // term2 += alpha[j, t - d] * Model.A[j, i] * length_density[i, d] * prod_tilda_b2; // norm_term2 += norm_alpha[j, t - d] * Model.A[j, i] * length_density[i, d] * prod_tilda_b2; // } // } // alpha[i, t] = term1 + term2; // auxiliary_alpha[i, t] = term1 + norm_term2; // c[t] += auxiliary_alpha[i, t]; // } // c[t] = (c[t] != 0) ? 1 / c[t] : 0; // for (i = 0; i < n; i++) // { // norm_alpha[i, t] = auxiliary_alpha[i, t] * c[t]; // } //} //#endregion //#region Для t>D ////третья строчка формулы //for (t = max_period + 1; t <= T; t++) //{ // c[t] = 0; // for (i = 0; i < n; i++) // { // float term = 0; // float norm_term = 0; // for (int d = 1; d <= max_period; d++) // for (int j = 0; j < n; j++) // { // if (length_density[i, d] > 0) // { // float prod_tilda_b = 1; // float[] fi = new float[d]; // fi = HMM_QPN.integral(Model.Ro[i], Model.Ro[i].Length, d); // for (int s = t - d + 1; s <= t; s++) // { // prod_tilda_b *= SymbolFinalProbability(Model, fi[s - t + d - 1], d, i, res[s]); // } // term += alpha[j, t - d] * Model.A[j, i] * length_density[i, d] * prod_tilda_b; // norm_term += norm_alpha[j, t - d] * Model.A[j, i] * length_density[i, d] * prod_tilda_b; // } // } // alpha[i, t] = term; // auxiliary_alpha[i, t] = norm_term; // c[t] += auxiliary_alpha[i, t]; // } // c[t] = (c[t] != 0) ? 1 / c[t] : 0; // for (i = 0; i < n; i++) // { // norm_alpha[i, t] = auxiliary_alpha[i, t] * c[t]; // } //} // #endregion #endregion Старый вариант формул #region Для t=1 //для t=1 c[1] = 0; for (i = 0; i < n; i++) { if (length_density[i, 1] > 0) { double[] fi = new double[1]; fi = HMM_QPN.integral(Model.Ro[i], Model.Ro[i].Length, 1); alpha[i, 1] = SymbolFinalProbability(Model, fi[0], 1, i, res[1]) * Model.Pi[i] * length_density[i, 1]; auxiliary_alpha[i, 1] = SymbolFinalProbability(Model, fi[0], 1, i, res[1]) * Model.Pi[i] * length_density[i, 1]; } else { alpha[i, 1] = 0; auxiliary_alpha[i, 1] = 0; } c[1] += auxiliary_alpha[i, 1]; } c[1] = (c[1] != 0) ? 1 / c[1] : 0;//вычислили нормировочный коэффициент for (i = 0; i < n; i++) { norm_alpha[i, 1] = auxiliary_alpha[i, 1] * c[1]; } #endregion #region Для t<T int t = 2; for (t = 2; t <= T; t++) { c[t] = 0; for (i = 0; i < n; i++) { double term = 0; double norm_term = 0; int D = max_period >= t ? t : max_period; for (int d = 1; d <= D; d++) { for (int j = 0; j < n; j++) { if (length_density[i, d] > 0) { double prod_tilda_b = 1; double[] fi = new double[d]; fi = HMM_QPN.integral(Model.Ro[i], Model.Ro[i].Length, d); for (int s = t - d + 1; s <= t; s++) { prod_tilda_b *= SymbolFinalProbability(Model, fi[s - t + d - 1], d, i, res[s]); } term += alpha[j, t - d] * Model.A[j, i] * length_density[i, d] * prod_tilda_b; norm_term += norm_alpha[j, t - d] * Model.A[j, i] * length_density[i, d] * prod_tilda_b; } } } alpha[i, t] = term; auxiliary_alpha[i, t] = norm_term; c[t] += auxiliary_alpha[i, t]; } c[t] = (c[t] != 0) ? 1 / c[t] : 0; for (i = 0; i < n; i++) { norm_alpha[i, t] = auxiliary_alpha[i, t] * c[t]; } } #endregion Для t<T double probability = 0; prob = 0; double coeffsum = 0; for (i = 0; i < n; i++) { // probability+=norm_alpha[i,T]; prob += alpha[i, T]; } for (t = 1; t <= T; t++) { coeffsum += c[t]; } probability = 1 / coeffsum; alpha_par = alpha; norm_alpha_par = norm_alpha; norm_coeff = c; return(probability); }