annotate toolboxes/FullBNT-1.0.7/graph/cliques_to_strong_jtree.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
rev   line source
wolffd@0 1 function [jtree, root, cliques, B, w] = mk_strong_jtree(cliques, ns, elim_order, MTG)
wolffd@0 2 % MK_SRONG_JTREE Make a strong junction tree.
wolffd@0 3 % [jtree, root, cliques, B, w] = mk_strong_jtree(cliques, ns, elim_order, MTG)
wolffd@0 4 %
wolffd@0 5 % Here is a definition of a strong jtree from Jensen et al. 1994:
wolffd@0 6 % "A junction tree is said to be strong if it has at least one distinguished clique R,
wolffd@0 7 % called a strong root, s.t. for each pair (C1,C2) of adjacent cliques in the tree,
wolffd@0 8 % with C1 closer to R than C2, there exists and ordering of [the nodes below] C2
wolffd@0 9 % that respects [the partial order] and with the vertices of the separator C1 intersect C2
wolffd@0 10 % preceeding the vertices [below C2] of C2 \ C1."
wolffd@0 11 %
wolffd@0 12 % For details, see
wolffd@0 13 % - Jensen, Jensen and Dittmer, "From influence diagrams to junction trees", UAI 94.
wolffd@0 14 %
wolffd@0 15 % MTG is the moralized, triangulated graph.
wolffd@0 16 % elim_order is the elimination ordering used to compute MTG.
wolffd@0 17
wolffd@0 18
wolffd@0 19 % Warning: this is a very naive implementation of the algorithm in Jensen et al.
wolffd@0 20
wolffd@0 21 n = length(elim_order);
wolffd@0 22 alpha(elim_order) = n:-1:1;
wolffd@0 23 % alpha(u) = i if we eliminate u at step n-i+1
wolffd@0 24 % i.e., vertices with higher alpha numbers are eliminated before vertices with lower numbers.
wolffd@0 25 % e.g., from the Jensen et al paper
wolffd@0 26 % node a=1 eliminated at step 6, so alpha(a)=16-6+1=11.
wolffd@0 27 % alpha = [11 1 2 10 9 3 4 7 5 8 13 12 6 16 15 14]
wolffd@0 28
wolffd@0 29
wolffd@0 30 % We sort the cliques in order of increasing index. The index of a clique C is defined as follows.
wolffd@0 31 % Let lower = {u | alpha(u) < alpha(v)}, and
wolffd@0 32 % let v in C be the highest-numbered vertex s.t. the vertices in W = lower intersect C
wolffd@0 33 % have a common neighbor u in U, where U = lower \ C.
wolffd@0 34 % If such a v exists, define index(C) = alpha(v), otherwise, index(C) = 1.
wolffd@0 35 % Intuitively, index(C) is the step in the elimination process at which C disappears.
wolffd@0 36
wolffd@0 37 num_cliques = length(cliques);
wolffd@0 38 index = zeros(1, num_cliques);
wolffd@0 39 for c = 1:num_cliques
wolffd@0 40 C = cliques{c};
wolffd@0 41 highest_num = -inf;
wolffd@0 42 for vi = 1:length(C)
wolffd@0 43 v = C(vi);
wolffd@0 44 lower = find(alpha < alpha(v));
wolffd@0 45 W = myintersect(lower, C);
wolffd@0 46 U = mysetdiff(lower, C);
wolffd@0 47 found = 0;
wolffd@0 48 for ui=1:length(U)
wolffd@0 49 u = U(ui);
wolffd@0 50 if mysubset(W, neighbors(MTG, u))
wolffd@0 51 found = 1;
wolffd@0 52 break;
wolffd@0 53 end
wolffd@0 54 end
wolffd@0 55 if found
wolffd@0 56 if alpha(v) > highest_num
wolffd@0 57 highest_num = alpha(v);
wolffd@0 58 end
wolffd@0 59 end
wolffd@0 60 end
wolffd@0 61 if highest_num == -inf
wolffd@0 62 index(c) = 1;
wolffd@0 63 else
wolffd@0 64 index(c) = highest_num;
wolffd@0 65 end
wolffd@0 66 end
wolffd@0 67
wolffd@0 68
wolffd@0 69 % Permute the cliques so that they are ordered according to index
wolffd@0 70 [dummy, clique_order] = sort(index);
wolffd@0 71 cliques = cliques(clique_order);
wolffd@0 72
wolffd@0 73 w = zeros(num_cliques, 1);
wolffd@0 74 B = sparse(num_cliques, 1);
wolffd@0 75 for i=1:num_cliques
wolffd@0 76 B(i, cliques{i}) = 1;
wolffd@0 77 w(i) = prod(ns(cliques{i}));
wolffd@0 78 end
wolffd@0 79
wolffd@0 80 % Pearl p113 suggests ordering the cliques by rank of the highest vertex in each clique.
wolffd@0 81 % However, this will only work if we use maximum cardinality search.
wolffd@0 82
wolffd@0 83
wolffd@0 84 % Join up the cliques so that they satisfy the Running Intersection Property.
wolffd@0 85 % This states that, for all k > 1, S(k) subseteq C(j) for some j < k, where
wolffd@0 86 % S(k) = C(k) intersect (union_{i=1}^{k-1} C(i))
wolffd@0 87 jtree = sparse(num_cliques, num_cliques);
wolffd@0 88 for k=2:num_cliques
wolffd@0 89 S = [];
wolffd@0 90 for i=1:k-1
wolffd@0 91 S = myunion(S, cliques{i});
wolffd@0 92 end
wolffd@0 93 S = myintersect(S, cliques{k});
wolffd@0 94 found = 0;
wolffd@0 95 for j=1:k-1
wolffd@0 96 if mysubset(S, cliques{j})
wolffd@0 97 found = 1;
wolffd@0 98 break;
wolffd@0 99 end
wolffd@0 100 end
wolffd@0 101 if ~found
wolffd@0 102 disp(['RIP is violated for clique ' num2str(k)]);
wolffd@0 103 end
wolffd@0 104 jtree(k,j)=1;
wolffd@0 105 jtree(j,k)=1;
wolffd@0 106 end
wolffd@0 107
wolffd@0 108 % Pearl p113 suggests connecting Ci to a predecessor Cj (j < i) sharing
wolffd@0 109 % the highest number of vertices with Ci (i.e., the heaviest i-j edge
wolffd@0 110 % in the jgraph). However, this will only work if we use maximum cardinality search.
wolffd@0 111
wolffd@0 112 root = 1;
wolffd@0 113
wolffd@0 114