function s = viterbi(x,hmm);
  % Returned s is MAP state sequence for output sequence x

  ns= length(hmm.p0);
  n = length(x);

  lp0 = log(hmm.p0);
  lPo = log(hmm.Po);
  lPt = log(hmm.Pt);
  
  val = zeros(ns,n);
  pointers = zeros(ns,n);		% back pointers
  
  val(:,1) = lp0' + lPo(:,x(1));
  for t=2:n,
    [val(:,t), pointers(:,t)] = max(op(val(:,t-1),'+',lPt)',[],2);
    val(:,t) = val(:,t) + lPo(:,x(t));
  end;
  
  [dummy, s(n)] = max(val(:,n));
  for t=n-1:-1:1,
    s(t) = pointers(s(t+1),t+1);
  end;
