public double RunForward <TEmmisionType>(IList <IObservation> observations, IHiddenMarkovModel <TEmmisionType> model) where TEmmisionType : IDistribution { var alphaEstimator = new AlphaEstimator <TEmmisionType>(); _alpha = alphaEstimator.Estimate(new BasicEstimationParameters <TEmmisionType> { Model = model, Observations = observations, Normalized = Normalized }); var T = observations.Count; var result = (Normalized) ? double.NaN : 0d; // Calculate results for (var i = 0; i < model.N; i++) { if (Normalized) { result = LogExtention.eLnSum(result, _alpha[T - 1][i]); } else { result += _alpha[T - 1][i]; } } return(result); }
public double[][] Estimate(KsiGammaTransitionProbabilityMatrixParameters <TDistribution> parameters) { if (_estimatedTransitionProbabilityMatrix != null) { return(_estimatedTransitionProbabilityMatrix); } _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 denominator = (parameters.Model.Normalized) ? double.NaN : 0, nominator = (parameters.Model.Normalized) ? double.NaN : 0; for (var t = 0; t < parameters.T - 1; t++) { if (parameters.Model.Normalized) { nominator = LogExtention.eLnSum(nominator, parameters.Ksi[t][i, j]); denominator = LogExtention.eLnSum(denominator, parameters.Gamma[t][i]); } else { nominator += parameters.Ksi[t][i, j]; denominator += parameters.Gamma[t][i]; } } _estimatedTransitionProbabilityMatrix[i][j] = CalculateTransitionProbabilityMatrixEntry(nominator, denominator, parameters.Normalized); } } return(_estimatedTransitionProbabilityMatrix); }
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(MuEstimationParameters <TDistribution> parameters) { if (_muUnivariate != null) { return(_muUnivariate); } _muUnivariate = new double[parameters.Model.N]; for (var n = 0; n < parameters.Model.N; n++) { var T = parameters.Observations.Count; var mean = 0d; var nK = 0d; for (var t = 0; t < T; t++) { if (parameters.Model.Normalized) { nK += LogExtention.eExp(parameters.Gamma[t][n]); mean += parameters.Observations[t].Value[0] * LogExtention.eExp(parameters.Gamma[t][n]); } else { nK += parameters.Gamma[t][n]; mean += parameters.Observations[t].Value[0] * parameters.Gamma[t][n]; } } _muUnivariate[n] = mean / nK; } return(_muUnivariate); }
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(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); }
public void eLn_XisZero_NaNReturned() { var x = 0; var result = LogExtention.eLn(x); Assert.AreEqual(double.NaN, result); }
public void eExp_XisNumber_ePowerXReturned() { var x = 1d; var result = LogExtention.eExp(x); Assert.AreEqual(Math.E, result); }
public void eLn_XisGreaterThanZero_LogXReturned() { var x = 1d; var result = LogExtention.eLn(x); Assert.AreEqual(0, result); }
public void eExp_XisNaN_ZeroReturned() { var x = double.NaN; var result = LogExtention.eExp(x); Assert.AreEqual(0, result); }
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_YandXnotEqualsNan_XPlusYReturned() { var x = 1d; var y = 1d; var result = LogExtention.eLnProduct(x, y); Assert.AreEqual(x + y, result); }
public void eLnSum_XGreaterThanY_eLnSumReturned() { var x = 2d; var y = 1d; var result = LogExtention.eLnSum(x, y); Assert.AreEqual(x + LogExtention.eLn(1 + Math.Exp(y - x)), 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 void eLnSum_YisNaN_XReturned() { var x = 1d; var y = double.NaN; var result = LogExtention.eLnSum(x, y); Assert.AreEqual(x, result); }
public void eLnSum_YGreaterThanX_eLnSumReturned() { var x = 1d; var y = 2d; var result = LogExtention.eLnSum(x, y); Assert.AreEqual(y + LogExtention.eLn(1 + Math.Exp(x - y)), result); }
public void eLnProduct_XisNaN_YReturned() { var x = double.NaN; var y = 1d; var result = LogExtention.eLnProduct(x, y); Assert.AreEqual(double.NaN, result); }
public double[][,] Estimate(SigmaEstimationParameters <TDistribution, double[][]> parameters) { if (_sigmaMultivariate != null) { return(_sigmaMultivariate); } try { _sigmaMultivariate = new double[parameters.Model.N][, ]; var K = parameters.Observations[0].Dimention; var T = parameters.Observations.Count; for (var n = 0; n < parameters.Model.N; n++) { var covariance = new double[K, K]; var nK = 0d; for (var t = 0; t < T; t++) { var x = parameters.Observations[t].Value; var z = x.Substruct(parameters.Mean[n]); var m = z.OuterProduct(z); if (parameters.Model.Normalized) { nK += LogExtention.eExp(parameters.Gamma[t][n]); m = m.Product(LogExtention.eExp(parameters.Gamma[t][n])); } else { nK += parameters.Gamma[t][n]; m = m.Product(parameters.Gamma[t][n]); } covariance = covariance.Add(m); } _sigmaMultivariate[n] = covariance.Product(1 / nK); var matrix = new Matrix(_sigmaMultivariate[n]); if (!matrix.PositiviDefinite) { _sigmaMultivariate[n] = matrix.ConvertToPositiveDefinite(); Debug.WriteLine("HMM State {0} Sigma is not Positive Definite. Converting.", n); Debug.WriteLine("{0}", matrix); } Debug.WriteLine("HMM State {0} Sigma : {1}", n, new Matrix(_sigmaMultivariate[n])); } } catch (Exception) { for (var n = 0; n < parameters.Model.N; n++) { Debug.WriteLine("HMM State {0} Sigma : {1}", n, new Matrix(_sigmaMultivariate[n])); } throw; } return(_sigmaMultivariate); }
protected void EstimatePi(double[][] gamma) { var checksum = 0d; for (var i = 0; i < _model.N; i++) { _estimatedPi[i] = (_model.Normalized) ? LogExtention.eExp(gamma[0][i]) : gamma[0][i]; checksum += _estimatedPi[i]; } CheckPi(checksum); }
public double[, ][,] Estimate(MixtureSigmaEstimationParameters <TDistribution> parameters) { if (_sigma != null) { return(_sigma); } try { _sigma = new double[parameters.Model.N, parameters.L][, ]; for (var i = 0; i < parameters.Model.N; i++) { for (var l = 0; l < parameters.L; l++) { var denominator = 0.0d; var nominator = new double[parameters.Observations[0].Dimention, parameters.Observations[0].Dimention]; for (var t = 0; t < parameters.Observations.Count; t++) { // TODO : weights here var weight = GetWeightValue(t, parameters.ObservationWeights); var gammaComponents = (parameters.Model.Normalized) ? LogExtention.eExp(parameters.GammaComponents[t][i, l]) : parameters.GammaComponents[t][i, l]; var x = parameters.Observations[t].Value; var z = x.Substruct(parameters.Mu[i, l]); var m = z.OuterProduct(z); m = m.Product(weight * gammaComponents); denominator += weight * gammaComponents; nominator = nominator.Add(m); } _sigma[i, l] = nominator.Product(1 / denominator); var matrix = new Matrix(_sigma[i, l]); if (!matrix.PositiviDefinite) { _sigma[i, l] = matrix.ConvertToPositiveDefinite(); Debug.WriteLine("HMM State [{0},{1}] Sigma is not Positive Definite. Converting.", i, l); Debug.WriteLine("{0}", matrix); } } } } catch (Exception) { for (var i = 0; i < parameters.Model.N; i++) { for (var l = 0; l < parameters.L; l++) { Debug.WriteLine("Mixture Sigma [{0},{1}] : {2}", i, l, new Matrix(_sigma[i, l])); } } throw; } return(_sigma); }
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); }
private double GetWeightValue(int t, decimal[] weights) { var weight = 0.0; if (weights != null) { weight = (_parameters.Model.Normalized) ? LogExtention.eLn((double)weights[t]) : (double)weights[t]; } else { weight = (_parameters.Model.Normalized) ? 0 : 1; } return(weight); }
public void Denormalize() { if (!_denormalized) { for (var i = 0; i < _parameters.Model.N; i++) { for (var l = 0; l < _parameters.L; l++) { _coefficients[i][l] = LogExtention.eExp(_coefficients[i][l]); } } _denormalized = true; } }
public double[] Estimate(PiParameters parameters) { if (_estimatedPi != null) { return(_estimatedPi); } _estimatedPi = new double[parameters.N]; for (var i = 0; i < parameters.N; i++) { _estimatedPi[i] = (parameters.Normalized) ? LogExtention.eExp(parameters.Gamma[0][i]) : parameters.Gamma[0][i]; } return(_estimatedPi); }
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); }
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 double[, ][] Estimate(MixtureCoefficientEstimationParameters <TDistribution> parameters) { if (_mu != null) { return(_mu); } try { _mu = new double[parameters.Model.N, parameters.L][]; for (var i = 0; i < parameters.Model.N; i++) { for (var l = 0; l < parameters.L; l++) { var denominator = 0.0d; var nominator = new double[parameters.Observations[0].Dimention]; for (var t = 0; t < parameters.Observations.Count; t++) { // TODO : weights here var weight = GetWeightValue(t, parameters.ObservationWeights); var x = parameters.Observations[t].Value; var gamma = (parameters.Model.Normalized) ? LogExtention.eExp(parameters.GammaComponents[t][i, l]) : parameters.GammaComponents[t][i, l]; denominator += weight * gamma; x = x.Product(gamma * weight); nominator = nominator.Add(x); } _mu[i, l] = nominator.Product(1 / denominator); } } } catch (Exception) { for (var i = 0; i < parameters.Model.N; i++) { for (var l = 0; l < parameters.L; l++) { Debug.WriteLine("Mixture Mu [{0},{1}] : {2}", i, l, new Vector(_mu[i, l])); } } throw; } return(_mu); }
public double[][] Estimate(MuEstimationParameters <TDistribution> parameters) { if (_muMultivariate != null) { return(_muMultivariate); } try { _muMultivariate = new double[parameters.Model.N][]; var K = parameters.Observations[0].Dimention; // Number of dimentions var T = parameters.Observations.Count; for (var n = 0; n < parameters.Model.N; n++) { var mean = new double[K]; var nK = 0d; for (var t = 0; t < T; t++) { if (parameters.Model.Normalized) { nK += LogExtention.eExp(parameters.Gamma[t][n]); mean = mean.Add(parameters.Observations[t].Value.Product(LogExtention.eExp(parameters.Gamma[t][n]))); } else { nK += parameters.Gamma[t][n]; mean = mean.Add(parameters.Observations[t].Value.Product(parameters.Gamma[t][n])); } } _muMultivariate[n] = mean.Product(1 / nK); Debug.WriteLine(string.Format("HMM State {0} : Mu {1}", n, new Vector(_muMultivariate[n]))); } } catch (Exception) { for (var n = 0; n < parameters.Model.N; n++) { Debug.WriteLine(string.Format("HMM State {0} : Mu {1}", n, new Vector(_muMultivariate[n]))); } throw; } return(_muMultivariate); }
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); }