예제 #1
0
        /// <summary>
        ///   Generates a random vector of observations from the model.
        /// </summary>
        ///
        /// <param name="samples">The number of samples to generate.</param>
        /// <param name="logLikelihood">The log-likelihood of the generated observation sequence.</param>
        /// <param name="path">The Viterbi path of the generated observation sequence.</param>
        ///
        /// <example>
        ///   An usage example is available at the <see cref="Generate(int)"/> documentation page.
        /// </example>
        ///
        /// <returns>A random vector of observations drawn from the model.</returns>
        ///
        public int[] Generate(int samples, out int[] path, out double logLikelihood)
        {
            double[] transitions = Probabilities;
            double[] emissions;

            int[] observations = new int[samples];
            logLikelihood = Double.NegativeInfinity;
            path          = new int[samples];


            // For each observation to be generated
            for (int t = 0; t < observations.Length; t++)
            {
                // Navigate randomly on one of the state transitions
                int state = GeneralDiscreteDistribution.Random(Matrix.Exp(transitions));

                // Generate a sample for the state
                emissions = Emissions.GetRow(state);
                int symbol = GeneralDiscreteDistribution.Random(Matrix.Exp(emissions));

                // Store the sample
                observations[t] = symbol;
                path[t]         = state;

                // Compute log-likelihood up to this point
                logLikelihood = Accord.Math.Special.LogSum(logLikelihood,
                                                           transitions[state] + emissions[symbol]);

                // Continue sampling
                transitions = Transitions.GetRow(state);
            }

            return(observations);
        }
예제 #2
0
        /// <summary>
        ///   Generates a random vector of observations from the model.
        /// </summary>
        ///
        /// <param name="samples">The number of samples to generate.</param>
        /// <param name="logLikelihood">The log-likelihood of the generated observation sequence.</param>
        /// <param name="path">The Viterbi path of the generated observation sequence.</param>
        ///
        /// <returns>A random vector of observations drawn from the model.</returns>
        ///
        public Array Generate(int samples, out int[] path, out double logLikelihood)
        {
            double[] transitions = Probabilities;

            logLikelihood = Double.NegativeInfinity;
            path          = new int[samples];

            var multivariate = Emissions as ISampleableDistribution <double[]>[];

            if (multivariate != null)
            {
                double[][] observations = new double[samples][];

                // For each observation to be generated
                for (int t = 0; t < observations.Length; t++)
                {
                    // Navigate randomly on one of the state transitions
                    int state = GeneralDiscreteDistribution.Random(Matrix.Exp(transitions));

                    // Generate a sample for the state
                    double[] symbol = multivariate[state].Generate();

                    // Store the sample
                    observations[t] = symbol;
                    path[t]         = state;

                    // Compute log-likelihood up to this point
                    logLikelihood = Accord.Math.Special.LogSum(logLikelihood,
                                                               transitions[state] + Emissions[state].LogProbabilityFunction(symbol));

                    // Continue sampling
                    transitions = Transitions.GetRow(state);
                }

                return(observations);
            }

            var univariate = Emissions as ISampleableDistribution <double>[];

            if (univariate != null)
            {
                double[] observations = new double[samples];

                // For each observation to be generated
                for (int t = 0; t < observations.Length; t++)
                {
                    // Navigate randomly on one of the state transitions
                    int state = GeneralDiscreteDistribution.Random(Matrix.Exp(transitions));

                    // Generate a sample for the state
                    double symbol = univariate[state].Generate();

                    // Store the sample
                    observations[t] = symbol;
                    path[t]         = state;

                    // Compute log-likelihood up to this point
                    logLikelihood = Accord.Math.Special.LogSum(logLikelihood,
                                                               transitions[state] + Emissions[state].LogProbabilityFunction(symbol));

                    // Continue sampling
                    transitions = Transitions.GetRow(state);
                }

                return(observations);
            }

            throw new ArgumentException("The model's emission distributions do not support sampling.");
        }