public void UpdateCurrentPos()
        {
            _oldPos     = _currentPos;
            _currentPos = _lastPath[_lastPath.Count - 1];



            Bounds = new HmmWindow(_windowSize, _currentPos, Data.InitialLogs.Length);
        }
        public void Reset()
        {
            _observations     = new List <int>();
            _lastObservations = new List <int>();
            _path             = new List <int>();
            _oldPos           = -1;
            _currentPos       = -1;

            Bounds = new HmmWindow(_windowSize, 0, Data.InitialLogs.Length);
        }
        private double[,] ForwardWindow(out double[] c)
        {
            int statesCount  = _windowSize;
            int observsCount = _lastObservations.Count;

            double[,] fwd = new double[observsCount, statesCount];
            c             = new double[observsCount];

            HmmWindow window = new HmmWindow(_windowSize, _currentPos, Data.InitialLogs.Length);

            // 1. Initialization
            for (int i = window.LeftBound; i < window.RightBound; i++)
            {
                fwd[0, i - window.LeftBound] = Data.InitialLogs[i] * Data.EmissionsLogs[i, _lastObservations[0]];
                c[0] += fwd[0, i - window.LeftBound];
            }

            if (c[0] != 0)
            {
                for (int i = 0; i < statesCount; i++)
                {
                    fwd[0, i] = fwd[0, i] / c[0];
                }
            }

            // 2. Induction
            for (int t = 1; t < observsCount; t++)
            {
                for (int i = window.LeftBound; i < window.RightBound; i++)
                {
                    double p = Data.EmissionsLogs[i, _lastObservations[t]];

                    double sum = 0.0;
                    for (int j = window.LeftBound; j < window.RightBound; j++)
                    {
                        sum += fwd[t - 1, j - window.LeftBound] * Data.TransitionsLogs[j, i];
                    }
                    fwd[t, i - window.LeftBound] = sum * p;

                    c[t] += fwd[t, i - window.LeftBound];                     // scaling coefficient
                }

                if (c[t] != 0)                 // Scaling
                {
                    for (int i = 0; i < statesCount; i++)
                    {
                        fwd[t, i] = fwd[t, i] / c[t];
                    }
                }
            }

            return(fwd);
        }
        private double[,] BackwardWindow(double[] c)
        {
            int statesCount  = _windowSize;
            int observsCount = _lastObservations.Count;

            double[,] bwd = new double[observsCount, statesCount];

            HmmWindow window = new HmmWindow(_windowSize, _currentPos, Data.InitialLogs.Length);

            for (int i = window.LeftBound; i < window.RightBound; i++)
            {
                bwd[0, i - window.LeftBound] = Data.InitialLogs[i] * Data.EmissionsLogs[i, _lastObservations[0]];
            }

            // 1. Initialization
            if (c[0] != 0)
            {
                for (int i = 0; i < statesCount; i++)
                {
                    bwd[0, i] = bwd[0, i] / c[0];
                }
            }

            // 2. Induction
            for (int t = observsCount - 2; t >= 0; t--)
            {
                for (int i = window.LeftBound; i < window.RightBound; i++)
                {
                    double sum = 0.0;
                    for (int j = window.LeftBound; j < window.RightBound; j++)
                    {
                        sum += bwd[t + 1, j - window.LeftBound] * Data.TransitionsLogs[i, j] * Data.EmissionsLogs[j, _lastObservations[t + 1]];
                    }
                    bwd[t, i - window.LeftBound] += sum;
                }

                if (c[t] != 0)                 // Scaling
                {
                    for (int i = 0; i < statesCount; i++)
                    {
                        bwd[t, i] = bwd[t, i] / c[t];
                    }
                }
            }

            return(bwd);
        }