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

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