wolffd@0: function CPD = hhmmF_CPD(bnet, self, Qself, Fbelow, varargin) wolffd@0: % HHMMF_CPD Make the CPD for an F node in a hierarchical HMM wolffd@0: % CPD = hhmmF_CPD(bnet, self, Qself, Fbelow, ...) wolffd@0: % wolffd@0: % Qps wolffd@0: % \ wolffd@0: % \ wolffd@0: % Fself wolffd@0: % / | wolffd@0: % / | wolffd@0: % Qself Fbelow wolffd@0: % wolffd@0: % We assume nodes are ordered (numbered) as follows: Qps, Q, Fbelow, F wolffd@0: % All nodes numbers should be from slice 1. wolffd@0: % wolffd@0: % If Fbelow if missing, this becomes a regular tabular_CPD. wolffd@0: % Qps may be omitted. wolffd@0: % wolffd@0: % optional args [defaults] wolffd@0: % wolffd@0: % Qps - node numbers. wolffd@0: % termprob - termprob(k,i,2) = prob finishing given Q(d)=i and Q(1:d-1)=k [ finish in last state wp 0.9] wolffd@0: % wolffd@0: % hhmmF_CPD is a subclass of tabular_CPD so we inherit inference methods like CPD_to_pot, etc. wolffd@0: % wolffd@0: % We create an isolated tabular_CPD with no F parent to learn termprob wolffd@0: % so we can avail of e.g., entropic or Dirichlet priors. wolffd@0: % wolffd@0: % For details, see "Linear-time inference in hierarchical HMMs", Murphy and Paskin, NIPS'01. wolffd@0: wolffd@0: wolffd@0: wolffd@0: Qps = []; wolffd@0: % get parents wolffd@0: for i=1:2:length(varargin) wolffd@0: switch varargin{i}, wolffd@0: case 'Qps', Qps = varargin{i+1}; wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: ns = bnet.node_sizes(:); wolffd@0: Qsz = ns(Qself); wolffd@0: Qpsz = prod(ns(Qps)); wolffd@0: CPD.Qsz = Qsz; wolffd@0: CPD.Qpsz = Qpsz; wolffd@0: wolffd@0: ps = parents(bnet.dag, self); wolffd@0: CPD.Fbelow_ndx = find_equiv_posns(Fbelow, ps); wolffd@0: CPD.Qps_ndx = find_equiv_posns(Qps, ps); wolffd@0: CPD.Qself_ndx = find_equiv_posns(Qself, ps); wolffd@0: wolffd@0: % set default arguments wolffd@0: p = 0.9; wolffd@0: %termprob(k,i,t) Might terminate if i=Qsz; will not terminate if i