annotate toolboxes/FullBNT-1.0.7/bnt/examples/static/Belprop/gmux1.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 % Test gmux.
Daniel@0 2 % The following model, where Y is a gmux node,
Daniel@0 3 % and M is set to 1, should be equivalent to X1 -> Y
Daniel@0 4 %
Daniel@0 5 % X1 Xn M
Daniel@0 6 % \ | /
Daniel@0 7 % Y
Daniel@0 8
Daniel@0 9 n = 3;
Daniel@0 10 N = n+2;
Daniel@0 11 Xs = 1:n;
Daniel@0 12 M = n+1;
Daniel@0 13 Y = n+2;
Daniel@0 14 dag = zeros(N,N);
Daniel@0 15 dag([Xs M], Y)=1;
Daniel@0 16
Daniel@0 17 dnodes = M;
Daniel@0 18 ns = zeros(1, N);
Daniel@0 19 sz = 2;
Daniel@0 20 ns(Xs) = sz;
Daniel@0 21 ns(M) = n;
Daniel@0 22 ns(Y) = sz;
Daniel@0 23
Daniel@0 24 bnet = mk_bnet(dag, ns, 'discrete', M, 'observed', [M Y]);
Daniel@0 25
Daniel@0 26 psz = ns(Xs(1));
Daniel@0 27 selfsz = ns(Y);
Daniel@0 28
Daniel@0 29 W = randn(selfsz, psz);
Daniel@0 30 mu = randn(selfsz, 1);
Daniel@0 31 Sigma = eye(selfsz, selfsz);
Daniel@0 32
Daniel@0 33 bnet.CPD{M} = root_CPD(bnet, M);
Daniel@0 34 for i=Xs(:)'
Daniel@0 35 bnet.CPD{i} = gaussian_CPD(bnet, i, 'mean', zeros(psz, 1), 'cov', eye(psz, psz));
Daniel@0 36 end
Daniel@0 37 bnet.CPD{Y} = gmux_CPD(bnet, Y, 'mean', mu, 'weights', W, 'cov', Sigma);
Daniel@0 38
Daniel@0 39 evidence = cell(1,N);
Daniel@0 40 yval = randn(selfsz, 1);
Daniel@0 41 evidence{Y} = yval;
Daniel@0 42 m = 2;
Daniel@0 43 %notm = not(m-1)+1; % only valid for n=2
Daniel@0 44 notm = mysetdiff(1:n, m);
Daniel@0 45 evidence{M} = m;
Daniel@0 46
Daniel@0 47 engines = {};
Daniel@0 48 engines{end+1} = jtree_inf_engine(bnet);
Daniel@0 49 engines{end+1} = pearl_inf_engine(bnet, 'protocol', 'parallel');
Daniel@0 50
Daniel@0 51 for e=1:length(engines)
Daniel@0 52 engines{e} = enter_evidence(engines{e}, evidence);
Daniel@0 53 mXm{e} = marginal_nodes(engines{e}, Xs(m));
Daniel@0 54
Daniel@0 55 % Since M=m, only Xm was updated.
Daniel@0 56 % Hence the posterior on Xnotm should equal the prior.
Daniel@0 57 for i=notm(:)'
Daniel@0 58 mXnotm = marginal_nodes(engines{e}, Xs(i));
Daniel@0 59 assert(approxeq(mXnotm.mu, zeros(psz,1)))
Daniel@0 60 assert(approxeq(mXnotm.Sigma, eye(psz, psz)))
Daniel@0 61 end
Daniel@0 62 end
Daniel@0 63
Daniel@0 64 % Check that all engines give the same posterior
Daniel@0 65 for e=2:length(engines)
Daniel@0 66 assert(approxeq(mXm{e}.mu, mXm{1}.mu))
Daniel@0 67 assert(approxeq(mXm{e}.Sigma, mXm{1}.Sigma))
Daniel@0 68 end
Daniel@0 69
Daniel@0 70
Daniel@0 71 % Compute the correct posterior by building Xm -> Y
Daniel@0 72
Daniel@0 73 N = 2;
Daniel@0 74 dag = zeros(N,N);
Daniel@0 75 dag(1, 2)=1;
Daniel@0 76 ns = [psz selfsz];
Daniel@0 77 bnet = mk_bnet(dag, ns, 'discrete', [], 'observed', 2);
Daniel@0 78
Daniel@0 79 bnet.CPD{1} = gaussian_CPD(bnet, 1, 'mean', zeros(psz, 1), 'cov', eye(psz, psz));
Daniel@0 80 bnet.CPD{2} = gaussian_CPD(bnet, 2, 'mean', mu, 'cov', Sigma, 'weights', W);
Daniel@0 81
Daniel@0 82 jengine = jtree_inf_engine(bnet);
Daniel@0 83 evidence = {[], yval};
Daniel@0 84 jengine = enter_evidence(jengine, evidence); % apply Bayes rule to invert the arc
Daniel@0 85 mX = marginal_nodes(jengine, 1);
Daniel@0 86
Daniel@0 87 for e=1:length(engines)
Daniel@0 88 assert(approxeq(mX.mu, mXm{e}.mu))
Daniel@0 89 assert(approxeq(mX.Sigma, mXm{e}.Sigma))
Daniel@0 90 end