001 package aima.probability.reasoning; 002 003 import java.util.ArrayList; 004 import aima.probability.RandomVariable; 005 import aima.util.Matrix; 006 007 /** 008 * @author Ravi Mohan 009 * 010 */ 011 012 public class FixedLagSmoothing { 013 014 // This implementation is almost certainly wrong (see comments below). 015 // This is faithful to the algorithm in the book but I think there are 016 // some errors in the algorithmas published. Need to clarify with Dr N. 017 018 private HiddenMarkovModel hmm; 019 020 private int timelag; 021 022 private ArrayList<String> evidenceFromSmoothedStepToPresent; 023 024 private int time; 025 026 private RandomVariable forwardMessage; 027 028 private Matrix B; 029 030 public FixedLagSmoothing(HiddenMarkovModel hmm, int timelag) { 031 this.hmm = hmm; 032 this.timelag = timelag; 033 this.evidenceFromSmoothedStepToPresent = new ArrayList<String>(); 034 this.time = 1; 035 this.forwardMessage = hmm.prior(); 036 this.B = hmm.transitionModel().unitMatrix(); 037 } 038 039 public RandomVariable smooth(String perception) { 040 041 evidenceFromSmoothedStepToPresent.add(perception); 042 Matrix O_t = hmm.sensorModel().asMatrix(perception); 043 Matrix transitionMatrix = hmm.transitionModel().asMatrix(); 044 if (time > timelag) { 045 046 forwardMessage = hmm.forward(forwardMessage, perception); // This 047 // seems 048 // WRONG 049 // I think this should be 050 // forwardMessage = hmm.forward(forwardMessage, 051 // evidenceFromSmoothedStepToPresent.get(0)); 052 // this the perception at t-d. the book's algorithm 053 // uses the latest perception. 054 evidenceFromSmoothedStepToPresent.remove(0); 055 Matrix O_t_minus_d = hmm.sensorModel().asMatrix( 056 evidenceFromSmoothedStepToPresent.get(0)); 057 058 B = O_t_minus_d.inverse().times( 059 transitionMatrix.inverse().times( 060 B.times(transitionMatrix.times(O_t)))); 061 062 } else { 063 064 B = B.times(transitionMatrix.times(O_t)); 065 066 } 067 time += 1; 068 if (time > timelag) { 069 070 Matrix one = hmm.prior().createUnitBelief().asMatrix(); 071 Matrix forwardMatrix = forwardMessage.asMatrix(); 072 RandomVariable result = hmm.prior().duplicate(); 073 Matrix backwardMessage = (B.times(one)); 074 075 result.updateFrom(forwardMatrix.arrayTimes(backwardMessage)); 076 077 result.normalize(); 078 return result; 079 } else { 080 return null; 081 } 082 083 } 084 085 }