/// <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); }
/// <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."); }