public IDistribution Evaluate(double[] observations, double[] symbols, double[] gamma)
        {
            var M             = symbols.Length;
            var T             = observations.Length;
            var probabilities = new double[M];

            for (var k = 0; k < M; k++)
            {
                double den = 0, num = 0;
                for (var t = 0; t < T; t++)
                {
                    if (observations[t] == symbols[k])
                    {
                        num = num + gamma[t];
                    }
                    den = den + gamma[t];
                }
                probabilities[k] = 1e-10;
                if (num.EqualsToZero())
                {
                    probabilities[k] = den.EqualsToZero() ? 0.0 : LogExtention.eExp(LogExtention.eLnProduct(num, -den));
                }
            }
            return(new DiscreteDistributionNormalized(symbols, probabilities));
        }
Example #2
0
        public double[][] Estimate(AlphaBetaTransitionProbabiltyMatrixParameters <TDistribution> parameters)
        {
            if (_estimatedTransitionProbabilityMatrix != null)
            {
                return(_estimatedTransitionProbabilityMatrix);
            }
            var T = parameters.Observations.Length;

            _estimatedTransitionProbabilityMatrix = new double[parameters.Model.N][];

            for (var i = 0; i < parameters.Model.N; i++)
            {
                _estimatedTransitionProbabilityMatrix[i] = new double[parameters.Model.N];
                for (var j = 0; j < parameters.Model.N; j++)
                {
                    double nominator = (parameters.Normalized) ? double.NaN : 0.0d, denominator = (parameters.Normalized) ? double.NaN : 0.0d;
                    for (var t = 0; t < T - 1; t++)
                    {
                        var probability = parameters.Model.Emission[j].ProbabilityDensityFunction(parameters.Observations[t + 1]);
                        if (parameters.Normalized)
                        {
                            nominator   = LogExtention.eLnSum(nominator, LogExtention.eLnProduct(parameters.Weights[t], LogExtention.eLnProduct(parameters.Alpha[t][i], LogExtention.eLnProduct(LogExtention.eLn(parameters.Model.TransitionProbabilityMatrix[i][j]), LogExtention.eLnProduct(LogExtention.eLn(probability), parameters.Beta[t + 1][j])))));
                            denominator = LogExtention.eLnSum(denominator, LogExtention.eLnProduct(parameters.Weights[t], LogExtention.eLnProduct(parameters.Alpha[t][i], parameters.Beta[t][j])));
                        }
                        else
                        {
                            nominator   += parameters.Weights[t] * parameters.Alpha[t][i] * parameters.Model.TransitionProbabilityMatrix[i][j] * probability * parameters.Beta[t + 1][j];
                            denominator += parameters.Weights[t] * parameters.Alpha[t][i] * parameters.Beta[t][j];
                        }
                    }
                    _estimatedTransitionProbabilityMatrix[i][j] = CalculateTransitionProbabilityMatrixEntry(nominator, denominator, parameters.Normalized);
                }
            }
            return(_estimatedTransitionProbabilityMatrix);
        }
Example #3
0
        public double[][] Estimate(AdvancedEstimationParameters <TDistribution> parameters)
        {
            if (_gamma != null)
            {
                return(_gamma);
            }

            var denominator = new double[parameters.Observations.Count];

            for (var t = 0; t < parameters.Observations.Count; t++)
            {
                denominator[t] = (parameters.Normalized) ? double.NaN : 0d;
                for (var i = 0; i < parameters.Model.N; i++)
                {
                    if (parameters.Normalized)
                    {
                        denominator[t] = LogExtention.eLnSum(denominator[t], LogExtention.eLnProduct(parameters.Alpha[t][i], parameters.Beta[t][i]));
                    }
                    else
                    {
                        denominator[t] += parameters.Alpha[t][i] * parameters.Beta[t][i];
                    }
                }
            }


            try
            {
                _gamma = new double[parameters.Observations.Count][];
                for (var t = 0; t < parameters.Observations.Count; t++)
                {
                    _gamma[t] = new double[parameters.Model.N];
                    for (var i = 0; i < parameters.Model.N; i++)
                    {
                        if (parameters.Normalized)
                        {
                            _gamma[t][i] = LogExtention.eLnProduct(LogExtention.eLnProduct(parameters.Alpha[t][i], parameters.Beta[t][i]), -denominator[t]);
                        }
                        else
                        {
                            _gamma[t][i] = (parameters.Alpha[t][i] * parameters.Beta[t][i]) / denominator[t];
                        }
                    }
                }
            }
            catch (Exception)
            {
                for (var t = 0; t < parameters.Observations.Count; t++)
                {
                    for (var i = 0; i < parameters.Model.N; i++)
                    {
                        Debug.WriteLine("Gamma [{0}][{1}] : alpha : {2} , beta : {3} , denominator : {4} : gamma {5} ", t, i, parameters.Alpha[t][i], parameters.Beta[t][i], denominator[t], _gamma[t][i]);
                    }
                }
                throw;
            }

            return(_gamma);
        }
Example #4
0
 private double CalculateTransitionProbabilityMatrixEntry(double nominator, double denominator, bool normalized)
 {
     if (denominator.EqualsToZero())
     {
         return(0);
     }
     return((normalized) ? LogExtention.eExp(LogExtention.eLnProduct(nominator, -denominator)) : nominator / denominator);
 }
Example #5
0
        public double[][] Estimate(BasicEstimationParameters <TDistribution> parameters)
        {
            if (_beta != null)
            {
                return(_beta);
            }
            var T = parameters.Observations.Count;

            try
            {
                _beta        = new double[T][];
                _beta[T - 1] = new double[parameters.Model.N];

                for (var i = 0; i < parameters.Model.N; i++)
                {
                    _beta[T - 1][i] = (parameters.Normalized) ? 0d : 1d;
                }

                for (var t = T - 2; t >= 0; t--)
                {
                    _beta[t] = new double[parameters.Model.N];
                    for (var i = 0; i < parameters.Model.N; i++)
                    {
                        _beta[t][i] = (parameters.Normalized) ? double.NaN : 0d;
                        for (var j = 0; j < parameters.Model.N; j++)
                        {
                            var o = EstimatorUtilities.GetProbability(parameters.Model.Emission[j], parameters.Observations, t + 1);
                            if (parameters.Normalized)
                            {
                                _beta[t][i] = LogExtention.eLnSum(_beta[t][i],
                                                                  LogExtention.eLnProduct(LogExtention.eLn(parameters.Model.TransitionProbabilityMatrix[i][j]),
                                                                                          LogExtention.eLnProduct(LogExtention.eLn(o), _beta[t + 1][j])));
                            }
                            else
                            {
                                _beta[t][i] += parameters.Model.TransitionProbabilityMatrix[i][j] * o * _beta[t + 1][j];
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                for (var t = T - 2; t >= 0; t--)
                {
                    for (var i = 0; i < parameters.Model.N; i++)
                    {
                        for (var j = 0; j < parameters.Model.N; j++)
                        {
                            Debug.WriteLine("[{0}][{1}] : beta : {2}", t, i, _beta[t][i]);
                        }
                    }
                }
                throw;
            }

            return(_beta);
        }
Example #6
0
        public void eLnProduct_XisNaN_YReturned()
        {
            var x = double.NaN;
            var y = 1d;

            var result = LogExtention.eLnProduct(x, y);

            Assert.AreEqual(double.NaN, result);
        }
Example #7
0
        public void eLnProduct_YandXnotEqualsNan_XPlusYReturned()
        {
            var x = 1d;
            var y = 1d;

            var result = LogExtention.eLnProduct(x, y);

            Assert.AreEqual(x + y, result);
        }
Example #8
0
        public double[][,] Estimate(AdvancedEstimationParameters <TDistribution> parameters)
        {
            if (_ksi != null)
            {
                return(_ksi);
            }
            var denominator = new double[parameters.Observations.Count];

            for (var t = 0; t < parameters.Observations.Count - 1; t++)
            {
                denominator[t] = (parameters.Normalized) ? double.NaN : 0d;
                for (var i = 0; i < parameters.Model.N; i++)
                {
                    for (var j = 0; j < parameters.Model.N; j++)
                    {
                        var o = EstimatorUtilities.GetProbability(parameters.Model.Emission[j], parameters.Observations, t + 1);
                        if (parameters.Normalized)
                        {
                            denominator[t] = LogExtention.eLnSum(denominator[t], LogExtention.eLnProduct(parameters.Alpha[t][i],
                                                                                                         LogExtention.eLnProduct(LogExtention.eLn(parameters.Model.TransitionProbabilityMatrix[i][j]),
                                                                                                                                 LogExtention.eLnProduct(parameters.Beta[t + 1][j], LogExtention.eLn(o)))));
                        }
                        else
                        {
                            denominator[t] += parameters.Alpha[t][i] * parameters.Model.TransitionProbabilityMatrix[i][j] * parameters.Beta[t + 1][j] * o;
                        }
                    }
                }
            }

            _ksi = new double[parameters.Observations.Count][, ];
            for (var t = 0; t < parameters.Observations.Count - 1; t++)
            {
                _ksi[t] = new double[parameters.Model.N, parameters.Model.N];
                for (var i = 0; i < parameters.Model.N; i++)
                {
                    for (var j = 0; j < parameters.Model.N; j++)
                    {
                        var o = EstimatorUtilities.GetProbability(parameters.Model.Emission[j], parameters.Observations, t + 1);
                        if (parameters.Normalized)
                        {
                            var nominator = LogExtention.eLnProduct(parameters.Alpha[t][i],
                                                                    LogExtention.eLnProduct(LogExtention.eLn(parameters.Model.TransitionProbabilityMatrix[i][j]),
                                                                                            LogExtention.eLnProduct(parameters.Beta[t + 1][j], LogExtention.eLn(o))));
                            _ksi[t][i, j] = LogExtention.eLnProduct(nominator, -denominator[t]);
                        }
                        else
                        {
                            var nominator = parameters.Alpha[t][i] * parameters.Model.TransitionProbabilityMatrix[i][j] * parameters.Beta[t + 1][j] * o;
                            _ksi[t][i, j] = nominator / denominator[t];
                        }
                    }
                }
            }

            return(_ksi);
        }
Example #9
0
        public double[][,] Estimate(MixtureAdvancedEstimationParameters <TDistribution> parameters)
        {
            if (_gammaComponents != null)
            {
                return(_gammaComponents);
            }

            try
            {
                _gammaComponents = new double[parameters.Observations.Count][, ];
                for (var t = 0; t < parameters.Observations.Count; t++)
                {
                    _gammaComponents[t] = new double[parameters.Model.N, parameters.L];
                    for (var i = 0; i < parameters.Model.N; i++)
                    {
                        var d = parameters.Model.Emission[i] as Mixture <IMultivariateDistribution>;
                        if (d != null)
                        {
                            for (var l = 0; l < parameters.L; l++)
                            {
                                //Emmision in our case are Mixture<T>
                                var p = d.ProbabilityDensityFunction(l, parameters.Observations[t].Value);
                                if (parameters.Normalized)
                                {
                                    _gammaComponents[t][i, l] = LogExtention.eLnProduct(_gammaEstimator.Estimate(parameters)[t][i], LogExtention.eLn(p));
                                }
                                else
                                {
                                    _gammaComponents[t][i, l] = _gammaEstimator.Estimate(parameters)[t][i] * p;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                for (var t = 0; t < parameters.Observations.Count; t++)
                {
                    if (Math.Round(_gammaComponents[t].Sum(), 5) > 1)
                    {
                        Debug.WriteLine("Mixture Gamma Components [{0}] : {1}", t, new Matrix(_gammaComponents[t]));
                        throw new ApplicationException(string.Format("Mixture Sigma is greater than 1. [{0}] : {1} : {2}", t, new Matrix(_gammaComponents[t]), Math.Round(_gammaComponents[t].Sum(), 5)));
                    }
                }
                throw;
            }


            return(_gammaComponents);
        }
Example #10
0
        public double[][] Estimate(BasicEstimationParameters <TDistribution> parameters)
        {
            if (_alpha != null)
            {
                return(_alpha);
            }

            _alpha    = new double[parameters.Observations.Count][];
            _alpha[0] = new double[parameters.Model.N];
            // Initialize
            for (var i = 0; i < parameters.Model.N; i++)
            {
                var o = EstimatorUtilities.GetProbability(parameters.Model.Emission[i], parameters.Observations, 0);
                _alpha[0][i] = (parameters.Normalized) ? LogExtention.eLnProduct(LogExtention.eLn(parameters.Model.Pi[i]), LogExtention.eLn(o)) : parameters.Model.Pi[i] * o;
            }
            // Induction
            for (var t = 1; t < parameters.Observations.Count; t++)
            {
                _alpha[t] = new double[parameters.Model.N];
                for (var j = 0; j < parameters.Model.N; j++)
                {
                    var sum = (parameters.Normalized) ? double.NaN : 0d;
                    for (var i = 0; i < parameters.Model.N; i++)
                    {
                        if (parameters.Normalized)
                        {
                            sum = LogExtention.eLnSum(sum, LogExtention.eLnProduct(_alpha[t - 1][i], LogExtention.eLn(parameters.Model.TransitionProbabilityMatrix[i][j])));
                        }
                        else
                        {
                            sum += _alpha[t - 1][i] * parameters.Model.TransitionProbabilityMatrix[i][j];
                        }
                    }
                    var o = EstimatorUtilities.GetProbability(parameters.Model.Emission[j], parameters.Observations, t);
                    if (parameters.Normalized)
                    {
                        _alpha[t][j] = LogExtention.eLnProduct(sum, LogExtention.eLn(o));
                    }
                    else
                    {
                        _alpha[t][j] = sum * o;
                    }
                }
            }

            return(_alpha);
        }
Example #11
0
        protected void EstimateTransitionProbabilityMatrix(double[][] gamma, double[][,] ksi, decimal[] observationWeights, int sequenceLength)
        {
            var checksum = new double[_model.N];

            for (var i = 0; i < _model.N; i++)
            {
                _estimatedTransitionProbabilityMatrix[i] = new double[_model.N];
                for (var j = 0; j < _model.N; j++)
                {
                    double den = (_model.Normalized) ? double.NaN : 0, num = (_model.Normalized) ? double.NaN : 0;
                    for (var t = 0; t < sequenceLength - 1; t++)
                    {
                        var weight = GetWeightValue(t, observationWeights);
                        if (_model.Normalized)
                        {
                            num = LogExtention.eLnSum(num, LogExtention.eLnProduct(weight, ksi[t][i, j]));
                            den = LogExtention.eLnSum(den, LogExtention.eLnProduct(weight, gamma[t][i]));
                        }
                        else
                        {
                            num += weight * ksi[t][i, j];
                            den += weight * gamma[t][i];
                        }
                    }
                    if (_model.Normalized)
                    {
                        _estimatedTransitionProbabilityMatrix[i][j] = den.EqualsToZero() ? 0.0 : LogExtention.eExp(LogExtention.eLnProduct(num, -den));
                    }
                    else
                    {
                        _estimatedTransitionProbabilityMatrix[i][j] = den.EqualsToZero() ? 0.0 : num / den;
                    }
                    checksum[i] = checksum[i] + _estimatedTransitionProbabilityMatrix[i][j];
                }
            }

            CheckTransitionProbabilityMatrix(checksum);
        }
Example #12
0
        public double RunBackward <TEmmisionType>(IList <IObservation> observations, IHiddenMarkovModel <TEmmisionType> model) where TEmmisionType : IDistribution
        {
            var betaEstimator = new BetaEstimator <TEmmisionType>();

            _beta = betaEstimator.Estimate(new BasicEstimationParameters <TEmmisionType> {
                Model = model, Observations = observations, Normalized = Normalized
            });
            var result = (Normalized) ? double.NaN : 0d;

            for (var j = 0; j < model.N; j++)
            {
                if (Normalized)
                {
                    result = LogExtention.eLnSum(result,
                                                 LogExtention.eLnProduct(LogExtention.eLn(model.Pi[j]), _beta[1][j]));
                }
                else
                {
                    result += model.Pi[j] * _beta[1][j];
                }
            }

            return(result);
        }
        public double[][] Estimate(MixtureCoefficientEstimationParameters <TDistribution> parameters)
        {
            _parameters = parameters;
            if (_coefficients != null)
            {
                return(_coefficients);
            }

            try
            {
                _coefficients = new double[parameters.Model.N][];
                _denominator  = new double[parameters.Model.N];
                for (var i = 0; i < parameters.Model.N; i++)
                {
                    _denominator[i] = (parameters.Model.Normalized) ? double.NaN : 0d;
                    for (var t = 0; t < parameters.Observations.Count; t++)
                    {
                        var weight = GetWeightValue(t, parameters.ObservationWeights);
                        if (parameters.Normalized)
                        {
                            _denominator[i] = LogExtention.eLnSum(LogExtention.eLnProduct(weight, parameters.Gamma[t][i]), _denominator[i]);
                        }
                        else
                        {
                            _denominator[i] += weight * parameters.Gamma[t][i];
                        }
                    }
                }
                for (var i = 0; i < parameters.Model.N; i++)
                {
                    _coefficients[i] = new double[parameters.L];
                    for (var l = 0; l < parameters.L; l++)
                    {
                        var nominator = (parameters.Model.Normalized) ? double.NaN : 0d;
                        for (var t = 0; t < parameters.Observations.Count; t++)
                        {
                            var weight = GetWeightValue(t, parameters.ObservationWeights);
                            if (parameters.Normalized)
                            {
                                nominator = LogExtention.eLnSum(LogExtention.eLnProduct(weight, parameters.GammaComponents[t][i, l]), nominator);
                            }
                            else
                            {
                                nominator += weight * parameters.GammaComponents[t][i, l];
                            }
                        }

                        if (parameters.Normalized)
                        {
                            _coefficients[i][l] = LogExtention.eLnProduct(nominator, -_denominator[i]);
                        }
                        else
                        {
                            _coefficients[i][l] = nominator / _denominator[i];
                        }

                        if (Math.Round(_coefficients[i].Sum(), 5) > 1)
                        {
                            Debug.WriteLine("Mixture Coeffiecients [{0},{1}] : {2}", i, l, new Vector(_coefficients[i]));
                            throw new ApplicationException(string.Format("Mixture Coeffiecients is greater than 1. [{0},{1}] : {2} : {3}", i, l, new Vector(_coefficients[i]), Math.Round(_coefficients[i].Sum(), 5)));
                        }
                    }
                }
            }
            catch (Exception)
            {
                for (var i = 0; i < parameters.Model.N; i++)
                {
                    for (var l = 0; l < parameters.L; l++)
                    {
                        Debug.WriteLine("Coeffiecients[{0}][{1}] : {2}", i, l, _coefficients[i][l]);
                        if (Math.Round(_coefficients[i].Sum(), 5) > 1)
                        {
                            Debug.WriteLine("Mixture Coeffiecients [{0},{1}] : {2}", i, l, new Vector(_coefficients[i]));
                            throw new ApplicationException(string.Format("Mixture Coeffiecients is greater than 1. [{0},{1}] : {2} : {3}", i, l, new Vector(_coefficients[i]), Math.Round(_coefficients[i].Sum(), 5)));
                        }
                    }
                }
                throw;
            }

            return(_coefficients);
        }
Example #14
0
        public IDistribution Evaluate(double[] observations, double[] symbols, double[] gamma, bool logNormalized)
        {
            var M             = symbols.Length;
            var T             = observations.Length;
            var probabilities = new double[M];

            for (var k = 0; k < M; k++)
            {
                double den = (logNormalized) ? double.NaN : 0, num = (logNormalized) ? double.NaN : 0;
                for (var t = 0; t < T; t++)
                {
                    if (observations[t] == symbols[k])
                    {
                        if (logNormalized)
                        {
                            num = LogExtention.eLnSum(num, gamma[t]);
                        }
                        else
                        {
                            num = num + gamma[t];
                        }
                    }
                    if (logNormalized)
                    {
                        den = LogExtention.eLnSum(den, gamma[t]);
                    }
                    else
                    {
                        den = den + gamma[t];
                    }
                }
                probabilities[k] = 1e-10;
                if (!num.EqualsToZero())
                {
                    if (logNormalized)
                    {
                        probabilities[k] = den.EqualsToZero() ? 0.0 : LogExtention.eExp(LogExtention.eLnProduct(num, -den));
                    }
                    else
                    {
                        probabilities[k] = den.EqualsToZero() ? 0.0 : num / den;
                    }
                }
            }
            return(new DiscreteDistribution(symbols, probabilities));
        }
Example #15
0
        public List <IState> Run(IList <IObservation> observations, IList <IState> states,
                                 double[] startDistribution,
                                 double[][] transitionProbabilityMatrix,
                                 double[][] distributionWeights,
                                 IDistribution[][] distributions)
        {
            var N = states.Count;
            var T = observations.Count;
            var K = distributionWeights[0].Length;

            ComputationPath = new double[T][];
            ReproducePath   = new int[T][];
            var mpp = new List <IState>(states.Count);

            // Initialize for the first observation
            ComputationPath[0] = new double[N];
            ReproducePath[0]   = new int[N];
            mpp.Add(new State());
            for (var i = 0; i < N; i++)
            {
                var sum = (Normalized) ? double.NaN : 0d;
                for (int k = 0; k < K; k++)
                {
                    if (Normalized)
                    {
                        sum = LogExtention.eLnSum(sum, LogExtention.eLnProduct(LogExtention.eLn(distributionWeights[i][k]), LogExtention.eLn(GetProbability(distributions[i][k], observations, 0))));
                    }
                    else
                    {
                        sum += distributionWeights[i][k] * GetProbability(distributions[i][k], observations, 0);
                    }
                }
                if (Normalized)
                {
                    ComputationPath[0][i] = LogExtention.eLnProduct(LogExtention.eLn(startDistribution[i]), sum);
                }
                else
                {
                    ComputationPath[0][i] = startDistribution[i] * sum;
                }

                ReproducePath[0][i] = -1;
            }

            // Induction
            for (var t = 1; t < T; t++)
            {
                ComputationPath[t] = new double[N];
                ReproducePath[t]   = new int[N];
                mpp.Add(new State());
                for (var j = 0; j < N; j++)
                {
                    // argmax + max
                    var max = double.NegativeInfinity; //0;
                    for (var i = 0; i < N; i++)
                    {
                        var value = (Normalized) ? LogExtention.eLnProduct(ComputationPath[t - 1][i], LogExtention.eLn(transitionProbabilityMatrix[i][j])) :
                                    ComputationPath[t - 1][i] * transitionProbabilityMatrix[i][j];
                        if (value > max)
                        {
                            max = value;
                            ReproducePath[t][j] = i;
                        }
                    }
                    var sum = (Normalized) ? double.NaN : 0d;
                    for (var k = 0; k < K; k++)
                    {
                        if (Normalized)
                        {
                            sum = LogExtention.eLnSum(sum, LogExtention.eLnProduct(LogExtention.eLn(distributionWeights[j][k]), LogExtention.eLn(GetProbability(distributions[j][k], observations, 0))));
                        }
                        else
                        {
                            sum += distributionWeights[j][k] * GetProbability(distributions[j][k], observations, 0);
                        }
                    }
                    if (Normalized)
                    {
                        ComputationPath[t][j] = LogExtention.eLnProduct(max, sum);
                    }
                    else
                    {
                        ComputationPath[t][j] = max * sum;
                    }
                }
            }
            // Calculate results (from first observation)
            mpp[T - 1] = states[GetMaximumDeltaValueStateIndex(ComputationPath[T - 1])];
            for (var i = T - 2; i >= 0; i--)
            {
                mpp[i] = states[ReproducePath[i + 1][mpp[i + 1].Index]];
            }
            return(mpp);
        }