private double PhiHelper(double t, int j, int k, int l)
        {
            //object helper_result = null;
            double result = 0;

            PiParams piParams = CDFParams[j, k, l];

            if (piParams.ExpLambda > 0)
            {
                double denominator = 1;
                for (int i = 0; i < M; i++)
                {
                    PiParams piParamsI = CDFParams[i, k, l];
                    if (piParamsI.ExpLambda > 0)
                    {
                        denominator += Exponential.CDF(piParamsI.ExpLambda, t) * piParamsI.Norm;    //!!!!!!!!!!!!!!! + -> -
                    }
                }

                result = Exponential.PDF(piParams.ExpLambda, t) * piParams.Norm / denominator;
            }
            return(result);
        }
        public void CDFParamsEstimate()
        {
            // i ->j, j->k, k->l
            //double[, ,] pi = new double[Observations.Count, Observations.Count, States.Count]; //условные вероятности переключения наблюдений при фиксированном состоянии
            //Pi[j,k,l] = P{Yn = fj | Yn-1 = fk, Xn-1 = el} // P{Yn = fi | Yn-1 = fj, Xn-1 = ek}

            PiParams[,,] result = new PiParams[Observations.Count, Observations.Count, States.Count]; //условные вероятности переключения наблюдений при фиксированном состоянии

            int[,,] N = new int[Observations.Count, Observations.Count, States.Count];                //количество соотвествующих сэмплов


            int    prevState = -1;
            int    prevObs   = -1;
            double previousStateChangeInstant = 0;

            foreach (Sample sample in ModelSamples) //бежим по сэмплам
            {
                if (prevState >= 0 && prevObs >= 0)
                {
                    N[sample.ObservationNumber, prevObs, prevState]++;
                    if (sample.Frame.ReceptionDuration > 0.0000001)
                    {
                        GammaSamples[sample.ObservationNumber, prevObs, prevState].Add(sample.Frame.ReceptionDuration);
                    }
                    else
                    {
                        GammaSamples[sample.ObservationNumber, prevObs, prevState].Add(0.0000001);
                    }

                    if (sample.StateNumber != prevState)
                    {
                        TimeInStateSamples[prevState].Add(sample.Instant - previousStateChangeInstant);
                        previousStateChangeInstant = sample.Instant;
                    }
                }
                prevState = sample.StateNumber;
                prevObs   = sample.ObservationNumber;
            }


            for (int l = 0; l < States.Count; l++)
            {
                for (int k = 0; k < Observations.Count; k++)
                {
                    int sum = 0;
                    for (int j = 0; j < Observations.Count; j++)
                    {
                        sum += N[j, k, l];
                    }
                    for (int j = 0; j < Observations.Count; j++)
                    {
                        double norm = 0;
                        if (sum > 0) // если 0, то очень фигово оценивается распределение
                        {
                            norm = (double)N[j, k, l] / (double)sum;
                        }
                        else
                        {
                            norm = 0;
                        }

                        double[] res       = { 0, 0 };
                        double   lambdares = 0;
                        if (GammaSamples[j, k, l].Count > 0) // если 0, то очень фигово оценивается распределение при Count = 1 или 2
                        {
                            res       = GammaFit(GammaSamples[j, k, l].ToArray());
                            lambdares = ExpFit(GammaSamples[j, k, l].ToArray());
                            //result[j, k, l].Gamma = new GammaParams(res[0], res[1]);
                        }
                        result[j, k, l]           = new PiParams(norm, new GammaParams(res[0], res[1]));
                        result[j, k, l].ExpLambda = 1 / lambdares;
                    }
                }
                TimesInStateCDFParams[l] = ExpFit(TimeInStateSamples[l].ToArray());
            }
            CDFParams = result;
        }