public ForwardBackward(List<HMM> HmmList, List<InputLine> Sequence) { m_HmmList = HmmList; m_Sequence = Sequence; m_WorkingStates = new List<HMM>(); m_WorkingStatesQty = 0; foreach (HMM Hmm in HmmList) if (!(Hmm.IsFirst || Hmm.IsFinal)) { m_WorkingStatesQty++; m_WorkingStates.Add(Hmm); } m_BeginingState = HmmList.Find(x => x.IsFirst == true); m_EndingState = HmmList.Find(x => x.IsFinal == true); m_FullSequenceCount = Sequence.Count + 2; // + 2 = for ending and beg BackwardValues = new double[m_FullSequenceCount,m_WorkingStatesQty]; ForwardValues = new double[m_FullSequenceCount,m_WorkingStatesQty]; for(int I = 0; I < m_FullSequenceCount; I++) for(int J = 0; J < m_WorkingStatesQty; J++) { BackwardValues[I,J] = 0; ForwardValues[I,J] = 0; } // backward L + 1; for (int I = 0; I < m_WorkingStatesQty; I++) BackwardValues[m_FullSequenceCount - 1, I] = 1; // Forward 0 for (int I = 0; I < m_WorkingStatesQty; I++) ForwardValues[0, I] = 1; }
public Viterbi(List<HMM> HmmList, List<InputLine> Sequence) { m_WorkingStates = new List<HMM>(); m_Sequence = Sequence; foreach (HMM Hmm in HmmList) if (!(Hmm.IsFirst || Hmm.IsFinal)) m_WorkingStates.Add(Hmm); m_BeginingState = HmmList.Find(x => x.IsFirst == true); m_EndingState = HmmList.Find(x => x.IsFinal == true); //+2 for fist and last state Results = new ViterbiResult[Sequence.Count + 2, m_WorkingStates.Count]; }
public ViterbiResult GetResult(int Position, HMM State) { int StateIndex = -1; for (int I = 0; I < m_WorkingStates.Count; I++) if (m_WorkingStates [I].Name == State.Name) { StateIndex = I; break; } //cheat if (StateIndex == -1) StateIndex = 0; return Results[Position, StateIndex]; }
private void MakeStep(int Pos, HMM State, int ArrayStateIndex) { double PrevMaxStateValue = 0; string PrevStateName = ""; for (int I = 0; I < m_WorkingStates.Count; I++) { HMM PrevState = (Pos == 1) ? m_BeginingState : m_WorkingStates[I]; double PrevStateValue = Results[Pos - 1, I].Possibility * PrevState.GetTransitionStrength(State.Name); if (PrevStateValue > PrevMaxStateValue) { PrevMaxStateValue = PrevStateValue; PrevStateName = PrevState.Name; } } double Emission = (Pos == m_Sequence.Count + 1) ? 1 : State.GetEmmisionStrength(m_Sequence[Pos - 1].Sequence); Results[Pos, ArrayStateIndex] = new ViterbiResult( Pos, State.Name, PrevStateName, Emission * PrevMaxStateValue); }
public static void ReadFile(string FileName) { HmmList = new List<HMM>(); Sequence = new List<InputLine>(); using (StreamReader SR = new StreamReader(FileName)) { string FileLine; LastState = null; Regex StatesReg = new Regex(StatesRegex); Regex StatesEm = new Regex(StatesEmissions); Regex SeqReg = new Regex(SequenceRegex); while((FileLine = SR.ReadLine()) != null) { Match M = StatesReg.Match(FileLine); if (M.Success) AddModifyState(M); M = StatesEm.Match(FileLine); if (M.Success) AddEmission(M, LastState); M = SeqReg.Match(FileLine); if (M.Success) AddToSequence(FileLine); } foreach(HMM H in HmmList) { Console.WriteLine(H.Name); foreach(HmmLink L in H.Links) Console.WriteLine("\t" + L.Hmm.Name + " = " + L.Strength.ToString()); foreach(Emission E in H.Emissions) Console.WriteLine("" + "Emmision for " + E.EmissionSequence + " is " + E.EmissionStrength.ToString()); } foreach(InputLine I in Sequence) Console.WriteLine(I.SequenceNo.ToString() + " " + I.StateName + " " + I.Sequence); } }
private static HMM FindOrCreate(List<HMM> HList, string Name) { HMM Hmm = HList.Find (x => x.Name == Name); if (Hmm == null) { Hmm = new HMM (Name); HList.Add (Hmm); } return Hmm; }
private static void AddModifyState(Match M) { //State St1 Transitions: B = 0.000 St1 = 0.960 St2 = 0.039 E = 0.001 LastState = FindOrCreate(HmmList, M.Groups [1].Value); foreach (Capture C in M.Groups[3].Captures) AddLink(LastState, C.Value); }
private static void AddLink(HMM Hmm, string Link) { //State = str string[] Expr = Link.Split(' '); HmmLink NewLink = new HmmLink(); NewLink.Hmm = FindOrCreate(HmmList, Expr[0]); NewLink.Strength = double.Parse(Expr[2]); if (Hmm.Links.Exists(x => x.Hmm.Name == NewLink.Hmm.Name)) throw (new Exception("Redefining value found for: " + Hmm.Name + "at " + NewLink.Hmm.Name)); Hmm.Links.Add(NewLink); }
private static void AddEmission(Match M, HMM StateToEdit) { // Emissions a = 0.139 b = 0.639 c = 0.222 foreach(Capture C in M.Groups[2].Captures) { string[] Expr = C.Value.Split(' '); StateToEdit.Emissions.Add( new Emission(Expr[0], double.Parse(Expr[2]))); } }
private double CalcForwardState(HMM Hmm, int SeqPos) { double Result = 0; int State = 0; double[] LogSums = new double[m_WorkingStatesQty]; double EmmisionStr = 1; // for endingState if (SeqPos < m_Sequence.Count) EmmisionStr = Hmm.GetEmmisionStrength(m_Sequence[SeqPos].Sequence); foreach(HMM HmmKm1 in m_WorkingStates) { // explog trick LogSums[State] = Math.Log(EmmisionStr) + Math.Log(HmmKm1.GetTransitionStrength(Hmm.Name)) + Math.Log(ForwardValues[SeqPos,State]); // seqpos - 1 + 1 to shift for begining state State++; } double MaxVal = LogSums[0]; for(int I = 1; I < m_WorkingStatesQty; I++) MaxVal = Math.Max(MaxVal,LogSums[I]); for(int I = 0; I < m_WorkingStatesQty; I++) Result += Math.Exp(MaxVal + Math.Log(Math.Exp(LogSums[I] - MaxVal))); return Result; }
private double CalcBackwardState(HMM Hmm, int SeqPos) { double Result = 0; int State = 0; double[] LogSums = new double[m_WorkingStatesQty]; foreach (HMM HmmKp1 in m_WorkingStates) { LogSums[State] = Math.Log(Hmm.GetTransitionStrength(HmmKp1.Name)) + Math.Log(HmmKp1.GetEmmisionStrength(m_Sequence[SeqPos + 1].Sequence)) + Math.Log(BackwardValues[SeqPos + 2,State]); // + 2 to shift from ending result State++; } double MaxVal = LogSums[0]; for (int I = 1; I < m_WorkingStatesQty; I++) MaxVal = Math.Max(MaxVal,LogSums[I]); for(int I = 0; I < m_WorkingStatesQty; I++) Result += Math.Exp(MaxVal + Math.Log(Math.Exp(LogSums[I] - MaxVal))); return Result; }