wolffd@0: function partial_order = determine_elim_constraints(bnet, onodes) wolffd@0: % DETERMINE_ELIM_CONSTRAINTS Determine what the constraints are (if any) on the elimination ordering. wolffd@0: % partial_order = determine_elim_constraints(bnet, onodes) wolffd@0: % wolffd@0: % A graph with different kinds of nodes (e.g., discrete and cts, or decision and rnd) is called marked. wolffd@0: % A strong root is guaranteed to exist if the marked graph is triangulated and does not have any paths of wolffd@0: % the form discrete -> cts -> discrete. In general we need to add extra edges to wolffd@0: % the moral graph to ensure this (see example in Lauritzen (1992) fig 3b). wolffd@0: % However, a simpler sufficient condition is to eliminate all the cts nodes before the discrete ones, wolffd@0: % because then, as we move from the leaves to the root, the cts nodes get marginalized away wolffd@0: % and we are left with purely discrete cliques. wolffd@0: % wolffd@0: % partial_order(i,j)=1 if we must marginalize j *before* i wolffd@0: % (so i will be nearer the strong root). wolffd@0: % If the hidden nodes are either all discrete or all cts, we set partial_order = []. wolffd@0: % wolffd@0: % For details, see wolffd@0: % - Jensen, Jensen and Dittmer, "From influence diagrams to junction trees", UAI 94. wolffd@0: % - Lauritzen, "Propgation of probabilities, means, and variances in mixed graphical wolffd@0: % association models", JASA 87(420):1098--1108, 1992. wolffd@0: % - K. Olesen, "Causal probabilistic networks with both discrete and continuous variables", wolffd@0: % IEEE Pami 15(3), 1993 wolffd@0: wolffd@0: wolffd@0: n = length(bnet.dag); wolffd@0: pot_type = determine_pot_type(bnet, onodes); wolffd@0: if (pot_type == 'd') | (pot_type == 'g') wolffd@0: partial_order = []; wolffd@0: return; wolffd@0: end wolffd@0: wolffd@0: wolffd@0: partial_order = sparse(n,n); wolffd@0: partial_order(bnet.dnodes, bnet.cnodes) = 1; wolffd@0: wolffd@0: % Integrate out cts nodes before their discrete parents - see Olesen (1993) p9 wolffd@0: % This method gives the wrong results on cg1.m! wolffd@0: if 0 wolffd@0: for i=bnet.cnodes(:)' wolffd@0: dps = myintersect(parents(bnet.dag, i), bnet.dnodes); wolffd@0: partial_order(dps, i)=1; wolffd@0: end wolffd@0: end