예제 #1
0
        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);
            }
        }
예제 #2
0
        /// <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);
                }
            }
        }
예제 #3
0
        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);
        }