diff options
| author | ziejd2 | 2018-03-14 23:23:33 -0500 |
|---|---|---|
| committer | GitHub | 2018-03-14 23:23:33 -0500 |
| commit | 1ff6baa44e22b91eefb48aea6f3befa078c0489b (patch) | |
| tree | e0fd79d2e32fd2aedda2eadaed0f19af3514c520 /sourcecodes/bnt-master/BNT/potentials/@scgpot | |
| parent | 6882395afdadf4e982b25b5215071a0932730950 (diff) | |
| parent | c80226899f5cdd9f11c163817d59445213f5bef0 (diff) | |
| download | BNW-1ff6baa44e22b91eefb48aea6f3befa078c0489b.tar.gz | |
Merge pull request #1 from ziejd2/octave_php_separate
Octave php separate
Diffstat (limited to 'sourcecodes/bnt-master/BNT/potentials/@scgpot')
14 files changed, 746 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Entries b/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Entries new file mode 100644 index 00000000..c990d57d --- /dev/null +++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Entries @@ -0,0 +1,12 @@ +/README/1.1.1.1/Thu Mar 20 15:07:16 2003// +/combine_pots.m/1.1.1.1/Tue Mar 11 17:49:28 2003// +/complement_pot.m/1.1.1.1/Wed May 21 13:49:34 2003// +/direct_combine_pots.m/1.1.1.1/Sun May 19 22:11:08 2002// +/extension_pot.m/1.1.1.1/Fri Jan 24 12:52:34 2003// +/marginalize_pot.m/1.1.1.1/Tue Mar 11 17:06:08 2003// +/normalize_pot.m/1.1.1.1/Wed May 21 13:49:44 2003// +/pot_to_marginal.m/1.1.1.1/Sun May 19 22:11:08 2002// +/recursive_combine_pots.m/1.1.1.1/Wed May 21 13:49:48 2003// +/reduce_pot.m/1.1.1.1/Tue Mar 11 18:07:12 2003// +/scgpot.m/1.1.1.1/Tue Mar 11 14:04:48 2003// +D diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Repository b/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Repository new file mode 100644 index 00000000..ffef4774 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Repository @@ -0,0 +1 @@ +FullBNT/BNT/potentials/@scgpot diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Root b/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Root new file mode 100644 index 00000000..f3bd14a6 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Root @@ -0,0 +1 @@ +:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/README b/sourcecodes/bnt-master/BNT/potentials/@scgpot/README new file mode 100644 index 00000000..1a3c9d16 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/README @@ -0,0 +1,11 @@ +% Stable conditional Gaussian inference +% Written by Rainer Deventer + + +@techreport{Lauritzen99, + author = "S. Lauritzen and F. Jensen", + title = "Stable Local Computation with Conditional {G}aussian Distributions", + year = 1999, + number = "R-99-2014", + institution = "Dept. Math. Sciences, Aalborg Univ." +} diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/combine_pots.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/combine_pots.m new file mode 100644 index 00000000..2315176a --- /dev/null +++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/combine_pots.m @@ -0,0 +1,24 @@ +function pot = combine_pots(pot1, pot2) +% COMBINE_POTS combine two potentials +% pot = combine_pots(pot1, pot2) + +% Reduce both potentials before trying to combine them. +% Cf. "Stable Local computation with Conditional Gaussian Distributions", page 9 +% Consider again two potentials with minimal tail + +% Guarantee minimal tails. If pot1 or pot2 are minimal, they are not changed +pot1 = reduce_pot(pot1); +pot2 = reduce_pot(pot2); + +%if the intersect set of these two potentials' head conts. combination is undifined +if ~isempty( myintersect(pot1.cheaddom, pot2.cheaddom) ) + return; +end + +if isempty( myintersect(pot1.domain, pot2.cheaddom) ) | isempty( myintersect(pot2.domain, pot1.cheaddom)) + % if satisfy the condition of directed combine + pot = direct_combine_pots(pot1, pot2); +else + % perform recursive combine + pot = recursive_combine_pots(pot1, pot2); +end diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/complement_pot.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/complement_pot.m new file mode 100644 index 00000000..25f1c1c6 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/complement_pot.m @@ -0,0 +1,221 @@ +function [margpot, comppot] = complement_pot(pot, keep) +% COMPLEMENT_POT complement means decompose of a potential into its strong marginal and +% its complement corresponds exactly to the decomposition of a probability distribution +% into its marginal and conditional +% [margpot, comppot] = complement_pot(pot, keep) + +% keep can only include continuous head nodes and discrete nodes +% margpot is the stable CG potential of keep nodes +% comppot is the stable CG potential of others in corresponds exactly to +% the discomposition of a probability distribution of its marginal and conditional + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Calculation of the marginal requires integration over % +% all variables in csumover. Thus cheadkeep contains all % +% continuous variables in the marginal potential % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%keyboard; +csumover = mysetdiff(pot.cheaddom, keep); +cheadkeep = mysetdiff(pot.cheaddom, csumover); + +nodesizes = zeros(1, max(pot.domain)); +nodesizes(pot.ddom) = pot.dsizes; +nodesizes(pot.cheaddom) = pot.cheadsizes; +nodesizes(pot.ctaildom) = pot.ctailsizes; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Description of the variables in the marginal domain % +% For the calculation of a strong marginal first integration % +% over all continuous variables in the head takes place. % +% The calculation of the marginal over the head variables % +% might result in a smaller or empty tail % +% If there are no head variables, and therefore no tail % +% variables, left marginalisation over discrete variables % +% may take place % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +margdom = mysetdiff(pot.domain,keep); +% margddom = pot.ddom; +margcheaddom = cheadkeep; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Marginalisation over discrete variables is only allowed when % +% the tail is empty % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +margddom = myintersect(pot.ddom,keep); % Discrete domain of marginal +margctaildom = myintersect(pot.ctaildom,keep); % Tail domain +assert(isempty(mysetdiff(pot.ddom,margddom)) | isempty(margctaildom)) + + +%margctaildom = pot.ctaildom; +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Even if marginalisation over continuous variables is only defined % +% for head variables, the marginalisation over haed-variables might % +% result in a smaller tail % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +margctaildom = myintersect(pot.ctaildom,keep); + +margcheadsizes = nodesizes(margcheaddom); +margcheadsize = sum(margcheadsizes); +margctailsizes = nodesizes(margctaildom); +margctailsize = sum(margctailsizes); + +compdom = pot.domain; +compddom = pot.ddom; +compcheaddom = csumover; +compctaildom = myunion(pot.ctaildom, cheadkeep); +compcheadsizes = nodesizes(compcheaddom); +compcheadsize = sum(compcheadsizes); +compctailsizes = nodesizes(compctaildom); +compctailsize = sum(compctailsizes); + +dkeep = myintersect(pot.ddom, keep); +%if dom is only contain discrete node +if isempty(pot.cheaddom) + dsumover = mysetdiff(pot.ddom, dkeep); + + if isempty(dsumover) + margpot = pot; + comppot = scgpot([], [], [], []); + return; + end + + + I = prod(nodesizes(dkeep)); + J = prod(nodesizes(dsumover)); + sum_map = find_equiv_posns(dsumover, pot.ddom); + keep_map = find_equiv_posns(dkeep, pot.ddom); + iv = zeros(1, length(pot.ddom)); % index vector + p1 = zeros(I,J); + for i=1:I + keep_iv = ind2subv(nodesizes(dkeep), i); + iv(keep_map) = keep_iv; + for j=1:J + sum_iv = ind2subv(nodesizes(dsumover), j); + iv(sum_map) = sum_iv; + k = subv2ind(nodesizes(pot.ddom), iv); + potc = struct(pot.scgpotc{k}); % violate object privacy + p1(i,j) = potc.p; + end + end + p2 = sum(p1,2); + p2 = p2 + (p2==0)*eps; + + margscpot = cell(1, I); + compscpot = cell(1, I*J); + iv = zeros(1, length(pot.ddom)); % index vector + for i=1:I + margscpot{i} = scgcpot(0, 0, p2(i)); + keep_iv = ind2subv(nodesizes(dkeep), i); + iv(keep_map) = keep_iv; + for j=1:J + sum_iv = ind2subv(nodesizes(dsumover), j); + iv(sum_map) = sum_iv; + k = subv2ind(nodesizes(pot.ddom), iv); + q = p1(i,j)/p2(i); + compscpot{k} = scgcpot(0, 0, q); + end + end + + margpot = scgpot(dkeep, [], [], nodesizes, margscpot); + comppot = scgpot(pot.ddom, [], [], nodesizes,compscpot); + return; +end +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% head of the potential is not empty % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +dsize = pot.dsize; +compscpot = cell(1, dsize); + +fmaskh = find_equiv_posns(margcheaddom, compctaildom); +fmaskt = find_equiv_posns(margctaildom, compctaildom); + +fh = block(fmaskh, compctailsizes); +ft = block(fmaskt, compctailsizes); + + +if ~isempty(margcheaddom) + for i=1:dsize + potc = struct(pot.scgpotc{i}); + q = 1; + p = potc.p; + [A1, A2, B1, B2, C11, C12, C21, C22] = partition_matrix_vec_3(potc.A, potc.B, potc.C, margcheaddom, compcheaddom, nodesizes); + + if ~isempty(margcheaddom) + margscpot{i} = scgcpot(margcheadsize, margctailsize, p, A1, B1, C11); + else + margscpot{i} = scgcpot(margcheadsize, margctailsize, p); + end + + if ~isempty(compcheaddom) + if ~isempty(margcheaddom) + E = A2 - C21*pinv(C11)*A1; + tmp1 = C21*pinv(C11); + tmp2 = B2 - C21*pinv(C11)*B1; + F = zeros(compcheadsize, compctailsize); + F(:, fh) = tmp1; + F(:, ft) = tmp2; + G = C22 - C21*pinv(C11)*C12; + else + E = A2; + F = B2; + G = C22; + end + compscpot{i} = scgcpot(compcheadsize, compctailsize, q, E, F, G); + else + compscpot{i} = scgcpot(compcheadsize, 0, q); + end + if isempty(margcheaddom) + margpot = scgpot(margddom, [], [], nodesizes, margscpot); + else + margpot = scgpot(margddom, margcheaddom, margctaildom, nodesizes, margscpot); + end + end +else + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Marginalisation took place over all head variables. % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Calculate the strong marginal % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + margpot = marginalize_pot(pot,keep); + mPot = struct(margpot); + for i =1:dsize + potc = struct(pot.scgpotc{i}); + % Get the probability of the original potential % + q = potc.p; + + % Get the configuration defined by the index i% + config = ind2subv(pot.dsizes,i); + + % Calculate the corresponding configuration in the marginal potential + if isempty(margpot.dsizes) + % keep == [] + indMargPot = 1; + else + equivPos = find_equiv_posns(dkeep,pot.ddom); + indMargPot = subv2ind(margpot.dsizes,config(equivPos)); + end + % Figure out the corresponding marginal potential + mPotC = struct(mPot.scgpotc{indMargPot}); + p = mPotC.p; + if p == 0 + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % The following assignment is correct as p is only zero if q is also zero % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + compscpot{i} = scgcpot(compcheadsize,compctailsize,0,potc.A,potc.B,potc.C); + else + compscpot{i} = scgcpot(compcheadsize,compctailsize,q/p,potc.A,potc.B,potc.C); + end + end +end +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Put all components in one potential % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +if isempty(compcheaddom) + comppot = scgpot(compddom, [], [], nodesizes,compscpot); +else + comppot = scgpot(compddom, compcheaddom, compctaildom, nodesizes,compscpot); +end + + diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/direct_combine_pots.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/direct_combine_pots.m new file mode 100644 index 00000000..deeb002d --- /dev/null +++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/direct_combine_pots.m @@ -0,0 +1,161 @@ +function pot = direct_combine_pots(pot1, pot2) +% DIRECTED_COMBINE_POTS The combination operation corresponds to ordinary composition of conditional distributions. +% In some sense is similar to that of forming disjoint union of set. +% pot = direct_combine_pots(pot1, pot2) + +% directed combine can be performed under the conditon that the head node set of pot1 is disjoint from the domain of +% pot2 or vice versa. if the last conditon was satisfied we exchange the pot1 and pot2 firstly then perform the operation. +% If neither of them was satified the directed combine is undifined. + + +if isempty( myintersect(pot1.domain, pot2.cheaddom) ) + pot1 = pot1; + pot2 = pot2; +elseif isempty( myintersect(pot2.domain, pot1.cheaddom)) + temppot = pot1; + pot1 = pot2; + pot2 = temppot; +else + assert(0); + return; +end + +domain = myunion(pot1.domain, pot2.domain); +nodesizes = zeros(1,max(domain)); +nodesizes(pot2.ctaildom) = pot2.ctailsizes; +nodesizes(pot2.cheaddom) = pot2.cheadsizes; +nodesizes(pot2.ddom) = pot2.dsizes; +nodesizes(pot1.ctaildom) = pot1.ctailsizes; +nodesizes(pot1.cheaddom) = pot1.cheadsizes; +nodesizes(pot1.ddom) = pot1.dsizes; + +dom_u = mysetdiff(pot2.ctaildom, pot1.cheaddom); +if ~isempty(dom_u) & ~mysubset(dom_u, pot1.ctaildom) + pot1 = extension_pot(pot1, [], [], dom_u, nodesizes(dom_u)); +end + +dom_u = myunion(pot1.cheaddom, pot1.ctaildom); +if ~isempty(dom_u) & ~mysubset(dom_u, pot2.ctaildom) + pot2 = extension_pot(pot2, [], [], dom_u, nodesizes(dom_u)); +end + + +cheaddom = myunion(pot1.cheaddom, pot2.cheaddom); +ctaildom = mysetdiff(myunion(pot1.ctaildom, pot2.ctaildom), cheaddom); +cdom = myunion(cheaddom, ctaildom); +ddom = mysetdiff(domain, cdom); +dsizes = nodesizes(ddom); +dsize = prod(nodesizes(ddom)); +cheadsizes = nodesizes(cheaddom); +cheadsize = sum(nodesizes(cheaddom)); +ctailsizes = nodesizes(ctaildom); +ctailsize = sum(nodesizes(ctaildom)); + +r1 = pot1.cheadsize; +s1 = pot1.ctailsize; +scpot = cell(1, dsize); +mask1 = []; +mask2 = []; +if ~isempty(pot1.ddom) + mask1 = find_equiv_posns(pot1.ddom, ddom); +end +if ~isempty(pot2.ddom) + mask2 = find_equiv_posns(pot2.ddom, ddom); +end +cmask1 = []; +cmask2 = []; +if ~isempty(pot1.cheaddom) + cmask1 = find_equiv_posns(pot1.cheaddom, cheaddom); +end +if ~isempty(pot2.cheaddom) + cmask2 = find_equiv_posns(pot2.cheaddom, cheaddom); +end + +u1 = block(cmask1, cheadsizes); +u2 = block(cmask2, cheadsizes); + +fmaskh = find_equiv_posns(pot1.cheaddom, pot2.ctaildom); +fmaskt = find_equiv_posns(pot1.ctaildom, pot2.ctaildom); + +fh = block(fmaskh, pot2.ctailsizes); +ft = block(fmaskt, pot2.ctailsizes); + +for i=1:dsize + sub = ind2subv(dsizes, i); + sub1 = sub(mask1); + sub2 = sub(mask2); + ind1 = subv2ind(pot1.dsizes, sub1); + ind2 = subv2ind(pot2.dsizes, sub2); + + if isempty(ind1) + ind1 = 1; + end + if isempty(ind2) + ind2 = 1; + end + potc1 = struct(pot1.scgpotc{ind1}); + potc2 = struct(pot2.scgpotc{ind2}); + p = potc1.p; + q = potc2.p; + ro = p*q; + + A = potc1.A; + B = potc1.B; + C = potc1.C; + + E = potc2.A; + F = potc2.B; + G = potc2.C; + + F1 = F(:, fh); + F2 = F(:, ft); + + if ~isempty(F1) + K1 = F1*A; + K2 = F1*B; + FCF = F1*C*F1'; + FC = F1*C; + CFT = C*F1'; + else + K1 = zeros(size(E)); + K2 = zeros(size(F2)); + FCF = zeros(size(G)); + FC = zeros(size(C, 1), size(G, 2)); + CFT = zeros(size(G, 2), size(C, 1)); + end + + + U = zeros(cheadsize,1); + W = zeros(cheadsize,cheadsize); + V = zeros(cheadsize,ctailsize); + + if cheadsize > 0 + U(u1) = A; + U(u2) = E + K1; + W(u1, u1) = C; + W(u2, u2) = G + FCF; + W(u1, u2) = CFT; + W(u2, u1) = FC; + else + U = zeros(cheadsize,1); + W = zeros(cheadsize,cheadsize); + end + if cheadsize > 0 | ctailsize > 0 + if ~isempty(u1) + V(u1, :) = B; + else + V(u1, :) = zeros(potc1.cheadsize, ctailsize); + end + if ~isempty(u2) + V(u2, :) = F2 + K2; + else + V(u2, :) = zeros(potc2.cheadsize, ctailsize); + end + else + V = zeros(cheadsize,ctailsize); + end + + scpot{i} = scgcpot(cheadsize, ctailsize, ro, U, V, W); +end + +pot = scgpot(ddom, cheaddom, ctaildom, nodesizes, scpot); diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/extension_pot.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/extension_pot.m new file mode 100644 index 00000000..a4c2b0e6 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/extension_pot.m @@ -0,0 +1,55 @@ +function pot = extension_pot(oldpot, ddom_u, dsizes, ctaildom_u, csizes) +% EXTENSION_POT Extense a stable CG potential. +% pot = extension_pot(oldpot, ddom_u, ctaildom_u, dsizes, csizes) +% ddom_u Added discrete nodes +% ctaildom_u Added continuous tail nodes +% csizes is the size of the tail nodes. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% A CG potential can be extended by adding discrete variables to its % +% domain of continuous variables to its tail % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +ddom = myunion(oldpot.ddom, ddom_u); +ctaildom = myunion(oldpot.ctaildom, ctaildom_u); +cheaddom = oldpot.cheaddom; +udom = myunion(ddom_u, ctaildom_u); +domain = myunion(oldpot.domain, udom); + +ns = zeros(1,max(domain)); +ns(ddom_u) = dsizes; +ns(ctaildom_u) = csizes; +ns(oldpot.ddom) = oldpot.dsizes; +ns(oldpot.cheaddom) = oldpot.cheadsizes; +ns(oldpot.ctaildom) = oldpot.ctailsizes; + +dsizes = ns(ddom); +dsize = prod(ns(ddom)); +cheadsizes = ns(cheaddom); +cheadsize = sum(ns(cheaddom)); +ctailsizes = ns(ctaildom); +ctailsize = sum(ns(ctaildom)); + +BZ = zeros(cheadsize, ctailsize); +potarray = cell(1, dsize); +mask = find_equiv_posns(oldpot.ddom, ddom); + +tmask = find_equiv_posns(oldpot.ctaildom, ctaildom); +tu = block(tmask, ctailsizes); + +for i=1:dsize + sub1 = ind2subv(dsizes, i); + sub2 = sub1(mask); + ind = subv2ind(oldpot.dsizes, sub2); + if isempty(ind) + ind = 1; + end + potc = struct(oldpot.scgpotc{ind}); + p = potc.p; + B = BZ; + if ~isempty(B) + B(:, tu) = potc.B; + end + potarray{i} = scgcpot(cheadsize, ctailsize, p, potc.A, B, potc.C); +end + +pot = scgpot(ddom, cheaddom, ctaildom, ns,potarray); diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/marginalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/marginalize_pot.m new file mode 100644 index 00000000..317f9f10 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/marginalize_pot.m @@ -0,0 +1,92 @@ +function smallpot = marginalize_pot(bigpot, keep) +% MARGINALIZE_POT Marginalize a cgpot onto a smaller domain. +% smallpot = marginalize_pot(bigpot, keep) + +sumover = mysetdiff(bigpot.domain, keep); +cdom = myunion(bigpot.cheaddom, bigpot.ctaildom); +csumover = myintersect(sumover, bigpot.cheaddom); +dsumover = myintersect(sumover, bigpot.ddom); + +dkeep = myintersect(keep, bigpot.ddom); +ckeep = myintersect(keep, bigpot.cheaddom); +cheaddom = myintersect(keep, bigpot.cheaddom); + +assert(isempty(myintersect(csumover,bigpot.ctaildom))); +ns = zeros(1, max(bigpot.domain)); +ns(bigpot.ddom) = bigpot.dsizes; +ns(bigpot.cheaddom) = bigpot.cheadsizes; +ns(bigpot.ctaildom) = bigpot.ctailsizes; + + +if sum(ns(csumover)) > 0 + for i=1:bigpot.dsize + bigpot.scgpotc{i} = marginalize_pot(bigpot.scgpotc{i}, ckeep, csumover, ns); + end +end + +if (isequal(csumover, cheaddom)) + bigpot.ctaildom = []; +end +% If we are not marginalizing over any discrete nodes, we are done. +if prod(ns(dsumover))==1 + smallpot = scgpot(dkeep, cheaddom, bigpot.ctaildom, ns, bigpot.scgpotc); + return; +end + +if (~isempty(bigpot.ctaildom)) + assert(0); + return; +end + +I = prod(ns(dkeep)); +J = prod(ns(dsumover)); +C = sum(ns(ckeep)); +sum_map = find_equiv_posns(dsumover, bigpot.ddom); +keep_map = find_equiv_posns(dkeep, bigpot.ddom); +iv = zeros(1, length(bigpot.ddom)); % index vector + +p1 = zeros(I,J); +A1 = zeros(C,J,I); +C1 = zeros(C,C,J,I); +for i=1:I + keep_iv = ind2subv(ns(dkeep), i); + iv(keep_map) = keep_iv; + for j=1:J + sum_iv = ind2subv(ns(dsumover), j); + iv(sum_map) = sum_iv; + k = subv2ind(ns(bigpot.ddom), iv); + pot = struct(bigpot.scgpotc{k}); % violate object privacy + p1(i,j) = pot.p; + if C > 0 % so mu1 and Sigma1 are non-empty + A1(:,j,i) = pot.A; + C1(:,:,j,i) = pot.C; + end + end +end + +% Collapse the mixture of Gaussians +coef = mk_stochastic(p1); % coef must be convex combination +%keyboard +p2 = sum(p1,2); +if (all(p2 == 0)) + p2 = p2 + (p2==0)*eps; +end +A = []; +S = []; + +pot = cell(1,I); +ctailsize = sum(ns(bigpot.ctaildom)); +tB = zeros(C, ctailsize); +for i=1:I + if C > 0 + [A, S] = collapse_mog(A1(:,:,i), C1(:,:,:,i), coef(i,:)); + end + p = p2(i); + pot{i} = scgcpot(C, ctailsize, p, A, tB, S); +end + +smallpot = scgpot(dkeep, ckeep, bigpot.ctaildom, ns, pot); + + + + diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/normalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/normalize_pot.m new file mode 100644 index 00000000..da265ef5 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/normalize_pot.m @@ -0,0 +1,16 @@ +function [pot, loglik] = normalize_pot(pot) +% NORMALIZE_POT Convert the SCG potential Pr(X,E) into Pr(X|E) and return log Pr(E). +% [pot, loglik] = normalize_pot(pot) + +% Marginalize down to [], so that the normalizing constant becomes Pr(E) +temp = marginalize_pot(pot, []); +[temp2, loglik] = normalize_pot(temp.scgpotc{1}); + +% Adjust scale factor to reflect the fact that the pot now represents Pr(X | E) instead of Pr(X,E). + +scale = -loglik; +if 1 + for i=1:pot.dsize + pot.scgpotc{i} = rescale_pot( pot.scgpotc{i}, scale); + end +end diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/pot_to_marginal.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/pot_to_marginal.m new file mode 100644 index 00000000..f7478ef8 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/pot_to_marginal.m @@ -0,0 +1,29 @@ +function m = pot_to_marginal(pot) +% POT_TO_MARGINAL Convert a scgpot to a marginal structure. +% m = pot_to_marginal(pot) + +assert(isempty(pot.ctaildom)) +m.domain = pot.domain; +n = pot.cheadsize; +d = pot.dsize; + +if n==0 + m.mu = []; + m.Sigma = []; +else + m.mu = zeros(n, d); + m.Sigma = zeros(n, n, d); +end +%m.T = 0*myones(pot.dsizes); +m.T = 0*myones(pot.dsize); +for i=1:pot.dsize + potc = struct(pot.scgpotc{i}); % violate privacy of object + if n > 0 + m.mu(:,i) = potc.A; + m.Sigma(:,:,i) = potc.C; + end + m.T(i) = potc.p; +end +if isvectorBNT(m.T) + m.T = m.T(:)'; +end diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/recursive_combine_pots.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/recursive_combine_pots.m new file mode 100644 index 00000000..27c04b75 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/recursive_combine_pots.m @@ -0,0 +1,40 @@ +function pot = recursive_combine_pots(pot1, pot2) +% RECURSIVE_COMBINE_POTS recursive combine two potentials +% pot = recursive_combine_pots(pot1, pot2) + +pot1 = reduce_pot(pot1); +pot2 = reduce_pot(pot2); +% Recursion is stopped, if recusive-combination is defined by direct combination, +% i.e. if the domain of one potential is disjoint from the head of the other. +if (isempty(myintersect(pot1.domain,pot2.cheaddom))|... + isempty(myintersect(pot1.cheaddom,pot2.domain))) + pot = direct_combine_pots(pot1,pot2); +else + % Test wether one of the set-differences is not empty + % as defined in Lauritzen99 "Stable Local Computation with Conditional Gaussian Distributions" + % on page 9 + D12 = mysetdiff(pot1.cheaddom, pot2.domain); + D21 = mysetdiff(pot2.cheaddom, pot1.domain); + if (isempty(D12) & isempty(D21)) + assert(0,'Recursive combination is not defined'); + end + + if ~isempty(D12) + % Calculate the complementary potential for the set + % D1\D12 as defined in Lauritzen 99, page 9 + keep = mysetdiff(pot1.domain,D12); + [margpot, comppot] = complement_pot(pot1,keep); + margpot = reduce_pot(margpot); + comppot = reduce_pot(comppot); + pot = direct_combine_pots( recursive_combine_pots(margpot, pot2), comppot); + elseif ~isempty(D21) + keep = mysetdiff(pot2.domain,D21); + [margpot, comppot] = complement_pot(pot2,D21); + margpot = reduce_pot(margpot); + comppot = reduce_pot(comppot); + pot = direct_combine_pots( recursive_combine_pots(pot1, margpot), comppot); + end +end + + + diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/reduce_pot.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/reduce_pot.m new file mode 100644 index 00000000..7ee4ab49 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/reduce_pot.m @@ -0,0 +1,53 @@ +function [reduced_pot,successful] = reduce_pot(pot,tailnodes) +% Executes the reduce operation defined in +% Stable Local Computation with Conditional Gaussian Distributions +% Steffen L. Lauritzen +% Frank Jensen +% September 1999 +% The potential pot is reduced if B contains any zero columns +% The test are restricted to the positions in tailnodes. +% Any columns successfully deleted are entered in the array successful +if nargin < 2 + tailnodes = pot.ctaildom; +end + +successful = []; +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Keep track of remaining tailnodes % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +rem_tailnodes = pot.ctaildom; +for i = tailnodes + pos = find(i==rem_tailnodes); + successful_red = [pos]; + red_scgcpot = cell(1,pot.dsize); + j = 1; + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Test whether all components of pot.scgpotc can be reduced % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + while ((j <= pot.dsize) & ~isempty(successful_red)) + [cpot,successful_red] = reduce_pot(pot.scgpotc{j},pos); + red_scgcpot{j} = cpot; + j = j + 1; + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % If i is a reducible tailnode, then reduce the potential % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if ~isempty(successful_red) + successful = [successful i]; + pot.scgpotc = red_scgcpot; + rem_tailnodes = mysetdiff(rem_tailnodes,i); + end; +end + +pot.ctaildom = rem_tailnodes; +positions = find_equiv_posns(rem_tailnodes,pot.ctaildom); +pot.ctailsizes = pot.ctailsizes(positions); +pot.ctailsize = sum(pot.ctailsizes); +pot.domain = mysetdiff(pot.domain,successful); +reduced_pot = pot; + + + + + diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/scgpot.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/scgpot.m new file mode 100644 index 00000000..7f923f22 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/scgpot.m @@ -0,0 +1,30 @@ +function pot = scgpot(ddom, cheaddom, ctaildom, node_sizes, scgpotc) +% SCGPOT Make a stable CG potential. +% pot = scgpot(ddom, cheaddom, ctaildom, node_sizes, scgpotc) +% +% ddom is discrete nodes contains in the potential +% cheaddom is head nodes constains in the potential +% ctaildom is tail nodes contains in the potential +% node_sizes(i) is the size of the i'th node. +% scgpotc is list of scgcpot objects. + +pot.ddom = ddom; +pot.cheaddom = cheaddom; +pot.ctaildom = ctaildom; +pot.domain = myunion(ddom, myunion(cheaddom, ctaildom)); +pot.dsizes = node_sizes(pot.ddom); +pot.dsize = prod(node_sizes(pot.ddom)); +pot.cheadsizes = node_sizes(pot.cheaddom); +pot.cheadsize = sum(node_sizes(pot.cheaddom)); +pot.ctailsizes = node_sizes(pot.ctaildom); +pot.ctailsize = sum(node_sizes(pot.ctaildom)); + +if nargin < 5 + scgpotc = cell(1, pot.dsize); + for i=1:pot.dsize + scgpotc{i} = scgcpot(pot.cheadsize, pot.ctailsize); + end +end +pot.scgpotc = scgpotc; + +pot = class(pot, 'scgpot'); |
