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)); }
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); }
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); }
private double CalculateTransitionProbabilityMatrixEntry(double nominator, double denominator, bool normalized) { if (denominator.EqualsToZero()) { return(0); } return((normalized) ? LogExtention.eExp(LogExtention.eLnProduct(nominator, -denominator)) : nominator / denominator); }
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); }
public void eLnProduct_XisNaN_YReturned() { var x = double.NaN; var y = 1d; var result = LogExtention.eLnProduct(x, y); Assert.AreEqual(double.NaN, result); }
public void eLnProduct_YandXnotEqualsNan_XPlusYReturned() { var x = 1d; var y = 1d; var result = LogExtention.eLnProduct(x, y); Assert.AreEqual(x + y, result); }
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); }
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); }
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); }
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); }
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); }
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)); }
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); }