Revision 8:b5b38998ef3b
| _FullBNT/BNT/@assocarray/CVS/Entries | ||
|---|---|---|
| 1 |
/assocarray.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 2 |
/subsref.m/1.1.1.1/Wed Aug 4 19:36:30 2004// |
|
| 3 |
D |
|
| _FullBNT/BNT/@assocarray/CVS/Repository | ||
|---|---|---|
| 1 |
FullBNT/BNT/@assocarray |
|
| _FullBNT/BNT/@assocarray/CVS/Root | ||
|---|---|---|
| 1 |
:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt |
|
| _FullBNT/BNT/@assocarray/assocarray.m | ||
|---|---|---|
| 1 |
function A = assocarray(keys, vals) |
|
| 2 |
% ASSOCARRAY Make an associative array |
|
| 3 |
% function A = assocarray(keys, vals) |
|
| 4 |
% |
|
| 5 |
% keys{i} is the i'th string, vals{i} is the i'th value.
|
|
| 6 |
% After construction, A('foo') will return the value associated with foo.
|
|
| 7 |
|
|
| 8 |
A.keys = keys; |
|
| 9 |
A.vals = vals; |
|
| 10 |
A = class(A, 'assocarray'); |
|
| _FullBNT/BNT/@assocarray/subsref.m | ||
|---|---|---|
| 1 |
function val = subsref(A, S) |
|
| 2 |
% SUBSREF Subscript reference for an associative array |
|
| 3 |
% A('foo') will return the value associated with foo.
|
|
| 4 |
% If there are multiple identicaly keys, the first match is returned. |
|
| 5 |
% Currently the search is sequential. |
|
| 6 |
|
|
| 7 |
i = 1; |
|
| 8 |
while i <= length(A.keys) |
|
| 9 |
if strcmp(S.subs{1}, A.keys{i})
|
|
| 10 |
val = A.vals{i};
|
|
| 11 |
return; |
|
| 12 |
end |
|
| 13 |
i = i + 1; |
|
| 14 |
end |
|
| 15 |
error(['can''t find ' S.subs{1}])
|
|
| _FullBNT/BNT/CPDs/@boolean_CPD/CVS/Entries | ||
|---|---|---|
| 1 |
/boolean_CPD.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 2 |
D |
|
| _FullBNT/BNT/CPDs/@boolean_CPD/CVS/Repository | ||
|---|---|---|
| 1 |
FullBNT/BNT/CPDs/@boolean_CPD |
|
| _FullBNT/BNT/CPDs/@boolean_CPD/CVS/Root | ||
|---|---|---|
| 1 |
:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt |
|
| _FullBNT/BNT/CPDs/@boolean_CPD/boolean_CPD.m | ||
|---|---|---|
| 1 |
function CPD = boolean_CPD(bnet, self, ftype, fname, pfail) |
|
| 2 |
% BOOLEAN_CPD Make a tabular CPD representing a (noisy) boolean function |
|
| 3 |
% |
|
| 4 |
% CPD = boolean_cpd(bnet, self, 'inline', f) uses the inline function f |
|
| 5 |
% to specify the CPT. |
|
| 6 |
% e.g., suppose X4 = X2 AND (NOT X3). Then we can write |
|
| 7 |
% bnet.CPD{4} = boolean_CPD(bnet, 4, 'inline', inline('(x(1) & ~x(2)'));
|
|
| 8 |
% Note that x(1) refers pvals(1) = X2, and x(2) refers to pvals(2)=X3. |
|
| 9 |
% |
|
| 10 |
% CPD = boolean_cpd(bnet, self, 'named', f) assumes f is a function name. |
|
| 11 |
% f can be built-in to matlab, or a file. |
|
| 12 |
% e.g., If X4 = X2 AND X3, we can write |
|
| 13 |
% bnet.CPD{4} = boolean_CPD(bnet, 4, 'named', 'and');
|
|
| 14 |
% e.g., If X4 = X2 OR X3, we can write |
|
| 15 |
% bnet.CPD{4} = boolean_CPD(bnet, 4, 'named', 'any');
|
|
| 16 |
% |
|
| 17 |
% CPD = boolean_cpd(bnet, self, 'rnd') makes a random non-redundant bool fn. |
|
| 18 |
% |
|
| 19 |
% CPD = boolean_CPD(bnet, self, 'inline'/'named', f, pfail) |
|
| 20 |
% will put probability mass 1-pfail on f(parents), and put pfail on the other value. |
|
| 21 |
% This is useful for simulating noisy boolean functions. |
|
| 22 |
% If pfail is omitted, it is set to 0. |
|
| 23 |
% (Note that adding noise to a random (non-redundant) boolean function just creates a different |
|
| 24 |
% (potentially redundant) random boolean function.) |
|
| 25 |
% |
|
| 26 |
% Note: This cannot be used to simulate a noisy-OR gate. |
|
| 27 |
% Example: suppose C has parents A and B, and the |
|
| 28 |
% link of A->C fails with prob pA and the link B->C fails with pB. |
|
| 29 |
% Then the noisy-OR gate defines the following distribution |
|
| 30 |
% |
|
| 31 |
% A B P(C=0) |
|
| 32 |
% 0 0 1.0 |
|
| 33 |
% 1 0 pA |
|
| 34 |
% 0 1 pB |
|
| 35 |
% 1 1 pA * PB |
|
| 36 |
% |
|
| 37 |
% By contrast, boolean_CPD(bnet, C, 'any', p) would define |
|
| 38 |
% |
|
| 39 |
% A B P(C=0) |
|
| 40 |
% 0 0 1-p |
|
| 41 |
% 1 0 p |
|
| 42 |
% 0 1 p |
|
| 43 |
% 1 1 p |
|
| 44 |
|
|
| 45 |
|
|
| 46 |
if nargin==0 |
|
| 47 |
% This occurs if we are trying to load an object from a file. |
|
| 48 |
CPD = tabular_CPD(bnet, self); |
|
| 49 |
return; |
|
| 50 |
elseif isa(bnet, 'boolean_CPD') |
|
| 51 |
% This might occur if we are copying an object. |
|
| 52 |
CPD = bnet; |
|
| 53 |
return; |
|
| 54 |
end |
|
| 55 |
|
|
| 56 |
if nargin < 5, pfail = 0; end |
|
| 57 |
|
|
| 58 |
ps = parents(bnet.dag, self); |
|
| 59 |
ns = bnet.node_sizes; |
|
| 60 |
psizes = ns(ps); |
|
| 61 |
self_size = ns(self); |
|
| 62 |
|
|
| 63 |
psucc = 1-pfail; |
|
| 64 |
|
|
| 65 |
k = length(ps); |
|
| 66 |
switch ftype |
|
| 67 |
case 'inline', f = eval_bool_fn(fname, k); |
|
| 68 |
case 'named', f = eval_bool_fn(fname, k); |
|
| 69 |
case 'rnd', f = mk_rnd_bool_fn(k); |
|
| 70 |
otherwise, error(['unknown function type ' ftype]); |
|
| 71 |
end |
|
| 72 |
|
|
| 73 |
CPT = zeros(prod(psizes), self_size); |
|
| 74 |
ndx = find(f==0); |
|
| 75 |
CPT(ndx, 1) = psucc; |
|
| 76 |
CPT(ndx, 2) = pfail; |
|
| 77 |
ndx = find(f==1); |
|
| 78 |
CPT(ndx, 2) = psucc; |
|
| 79 |
CPT(ndx, 1) = pfail; |
|
| 80 |
if k > 0 |
|
| 81 |
CPT = reshape(CPT, [psizes self_size]); |
|
| 82 |
end |
|
| 83 |
|
|
| 84 |
clamp = 1; |
|
| 85 |
CPD = tabular_CPD(bnet, self, CPT, [], clamp); |
|
| 86 |
|
|
| 87 |
|
|
| 88 |
|
|
| 89 |
%%%%%%%%%%%% |
|
| 90 |
|
|
| 91 |
function f = eval_bool_fn(fname, n) |
|
| 92 |
% EVAL_BOOL_FN Evaluate a boolean function on all bit vectors of length n |
|
| 93 |
% f = eval_bool_fn(fname, n) |
|
| 94 |
% |
|
| 95 |
% e.g. f = eval_bool_fn(inline('x(1) & x(3)'), 3)
|
|
| 96 |
% returns 0 0 0 0 0 1 0 1 |
|
| 97 |
|
|
| 98 |
ns = 2*ones(1, n); |
|
| 99 |
f = zeros(1, 2^n); |
|
| 100 |
bits = ind2subv(ns, 1:2^n); |
|
| 101 |
for i=1:2^n |
|
| 102 |
f(i) = feval(fname, bits(i,:)-1); |
|
| 103 |
end |
|
| 104 |
|
|
| 105 |
%%%%%%%%%%%%%%% |
|
| 106 |
|
|
| 107 |
function f = mk_rnd_bool_fn(n) |
|
| 108 |
% MK_RND_BOOL_FN Make a random bit vector of length n that encodes a non-redundant boolean function |
|
| 109 |
% f = mk_rnd_bool_fn(n) |
|
| 110 |
|
|
| 111 |
red = 1; |
|
| 112 |
while red |
|
| 113 |
f = sample_discrete([0.5 0.5], 2^n, 1)-1; |
|
| 114 |
red = redundant_bool_fn(f); |
|
| 115 |
end |
|
| 116 |
|
|
| 117 |
%%%%%%%% |
|
| 118 |
|
|
| 119 |
|
|
| 120 |
function red = redundant_bool_fn(f) |
|
| 121 |
% REDUNDANT_BOOL_FN Does a boolean function depend on all its input values? |
|
| 122 |
% r = redundant_bool_fn(f) |
|
| 123 |
% |
|
| 124 |
% f is a vector of length 2^n, representing the output for each bit vector. |
|
| 125 |
% An input is redundant if there is no assignment to the other bits |
|
| 126 |
% which changes the output e.g., input 1 is redundant if u(2:n) s.t., |
|
| 127 |
% f([0 u(2:n)]) <> f([1 u(2:n)]). |
|
| 128 |
% A function is redundant it it has any redundant inputs. |
|
| 129 |
|
|
| 130 |
n = log2(length(f)); |
|
| 131 |
ns = 2*ones(1,n); |
|
| 132 |
red = 0; |
|
| 133 |
for i=1:n |
|
| 134 |
ens = ns; |
|
| 135 |
ens(i) = 1; |
|
| 136 |
U = ind2subv(ens, 1:2^(n-1)); |
|
| 137 |
U(:,i) = 1; |
|
| 138 |
f1 = f(subv2ind(ns, U)); |
|
| 139 |
U(:,i) = 2; |
|
| 140 |
f2 = f(subv2ind(ns, U)); |
|
| 141 |
if isequal(f1, f2) |
|
| 142 |
red = 1; |
|
| 143 |
return; |
|
| 144 |
end |
|
| 145 |
end |
|
| 146 |
|
|
| 147 |
|
|
| 148 |
%%%%%%%%%% |
|
| 149 |
|
|
| 150 |
function [b, iter] = rnd_truth_table(N) |
|
| 151 |
% RND_TRUTH_TABLE Construct the output of a random truth table s.t. each input is non-redundant |
|
| 152 |
% b = rnd_truth_table(N) |
|
| 153 |
% |
|
| 154 |
% N is the number of inputs. |
|
| 155 |
% b is a random bit string of length N, representing the output of the truth table. |
|
| 156 |
% Non-redundant means that, for each input position k, |
|
| 157 |
% there are at least two bit patterns, u and v, that differ only in the k'th position, |
|
| 158 |
% s.t., f(u) ~= f(v), where f is the function represented by b. |
|
| 159 |
% We use rejection sampling to ensure non-redundancy. |
|
| 160 |
% |
|
| 161 |
% Example: b = [0 0 0 1 0 0 0 1] is indep of 3rd input (AND of inputs 1 and 2) |
|
| 162 |
|
|
| 163 |
bits = ind2subv(2*ones(1,N), 1:2^N)-1; |
|
| 164 |
redundant = 1; |
|
| 165 |
iter = 0; |
|
| 166 |
while redundant & (iter < 4) |
|
| 167 |
iter = iter + 1; |
|
| 168 |
b = sample_discrete([0.5 0.5], 1, 2^N)-1; |
|
| 169 |
redundant = 0; |
|
| 170 |
for i=1:N |
|
| 171 |
on = find(bits(:,i)==1); |
|
| 172 |
off = find(bits(:,i)==0); |
|
| 173 |
if isequal(b(on), b(off)) |
|
| 174 |
redundant = 1; |
|
| 175 |
break; |
|
| 176 |
end |
|
| 177 |
end |
|
| 178 |
end |
|
| 179 |
|
|
| _FullBNT/BNT/CPDs/@deterministic_CPD/CVS/Entries | ||
|---|---|---|
| 1 |
/deterministic_CPD.m/1.1.1.1/Mon Oct 7 13:26:36 2002// |
|
| 2 |
D |
|
| _FullBNT/BNT/CPDs/@deterministic_CPD/CVS/Repository | ||
|---|---|---|
| 1 |
FullBNT/BNT/CPDs/@deterministic_CPD |
|
| _FullBNT/BNT/CPDs/@deterministic_CPD/CVS/Root | ||
|---|---|---|
| 1 |
:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt |
|
| _FullBNT/BNT/CPDs/@deterministic_CPD/deterministic_CPD.m | ||
|---|---|---|
| 1 |
function CPD = deterministic_CPD(bnet, self, fname, pfail) |
|
| 2 |
% DETERMINISTIC_CPD Make a tabular CPD representing a (noisy) deterministic function |
|
| 3 |
% |
|
| 4 |
% CPD = deterministic_CPD(bnet, self, fname) |
|
| 5 |
% This calls feval(fname, pvals) for each possible vector of parent values. |
|
| 6 |
% e.g., suppose there are 2 ternary parents, then pvals = |
|
| 7 |
% [1 1], [2 1], [3 1], [1 2], [2 2], [3 2], [1 3], [2 3], [3 3] |
|
| 8 |
% If v = feval(fname, pvals(i)), then |
|
| 9 |
% CPD(x | parents=pvals(i)) = 1 if x==v, and = 0 if x<>v |
|
| 10 |
% e.g., suppose X4 = X2 AND (NOT X3). Then |
|
| 11 |
% bnet.CPD{4} = deterministic_CPD(bnet, 4, inline('((x(1)-1) & ~(x(2)-1)) + 1'));
|
|
| 12 |
% Note that x(1) refers pvals(1) = X2, and x(2) refers to pvals(2)=X3 |
|
| 13 |
% See also boolean_CPD. |
|
| 14 |
% |
|
| 15 |
% CPD = deterministic_CPD(bnet, self, fname, pfail) |
|
| 16 |
% will put probability mass 1-pfail on f(parents), and distribute pfail over the other values. |
|
| 17 |
% This is useful for simulating noisy deterministic functions. |
|
| 18 |
% If pfail is omitted, it is set to 0. |
|
| 19 |
% |
|
| 20 |
|
|
| 21 |
|
|
| 22 |
if nargin==0 |
|
| 23 |
% This occurs if we are trying to load an object from a file. |
|
| 24 |
CPD = tabular_CPD(bnet, self); |
|
| 25 |
return; |
|
| 26 |
elseif isa(bnet, 'deterministic_CPD') |
|
| 27 |
% This might occur if we are copying an object. |
|
| 28 |
CPD = bnet; |
|
| 29 |
return; |
|
| 30 |
end |
|
| 31 |
|
|
| 32 |
if nargin < 4, pfail = 0; end |
|
| 33 |
|
|
| 34 |
ps = parents(bnet.dag, self); |
|
| 35 |
ns = bnet.node_sizes; |
|
| 36 |
psizes = ns(ps); |
|
| 37 |
self_size = ns(self); |
|
| 38 |
|
|
| 39 |
psucc = 1-pfail; |
|
| 40 |
|
|
| 41 |
CPT = zeros(prod(psizes), self_size); |
|
| 42 |
pvals = zeros(1, length(ps)); |
|
| 43 |
for i=1:prod(psizes) |
|
| 44 |
pvals = ind2subv(psizes, i); |
|
| 45 |
x = feval(fname, pvals); |
|
| 46 |
%fprintf('%d ', [pvals x]); fprintf('\n');
|
|
| 47 |
if psucc == 1 |
|
| 48 |
CPT(i, x) = 1; |
|
| 49 |
else |
|
| 50 |
CPT(i, x) = psucc; |
|
| 51 |
rest = mysetdiff(1:self_size, x); |
|
| 52 |
CPT(i, rest) = pfail/length(rest); |
|
| 53 |
end |
|
| 54 |
end |
|
| 55 |
CPT = reshape(CPT, [psizes self_size]); |
|
| 56 |
|
|
| 57 |
CPD = tabular_CPD(bnet, self, 'CPT',CPT, 'clamped',1); |
|
| 58 |
|
|
| 59 |
|
|
| _FullBNT/BNT/CPDs/@discrete_CPD/CPD_to_lambda_msg.m | ||
|---|---|---|
| 1 |
function lam_msg = CPD_to_lambda_msg(CPD, msg_type, n, ps, msg, p, evidence) |
|
| 2 |
% CPD_TO_LAMBDA_MSG Compute lambda message (discrete) |
|
| 3 |
% lam_msg = compute_lambda_msg(CPD, msg_type, n, ps, msg, p, evidence) |
|
| 4 |
% Pearl p183 eq 4.52 |
|
| 5 |
|
|
| 6 |
switch msg_type |
|
| 7 |
case 'd', |
|
| 8 |
T = prod_CPT_and_pi_msgs(CPD, n, ps, msg, p); |
|
| 9 |
mysize = length(msg{n}.lambda);
|
|
| 10 |
lambda = dpot(n, mysize, msg{n}.lambda);
|
|
| 11 |
T = multiply_by_pot(T, lambda); |
|
| 12 |
lam_msg = pot_to_marginal(marginalize_pot(T, p)); |
|
| 13 |
lam_msg = lam_msg.T; |
|
| 14 |
case 'g', |
|
| 15 |
error('discrete_CPD can''t create Gaussian msgs')
|
|
| 16 |
end |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/CPD_to_pi.m | ||
|---|---|---|
| 1 |
function pi = CPD_to_pi(CPD, msg_type, n, ps, msg, evidence) |
|
| 2 |
% COMPUTE_PI Compute pi vector (discrete) |
|
| 3 |
% pi = compute_pi(CPD, msg_type, n, ps, msg, evidence) |
|
| 4 |
% Pearl p183 eq 4.51 |
|
| 5 |
|
|
| 6 |
switch msg_type |
|
| 7 |
case 'd', |
|
| 8 |
T = prod_CPT_and_pi_msgs(CPD, n, ps, msg); |
|
| 9 |
pi = pot_to_marginal(marginalize_pot(T, n)); |
|
| 10 |
pi = pi.T(:); |
|
| 11 |
case 'g', |
|
| 12 |
error('can only convert discrete CPD to Gaussian pi if observed')
|
|
| 13 |
end |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/CPD_to_scgpot.m | ||
|---|---|---|
| 1 |
function pot = CPD_to_scgpot(CPD, domain, ns, cnodes, evidence) |
|
| 2 |
% CPD_TO_SCGPOT Convert a CPD to a CG potential, incorporating any evidence (discrete) |
|
| 3 |
% pot = CPD_to_scgpot(CPD, domain, ns, cnodes, evidence) |
|
| 4 |
% |
|
| 5 |
% domain is the domain of CPD. |
|
| 6 |
% node_sizes(i) is the size of node i. |
|
| 7 |
% cnodes |
|
| 8 |
% evidence{i} is the evidence on the i'th node.
|
|
| 9 |
|
|
| 10 |
%odom = domain(~isemptycell(evidence(domain))); |
|
| 11 |
|
|
| 12 |
%vals = cat(1, evidence{odom});
|
|
| 13 |
%map = find_equiv_posns(odom, domain); |
|
| 14 |
%index = mk_multi_index(length(domain), map, vals); |
|
| 15 |
CPT = CPD_to_CPT(CPD); |
|
| 16 |
%CPT = CPT(index{:});
|
|
| 17 |
CPT = CPT(:); |
|
| 18 |
%ns(odom) = 1; |
|
| 19 |
potarray = cell(1, length(CPT)); |
|
| 20 |
for i=1:length(CPT) |
|
| 21 |
%p = CPT(i); |
|
| 22 |
potarray{i} = scgcpot(0, 0, CPT(i));
|
|
| 23 |
%scpot{i} = scpot(0, 0);
|
|
| 24 |
end |
|
| 25 |
pot = scgpot(domain, [], [], ns, potarray); |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/CVS/Entries | ||
|---|---|---|
| 1 |
/CPD_to_lambda_msg.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 2 |
/CPD_to_pi.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 3 |
/CPD_to_scgpot.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 4 |
/README/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 5 |
/convert_CPD_to_table_hidden_ps.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 6 |
/convert_obs_CPD_to_table.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 7 |
/convert_to_pot.m/1.1.1.1/Fri Feb 20 22:00:38 2004// |
|
| 8 |
/convert_to_sparse_table.c/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 9 |
/convert_to_table.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 10 |
/discrete_CPD.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 11 |
/dom_sizes.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 12 |
/log_prob_node.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 13 |
/prob_node.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 14 |
/sample_node.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 15 |
D |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/CVS/Entries.Log | ||
|---|---|---|
| 1 |
A D/Old//// |
|
| 2 |
A D/private//// |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/CVS/Repository | ||
|---|---|---|
| 1 |
FullBNT/BNT/CPDs/@discrete_CPD |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/CVS/Root | ||
|---|---|---|
| 1 |
:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/Old/CVS/Entries | ||
|---|---|---|
| 1 |
/convert_to_pot.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 2 |
/convert_to_table.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 3 |
/prob_CPD.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 4 |
/prob_node.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 5 |
D |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/Old/CVS/Repository | ||
|---|---|---|
| 1 |
FullBNT/BNT/CPDs/@discrete_CPD/Old |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/Old/CVS/Root | ||
|---|---|---|
| 1 |
:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/Old/convert_to_pot.m | ||
|---|---|---|
| 1 |
function pot = convert_to_pot(CPD, pot_type, domain, evidence) |
|
| 2 |
% CONVERT_TO_POT Convert a tabular CPD to one or more potentials |
|
| 3 |
% pots = convert_to_pot(CPD, pot_type, domain, evidence) |
|
| 4 |
% |
|
| 5 |
% pots{i} = CPD evaluated using evidence(domain(:,i))
|
|
| 6 |
% If 'domains' is a single row vector, pots will be an object, not a cell array. |
|
| 7 |
|
|
| 8 |
ncases = size(domain,2); |
|
| 9 |
assert(ncases==1); % not yet vectorized |
|
| 10 |
|
|
| 11 |
sz = dom_sizes(CPD); |
|
| 12 |
ns = zeros(1, max(domain)); |
|
| 13 |
ns(domain) = sz; |
|
| 14 |
|
|
| 15 |
local_ev = evidence(domain); |
|
| 16 |
obs_bitv = ~isemptycell(local_ev); |
|
| 17 |
odom = domain(obs_bitv); |
|
| 18 |
T = convert_to_table(CPD, domain, local_ev, obs_bitv); |
|
| 19 |
|
|
| 20 |
switch pot_type |
|
| 21 |
case 'u', |
|
| 22 |
pot = upot(domain, sz, T, 0*myones(sz)); |
|
| 23 |
case 'd', |
|
| 24 |
ns(odom) = 1; |
|
| 25 |
pot = dpot(domain, ns(domain), T); |
|
| 26 |
case {'c','g'},
|
|
| 27 |
% Since we want the output to be a Gaussian, the whole family must be observed. |
|
| 28 |
% In other words, the potential is really just a constant. |
|
| 29 |
p = T; |
|
| 30 |
%p = prob_node(CPD, evidence(domain(end)), evidence(domain(1:end-1))); |
|
| 31 |
ns(domain) = 0; |
|
| 32 |
pot = cpot(domain, ns(domain), log(p)); |
|
| 33 |
case 'cg', |
|
| 34 |
T = T(:); |
|
| 35 |
ns(odom) = 1; |
|
| 36 |
can = cell(1, length(T)); |
|
| 37 |
for i=1:length(T) |
|
| 38 |
can{i} = cpot([], [], log(T(i)));
|
|
| 39 |
end |
|
| 40 |
pot = cgpot(domain, [], ns, can); |
|
| 41 |
otherwise, |
|
| 42 |
error(['unrecognized pot type ' pot_type]) |
|
| 43 |
end |
|
| 44 |
|
|
| _FullBNT/BNT/CPDs/@discrete_CPD/Old/convert_to_table.m | ||
|---|---|---|
| 1 |
function T = convert_to_table(CPD, domain, local_ev, obs_bitv) |
|
| 2 |
% CONVERT_TO_TABLE Convert a discrete CPD to a table |
|
| 3 |
% function T = convert_to_table(CPD, domain, local_ev, obs_bitv) |
|
| 4 |
% |
|
| 5 |
% We convert the CPD to a CPT, and then lookup the evidence on the discrete parents. |
|
| 6 |
% The resulting table can easily be converted to a potential. |
|
| 7 |
|
|
| 8 |
|
|
| 9 |
CPT = CPD_to_CPT(CPD); |
|
| 10 |
obs_child_only = ~any(obs_bitv(1:end-1)) & obs_bitv(end); |
|
| 11 |
|
|
| 12 |
if obs_child_only |
|
| 13 |
sz = size(CPT); |
|
| 14 |
CPT = reshape(CPT, prod(sz(1:end-1)), sz(end)); |
|
| 15 |
o = local_ev{end};
|
|
| 16 |
T = CPT(:, o); |
|
| 17 |
else |
|
| 18 |
odom = domain(obs_bitv); |
|
| 19 |
vals = cat(1, local_ev{find(obs_bitv)}); % undo cell array
|
|
| 20 |
map = find_equiv_posns(odom, domain); |
|
| 21 |
index = mk_multi_index(length(domain), map, vals); |
|
| 22 |
T = CPT(index{:});
|
|
| 23 |
end |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/Old/prob_CPD.m | ||
|---|---|---|
| 1 |
function p = prob_CPD(CPD, domain, ns, cnodes, evidence) |
|
| 2 |
% PROB_CPD Compute prob of a node given evidence on the parents (discrete) |
|
| 3 |
% p = prob_CPD(CPD, domain, ns, cnodes, evidence) |
|
| 4 |
% |
|
| 5 |
% domain is the domain of CPD. |
|
| 6 |
% node_sizes(i) is the size of node i. |
|
| 7 |
% cnodes = all the cts nodes |
|
| 8 |
% evidence{i} is the evidence on the i'th node.
|
|
| 9 |
|
|
| 10 |
ps = domain(1:end-1); |
|
| 11 |
self = domain(end); |
|
| 12 |
CPT = CPD_to_CPT(CPD); |
|
| 13 |
|
|
| 14 |
if isempty(ps) |
|
| 15 |
T = CPT; |
|
| 16 |
else |
|
| 17 |
assert(~any(isemptycell(evidence(ps)))); |
|
| 18 |
pvals = cat(1, evidence{ps});
|
|
| 19 |
i = subv2ind(ns(ps), pvals(:)'); |
|
| 20 |
T = reshape(CPT, [prod(ns(ps)) ns(self)]); |
|
| 21 |
T = T(i,:); |
|
| 22 |
end |
|
| 23 |
p = T(evidence{self});
|
|
| 24 |
|
|
| 25 |
|
|
| _FullBNT/BNT/CPDs/@discrete_CPD/Old/prob_node.m | ||
|---|---|---|
| 1 |
function [P, p] = prob_node(CPD, self_ev, pev) |
|
| 2 |
% PROB_NODE Compute prod_m P(x(i,m)| x(pi_i,m), theta_i) for node i (discrete) |
|
| 3 |
% [P, p] = prob_node(CPD, self_ev, pev) |
|
| 4 |
% |
|
| 5 |
% self_ev(m) is the evidence on this node in case m. |
|
| 6 |
% pev(i,m) is the evidence on the i'th parent in case m (if there are any parents). |
|
| 7 |
% (These may also be cell arrays.) |
|
| 8 |
% |
|
| 9 |
% p(m) = P(x(i,m)| x(pi_i,m), theta_i) |
|
| 10 |
% P = prod p(m) |
|
| 11 |
|
|
| 12 |
if iscell(self_ev), usecell = 1; else usecell = 0; end |
|
| 13 |
|
|
| 14 |
ncases = length(self_ev); |
|
| 15 |
sz = dom_sizes(CPD); |
|
| 16 |
|
|
| 17 |
nparents = length(sz)-1; |
|
| 18 |
if nparents == 0 |
|
| 19 |
assert(isempty(pev)); |
|
| 20 |
else |
|
| 21 |
assert(isequal(size(pev), [nparents ncases])); |
|
| 22 |
end |
|
| 23 |
|
|
| 24 |
n = length(sz); |
|
| 25 |
dom = 1:n; |
|
| 26 |
p = zeros(1, ncases); |
|
| 27 |
if nparents == 0 |
|
| 28 |
for m=1:ncases |
|
| 29 |
if usecell |
|
| 30 |
evidence = {self_ev{m}};
|
|
| 31 |
else |
|
| 32 |
evidence = num2cell(self_ev(m)); |
|
| 33 |
end |
|
| 34 |
T = convert_to_table(CPD, dom, evidence); |
|
| 35 |
p(m) = T; |
|
| 36 |
end |
|
| 37 |
else |
|
| 38 |
for m=1:ncases |
|
| 39 |
if usecell |
|
| 40 |
evidence = cell(1,n); |
|
| 41 |
evidence(1:n-1) = pev(:,m); |
|
| 42 |
evidence(n) = self_ev(m); |
|
| 43 |
else |
|
| 44 |
evidence = num2cell([pev(:,m)', self_ev(m)]); |
|
| 45 |
end |
|
| 46 |
T = convert_to_table(CPD, dom, evidence); |
|
| 47 |
p(m) = T; |
|
| 48 |
end |
|
| 49 |
end |
|
| 50 |
P = prod(p); |
|
| 51 |
|
|
| _FullBNT/BNT/CPDs/@discrete_CPD/README | ||
|---|---|---|
| 1 |
Any CPD on a discrete child with discrete parents |
|
| 2 |
can be represented as a table (although this might be quite big). |
|
| 3 |
discrete_CPD uses this tabular representation to implement various |
|
| 4 |
functions. Subtypes are free to implement more efficient versions. |
|
| 5 |
|
|
| _FullBNT/BNT/CPDs/@discrete_CPD/convert_CPD_to_table_hidden_ps.m | ||
|---|---|---|
| 1 |
function T = convert_CPD_to_table_hidden_ps(CPD, child_obs) |
|
| 2 |
% CONVERT_CPD_TO_TABLE_HIDDEN_PS Convert a discrete CPD to a table |
|
| 3 |
% T = convert_CPD_to_table_hidden_ps(CPD, child_obs) |
|
| 4 |
% |
|
| 5 |
% This is like convert_to_table, except that we are guaranteed that |
|
| 6 |
% none of the parents have evidence on them. |
|
| 7 |
% child_obs may be an integer (1,2,...) or []. |
|
| 8 |
|
|
| 9 |
CPT = CPD_to_CPT(CPD); |
|
| 10 |
if isempty(child_obs) |
|
| 11 |
T = CPT(:); |
|
| 12 |
else |
|
| 13 |
sz = dom_sizes(CPD); |
|
| 14 |
if length(sz)==1 % no parents |
|
| 15 |
T = CPT(child_obs); |
|
| 16 |
else |
|
| 17 |
CPT = reshape(CPT, prod(sz(1:end-1)), sz(end)); |
|
| 18 |
T = CPT(:, child_obs); |
|
| 19 |
end |
|
| 20 |
end |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/convert_obs_CPD_to_table.m | ||
|---|---|---|
| 1 |
function T = convert_to_table(CPD, domain, evidence) |
|
| 2 |
% CONVERT_TO_TABLE Convert a discrete CPD to a table |
|
| 3 |
% T = convert_to_table(CPD, domain, evidence) |
|
| 4 |
% |
|
| 5 |
% We convert the CPD to a CPT, and then lookup the evidence on the discrete parents. |
|
| 6 |
% The resulting table can easily be converted to a potential. |
|
| 7 |
|
|
| 8 |
CPT = CPD_to_CPT(CPD); |
|
| 9 |
odom = domain(~isemptycell(evidence(domain))); |
|
| 10 |
vals = cat(1, evidence{odom});
|
|
| 11 |
map = find_equiv_posns(odom, domain); |
|
| 12 |
index = mk_multi_index(length(domain), map, vals); |
|
| 13 |
T = CPT(index{:});
|
|
| _FullBNT/BNT/CPDs/@discrete_CPD/convert_to_pot.m | ||
|---|---|---|
| 1 |
function pot = convert_to_pot(CPD, pot_type, domain, evidence) |
|
| 2 |
% CONVERT_TO_POT Convert a discrete CPD to a potential |
|
| 3 |
% pot = convert_to_pot(CPD, pot_type, domain, evidence) |
|
| 4 |
% |
|
| 5 |
% pots = CPD evaluated using evidence(domain) |
|
| 6 |
|
|
| 7 |
ncases = size(domain,2); |
|
| 8 |
assert(ncases==1); % not yet vectorized |
|
| 9 |
|
|
| 10 |
sz = dom_sizes(CPD); |
|
| 11 |
ns = zeros(1, max(domain)); |
|
| 12 |
ns(domain) = sz; |
|
| 13 |
|
|
| 14 |
CPT1 = CPD_to_CPT(CPD); |
|
| 15 |
spar = issparse(CPT1); |
|
| 16 |
odom = domain(~isemptycell(evidence(domain))); |
|
| 17 |
if spar |
|
| 18 |
T = convert_to_sparse_table(CPD, domain, evidence); |
|
| 19 |
else |
|
| 20 |
T = convert_to_table(CPD, domain, evidence); |
|
| 21 |
end |
|
| 22 |
|
|
| 23 |
switch pot_type |
|
| 24 |
case 'u', |
|
| 25 |
pot = upot(domain, sz, T, 0*myones(sz)); |
|
| 26 |
case 'd', |
|
| 27 |
ns(odom) = 1; |
|
| 28 |
pot = dpot(domain, ns(domain), T); |
|
| 29 |
case {'c','g'},
|
|
| 30 |
% Since we want the output to be a Gaussian, the whole family must be observed. |
|
| 31 |
% In other words, the potential is really just a constant. |
|
| 32 |
p = T; |
|
| 33 |
%p = prob_node(CPD, evidence(domain(end)), evidence(domain(1:end-1))); |
|
| 34 |
ns(domain) = 0; |
|
| 35 |
pot = cpot(domain, ns(domain), log(p)); |
|
| 36 |
|
|
| 37 |
case 'cg', |
|
| 38 |
T = T(:); |
|
| 39 |
ns(odom) = 1; |
|
| 40 |
can = cell(1, length(T)); |
|
| 41 |
for i=1:length(T) |
|
| 42 |
if T(i) == 0 |
|
| 43 |
can{i} = cpot([], [], -Inf); % bug fix by Bob Welch 20/2/04
|
|
| 44 |
else |
|
| 45 |
can{i} = cpot([], [], log(T(i)));
|
|
| 46 |
end; |
|
| 47 |
end |
|
| 48 |
pot = cgpot(domain, [], ns, can); |
|
| 49 |
|
|
| 50 |
case 'scg' |
|
| 51 |
T = T(:); |
|
| 52 |
ns(odom) = 1; |
|
| 53 |
pot_array = cell(1, length(T)); |
|
| 54 |
for i=1:length(T) |
|
| 55 |
pot_array{i} = scgcpot([], [], T(i));
|
|
| 56 |
end |
|
| 57 |
pot = scgpot(domain, [], [], ns, pot_array); |
|
| 58 |
|
|
| 59 |
otherwise, |
|
| 60 |
error(['unrecognized pot type ' pot_type]) |
|
| 61 |
end |
|
| 62 |
|
|
| _FullBNT/BNT/CPDs/@discrete_CPD/convert_to_sparse_table.c | ||
|---|---|---|
| 1 |
/* convert_to_sparse_table.c convert a sparse discrete CPD with evidence into sparse table */ |
|
| 2 |
/* convert_to_pot.m located in ../CPDs/discrete_CPD call it */ |
|
| 3 |
/* 3 input */ |
|
| 4 |
/* CPD prhs[0] with 1D sparse CPT */ |
|
| 5 |
/* domain prhs[1] */ |
|
| 6 |
/* evidence prhs[2] */ |
|
| 7 |
/* 1 output */ |
|
| 8 |
/* T plhs[0] sparse table */ |
|
| 9 |
|
|
| 10 |
#include <math.h> |
|
| 11 |
#include "mex.h" |
|
| 12 |
|
|
| 13 |
void ind_subv(int index, const int *cumprod, const int n, int *bsubv){
|
|
| 14 |
int i; |
|
| 15 |
|
|
| 16 |
for (i = n-1; i >= 0; i--) {
|
|
| 17 |
bsubv[i] = ((int)floor(index / cumprod[i])); |
|
| 18 |
index = index % cumprod[i]; |
|
| 19 |
} |
|
| 20 |
} |
|
| 21 |
|
|
| 22 |
int subv_ind(const int n, const int *cumprod, const int *subv){
|
|
| 23 |
int i, index=0; |
|
| 24 |
|
|
| 25 |
for(i=0; i<n; i++){
|
|
| 26 |
index += subv[i] * cumprod[i]; |
|
| 27 |
} |
|
| 28 |
return index; |
|
| 29 |
} |
|
| 30 |
|
|
| 31 |
void reset_nzmax(mxArray *spArray, const int old_nzmax, const int new_nzmax){
|
|
| 32 |
double *ptr; |
|
| 33 |
void *newptr; |
|
| 34 |
int *ir, *jc; |
|
| 35 |
int nbytes; |
|
| 36 |
|
|
| 37 |
if(new_nzmax == old_nzmax) return; |
|
| 38 |
nbytes = new_nzmax * sizeof(*ptr); |
|
| 39 |
ptr = mxGetPr(spArray); |
|
| 40 |
newptr = mxRealloc(ptr, nbytes); |
|
| 41 |
mxSetPr(spArray, newptr); |
|
| 42 |
nbytes = new_nzmax * sizeof(*ir); |
|
| 43 |
ir = mxGetIr(spArray); |
|
| 44 |
newptr = mxRealloc(ir, nbytes); |
|
| 45 |
mxSetIr(spArray, newptr); |
|
| 46 |
jc = mxGetJc(spArray); |
|
| 47 |
jc[0] = 0; |
|
| 48 |
jc[1] = new_nzmax; |
|
| 49 |
mxSetNzmax(spArray, new_nzmax); |
|
| 50 |
} |
|
| 51 |
|
|
| 52 |
|
|
| 53 |
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
|
|
| 54 |
int i, j, NS, NZB, count, bdim, match, domain, bindex, sindex, nzCounts=0; |
|
| 55 |
int *observed, *bsubv, *ssubv, *bir, *sir, *bjc, *sjc, *mask, *ssize, *bcumprod, *scumprod; |
|
| 56 |
double *pDomain, *pSize, *bpr, *spr; |
|
| 57 |
mxArray *pTemp; |
|
| 58 |
|
|
| 59 |
pTemp = mxGetField(prhs[0], 0, "CPT"); |
|
| 60 |
bpr = mxGetPr(pTemp); |
|
| 61 |
bir = mxGetIr(pTemp); |
|
| 62 |
bjc = mxGetJc(pTemp); |
|
| 63 |
NZB = bjc[1]; |
|
| 64 |
pTemp = mxGetField(prhs[0], 0, "sizes"); |
|
| 65 |
pSize = mxGetPr(pTemp); |
|
| 66 |
|
|
| 67 |
pDomain = mxGetPr(prhs[1]); |
|
| 68 |
bdim = mxGetNumberOfElements(prhs[1]); |
|
| 69 |
|
|
| 70 |
mask = malloc(bdim * sizeof(int)); |
|
| 71 |
ssize = malloc(bdim * sizeof(int)); |
|
| 72 |
observed = malloc(bdim * sizeof(int)); |
|
| 73 |
|
|
| 74 |
for(i=0; i<bdim; i++){
|
|
| 75 |
ssize[i] = (int)pSize[i]; |
|
| 76 |
} |
|
| 77 |
|
|
| 78 |
count = 0; |
|
| 79 |
for(i=0; i<bdim; i++){
|
|
| 80 |
domain = (int)pDomain[i] - 1; |
|
| 81 |
pTemp = mxGetCell(prhs[2], domain); |
|
| 82 |
if(pTemp){
|
|
| 83 |
mask[count] = i; |
|
| 84 |
ssize[i] = 1; |
|
| 85 |
observed[count] = (int)mxGetScalar(pTemp) - 1; |
|
| 86 |
count++; |
|
| 87 |
} |
|
| 88 |
} |
|
| 89 |
|
|
| 90 |
if(count == 0){
|
|
| 91 |
pTemp = mxGetField(prhs[0], 0, "CPT"); |
|
| 92 |
plhs[0] = mxDuplicateArray(pTemp); |
|
| 93 |
free(mask); |
|
| 94 |
free(ssize); |
|
| 95 |
free(observed); |
|
| 96 |
return; |
|
| 97 |
} |
|
| 98 |
|
|
| 99 |
bsubv = malloc(bdim * sizeof(int)); |
|
| 100 |
ssubv = malloc(count * sizeof(int)); |
|
| 101 |
bcumprod = malloc(bdim * sizeof(int)); |
|
| 102 |
scumprod = malloc(bdim * sizeof(int)); |
|
| 103 |
|
|
| 104 |
NS = 1; |
|
| 105 |
for(i=0; i<bdim; i++){
|
|
| 106 |
NS *= ssize[i]; |
|
| 107 |
} |
|
| 108 |
|
|
| 109 |
plhs[0] = mxCreateSparse(NS, 1, NS, mxREAL); |
|
| 110 |
spr = mxGetPr(plhs[0]); |
|
| 111 |
sir = mxGetIr(plhs[0]); |
|
| 112 |
sjc = mxGetJc(plhs[0]); |
|
| 113 |
sjc[0] = 0; |
|
| 114 |
sjc[1] = NS; |
|
| 115 |
|
|
| 116 |
bcumprod[0] = 1; |
|
| 117 |
scumprod[0] = 1; |
|
| 118 |
for(i=0; i<bdim-1; i++){
|
|
| 119 |
bcumprod[i+1] = bcumprod[i] * (int)pSize[i]; |
|
| 120 |
scumprod[i+1] = scumprod[i] * ssize[i]; |
|
| 121 |
} |
|
| 122 |
|
|
| 123 |
nzCounts = 0; |
|
| 124 |
for(i=0; i<NZB; i++){
|
|
| 125 |
bindex = bir[i]; |
|
| 126 |
ind_subv(bindex, bcumprod, bdim, bsubv); |
|
| 127 |
for(j=0; j<count; j++){
|
|
| 128 |
ssubv[j] = bsubv[mask[j]]; |
|
| 129 |
} |
|
| 130 |
match = 1; |
|
| 131 |
for(j=0; j<count; j++){
|
|
| 132 |
if((ssubv[j]) != observed[j]){
|
|
| 133 |
match = 0; |
|
| 134 |
break; |
|
| 135 |
} |
|
| 136 |
} |
|
| 137 |
if(match){
|
|
| 138 |
spr[nzCounts] = bpr[i]; |
|
| 139 |
sindex = subv_ind(bdim, scumprod, bsubv); |
|
| 140 |
sir[nzCounts] = sindex; |
|
| 141 |
nzCounts++; |
|
| 142 |
} |
|
| 143 |
} |
|
| 144 |
|
|
| 145 |
reset_nzmax(plhs[0], NS, nzCounts); |
|
| 146 |
free(mask); |
|
| 147 |
free(ssize); |
|
| 148 |
free(observed); |
|
| 149 |
free(bsubv); |
|
| 150 |
free(ssubv); |
|
| 151 |
free(bcumprod); |
|
| 152 |
free(scumprod); |
|
| 153 |
} |
|
| 154 |
|
|
| _FullBNT/BNT/CPDs/@discrete_CPD/convert_to_table.m | ||
|---|---|---|
| 1 |
function T = convert_to_table(CPD, domain, evidence) |
|
| 2 |
% CONVERT_TO_TABLE Convert a discrete CPD to a table |
|
| 3 |
% T = convert_to_table(CPD, domain, evidence) |
|
| 4 |
% |
|
| 5 |
% We convert the CPD to a CPT, and then lookup the evidence on the discrete parents. |
|
| 6 |
% The resulting table can easily be converted to a potential. |
|
| 7 |
|
|
| 8 |
domain = domain(:); |
|
| 9 |
CPT = CPD_to_CPT(CPD); |
|
| 10 |
odom = domain(~isemptycell(evidence(domain))); |
|
| 11 |
vals = cat(1, evidence{odom});
|
|
| 12 |
map = find_equiv_posns(odom, domain); |
|
| 13 |
index = mk_multi_index(length(domain), map, vals); |
|
| 14 |
T = CPT(index{:});
|
|
| 15 |
T = T(:); |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/discrete_CPD.m | ||
|---|---|---|
| 1 |
function CPD = discrete_CPD(clamped, dom_sizes) |
|
| 2 |
% DISCRETE_CPD Virtual constructor for generic discrete CPD |
|
| 3 |
% CPD = discrete_CPD(clamped, dom_sizes) |
|
| 4 |
|
|
| 5 |
CPD.dom_sizes = dom_sizes; |
|
| 6 |
CPD = class(CPD, 'discrete_CPD', generic_CPD(clamped)); |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/dom_sizes.m | ||
|---|---|---|
| 1 |
function sz = dom_sizes(CPD) |
|
| 2 |
% DOM_SIZES Return the size of each node in the domain |
|
| 3 |
% sz = dom_sizes(CPD) |
|
| 4 |
|
|
| 5 |
sz = CPD.dom_sizes; |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/log_prob_node.m | ||
|---|---|---|
| 1 |
function L = log_prob_node(CPD, self_ev, pev) |
|
| 2 |
% LOG_PROB_NODE Compute sum_m log P(x(i,m)| x(pi_i,m), theta_i) for node i (discrete) |
|
| 3 |
% L = log_prob_node(CPD, self_ev, pev) |
|
| 4 |
% |
|
| 5 |
% self_ev(m) is the evidence on this node in case m. |
|
| 6 |
% pev(i,m) is the evidence on the i'th parent in case m (if there are any parents). |
|
| 7 |
% (These may also be cell arrays.) |
|
| 8 |
|
|
| 9 |
[P, p] = prob_node(CPD, self_ev, pev); % P may underflow, so we use p |
|
| 10 |
tiny = exp(-700); |
|
| 11 |
p = p + (p==0)*tiny; % replace 0s by tiny |
|
| 12 |
L = sum(log(p)); |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/private/CVS/Entries | ||
|---|---|---|
| 1 |
/prod_CPT_and_pi_msgs.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 2 |
D |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/private/CVS/Repository | ||
|---|---|---|
| 1 |
FullBNT/BNT/CPDs/@discrete_CPD/private |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/private/CVS/Root | ||
|---|---|---|
| 1 |
:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/private/prod_CPT_and_pi_msgs.m | ||
|---|---|---|
| 1 |
function T = prod_CPT_and_pi_msgs(CPD, n, ps, msgs, except) |
|
| 2 |
% PROD_CPT_AND_PI_MSGS Multiply the CPD and all the pi messages from parents, perhaps excepting one |
|
| 3 |
% T = prod_CPY_and_pi_msgs(CPD, n, ps, msgs, except) |
|
| 4 |
|
|
| 5 |
if nargin < 5, except = -1; end |
|
| 6 |
|
|
| 7 |
dom = [ps n]; |
|
| 8 |
%ns = sparse(1, max(dom)); |
|
| 9 |
ns = zeros(1, max(dom)); |
|
| 10 |
CPT = CPD_to_CPT(CPD); |
|
| 11 |
ns(dom) = mysize(CPT); |
|
| 12 |
T = dpot(dom, ns(dom), CPT); |
|
| 13 |
for i=1:length(ps) |
|
| 14 |
p = ps(i); |
|
| 15 |
if p ~= except |
|
| 16 |
T = multiply_by_pot(T, dpot(p, ns(p), msgs{n}.pi_from_parent{i}));
|
|
| 17 |
end |
|
| 18 |
end |
|
| _FullBNT/BNT/CPDs/@discrete_CPD/prob_node.m | ||
|---|---|---|
| 1 |
function [P, p] = prob_node(CPD, self_ev, pev) |
|
| 2 |
% PROB_NODE Compute prod_m P(x(i,m)| x(pi_i,m), theta_i) for node i (discrete) |
|
| 3 |
% [P, p] = prob_node(CPD, self_ev, pev) |
|
| 4 |
% |
|
| 5 |
% self_ev(m) is the evidence on this node in case m. |
|
| 6 |
% pev(i,m) is the evidence on the i'th parent in case m (if there are any parents). |
|
| 7 |
% (These may also be cell arrays.) |
|
| 8 |
% |
|
| 9 |
% p(m) = P(x(i,m)| x(pi_i,m), theta_i) |
|
| 10 |
% P = prod p(m) |
|
| 11 |
|
|
| 12 |
if iscell(self_ev), usecell = 1; else usecell = 0; end |
|
| 13 |
|
|
| 14 |
ncases = length(self_ev); |
|
| 15 |
sz = dom_sizes(CPD); |
|
| 16 |
|
|
| 17 |
nparents = length(sz)-1; |
|
| 18 |
if nparents == 0 |
|
| 19 |
assert(isempty(pev)); |
|
| 20 |
else |
|
| 21 |
assert(isequal(size(pev), [nparents ncases])); |
|
| 22 |
end |
|
| 23 |
|
|
| 24 |
n = length(sz); |
|
| 25 |
dom = 1:n; |
|
| 26 |
p = zeros(1, ncases); |
|
| 27 |
if isa(CPD, 'tabular_CPD') |
|
| 28 |
% speed up by looking up CPT using index Zhang Yimin 2001-12-31 |
|
| 29 |
if usecell |
|
| 30 |
if nparents == 0 |
|
| 31 |
data = [cell2num(self_ev)]; |
|
| 32 |
else |
|
| 33 |
data = [cell2num(pev); cell2num(self_ev)]; |
|
| 34 |
end |
|
| 35 |
else |
|
| 36 |
if nparents == 0 |
|
| 37 |
data = [self_ev]; |
|
| 38 |
else |
|
| 39 |
data = [pev; self_ev]; |
|
| 40 |
end |
|
| 41 |
end |
|
| 42 |
|
|
| 43 |
indices = subv2ind(sz, data'); % each row of data' is a case |
|
| 44 |
|
|
| 45 |
CPT=CPD_to_CPT(CPD); |
|
| 46 |
p = CPT(indices); |
|
| 47 |
|
|
| 48 |
%get the prob list |
|
| 49 |
%cpt_size = prod(sz); |
|
| 50 |
%prob_list=reshape(CPT, cpt_size, 1); |
|
| 51 |
%for m=1:ncases %here we assume we get evidence for node and all its parents |
|
| 52 |
% idx=indices(m); |
|
| 53 |
% p(m)=prob_list(idx); |
|
| 54 |
%end |
|
| 55 |
|
|
| 56 |
else % eg. softmax |
|
| 57 |
|
|
| 58 |
for m=1:ncases |
|
| 59 |
if usecell |
|
| 60 |
if nparents == 0 |
|
| 61 |
evidence = {self_ev{m}};
|
|
| 62 |
else |
|
| 63 |
evidence = cell(1,n); |
|
| 64 |
evidence(1:n-1) = pev(:,m); |
|
| 65 |
evidence(n) = self_ev(m); |
|
| 66 |
end |
|
| 67 |
else |
|
| 68 |
if nparents == 0 |
|
| 69 |
evidence = num2cell(self_ev(m)); |
|
| 70 |
else |
|
| 71 |
evidence = num2cell([pev(:,m)', self_ev(m)]); |
|
| 72 |
end |
|
| 73 |
end |
|
| 74 |
T = convert_to_table(CPD, dom, evidence); |
|
| 75 |
p(m) = T; |
|
| 76 |
end |
|
| 77 |
end |
|
| 78 |
|
|
| 79 |
P = prod(p); |
|
| 80 |
|
|
| 81 |
|
|
| _FullBNT/BNT/CPDs/@discrete_CPD/sample_node.m | ||
|---|---|---|
| 1 |
function y = sample_node(CPD, pvals) |
|
| 2 |
% SAMPLE_NODE Draw a random sample from P(Xi | x(pi_i), theta_i) (discrete) |
|
| 3 |
% y = sample_node(CPD, parent_evidence) |
|
| 4 |
% |
|
| 5 |
% parent_evidence{i} is the value of the i'th parent
|
|
| 6 |
|
|
| 7 |
if 0 |
|
| 8 |
n = length(pvals)+1; |
|
| 9 |
dom = 1:n; |
|
| 10 |
evidence = cell(1,n); |
|
| 11 |
evidence(1:n-1) = pvals; |
|
| 12 |
T = convert_to_table(CPD, dom, evidence); |
|
| 13 |
y = sample_discrete(T); |
|
| 14 |
end |
|
| 15 |
|
|
| 16 |
|
|
| 17 |
CPT = CPD_to_CPT(CPD); |
|
| 18 |
sz = mysize(CPT); |
|
| 19 |
nparents = length(sz)-1; |
|
| 20 |
switch nparents |
|
| 21 |
case 0, T = CPT; |
|
| 22 |
case 1, T = CPT(pvals{1}, :);
|
|
| 23 |
case 2, T = CPT(pvals{1}, pvals{2}, :);
|
|
| 24 |
case 3, T = CPT(pvals{1}, pvals{2}, pvals{3}, :);
|
|
| 25 |
case 4, T = CPT(pvals{1}, pvals{2}, pvals{3}, pvals{4}, :);
|
|
| 26 |
otherwise, |
|
| 27 |
pvals = cat(1, pvals{:});
|
|
| 28 |
psz = sz(1:end-1); |
|
| 29 |
ssz = sz(end); |
|
| 30 |
i = subv2ind(psz, pvals(:)'); |
|
| 31 |
T = reshape(CPT, [prod(psz) ssz]); |
|
| 32 |
T = T(i,:); |
|
| 33 |
end |
|
| 34 |
y = sample_discrete(T); |
|
| _FullBNT/BNT/CPDs/@gaussian_CPD/CPD_to_lambda_msg.m | ||
|---|---|---|
| 1 |
function lam_msg = CPD_to_lambda_msg(CPD, msg_type, n, ps, msg, p, evidence) |
|
| 2 |
% CPD_TO_LAMBDA_MSG Compute lambda message (gaussian) |
|
| 3 |
% lam_msg = compute_lambda_msg(CPD, msg_type, n, ps, msg, p, evidence) |
|
| 4 |
% Pearl p183 eq 4.52 |
|
| 5 |
|
|
| 6 |
switch msg_type |
|
| 7 |
case 'd', |
|
| 8 |
error('gaussian_CPD can''t create discrete msgs')
|
|
| 9 |
case 'g', |
|
| 10 |
cps = ps(CPD.cps); |
|
| 11 |
cpsizes = CPD.sizes(CPD.cps); |
|
| 12 |
self_size = CPD.sizes(end); |
|
| 13 |
i = find_equiv_posns(p, cps); % p is n's i'th cts parent |
|
| 14 |
psz = cpsizes(i); |
|
| 15 |
if all(msg{n}.lambda.precision == 0) % no info to send on
|
|
| 16 |
lam_msg.precision = zeros(psz, psz); |
|
| 17 |
lam_msg.info_state = zeros(psz, 1); |
|
| 18 |
return; |
|
| 19 |
end |
|
| 20 |
[m, Q, W] = gaussian_CPD_params_given_dps(CPD, [ps n], evidence); |
|
| 21 |
Bmu = m; |
|
| 22 |
BSigma = Q; |
|
| 23 |
for k=1:length(cps) % only get pi msgs from cts parents |
|
| 24 |
pk = cps(k); |
|
| 25 |
if pk ~= p |
|
| 26 |
%bk = block(k, cpsizes); |
|
| 27 |
bk = CPD.cps_block_ndx{k};
|
|
| 28 |
Bk = W(:, bk); |
|
| 29 |
m = msg{n}.pi_from_parent{k};
|
|
| 30 |
BSigma = BSigma + Bk * m.Sigma * Bk'; |
|
| 31 |
Bmu = Bmu + Bk * m.mu; |
|
| 32 |
end |
|
| 33 |
end |
|
| 34 |
% BSigma = Q + sum_{k \neq i} B_k Sigma_k B_k'
|
|
| 35 |
%bi = block(i, cpsizes); |
|
| 36 |
bi = CPD.cps_block_ndx{i};
|
|
| 37 |
Bi = W(:,bi); |
|
| 38 |
P = msg{n}.lambda.precision;
|
|
| 39 |
if (rcond(P) > 1e-3) | isinf(P) |
|
| 40 |
if isinf(P) % Y is observed |
|
| 41 |
Sigma_lambda = zeros(self_size, self_size); % infinite precision => 0 variance |
|
| 42 |
mu_lambda = msg{n}.lambda.mu; % observed_value;
|
|
| 43 |
else |
|
| 44 |
Sigma_lambda = inv(P); |
|
| 45 |
mu_lambda = Sigma_lambda * msg{n}.lambda.info_state;
|
|
| 46 |
end |
|
| 47 |
C = inv(Sigma_lambda + BSigma); |
|
| 48 |
lam_msg.precision = Bi' * C * Bi; |
|
| 49 |
lam_msg.info_state = Bi' * C * (mu_lambda - Bmu); |
|
| 50 |
else |
|
| 51 |
% method that uses matrix inversion lemma to avoid inverting P |
|
| 52 |
A = inv(P + inv(BSigma)); |
|
| 53 |
C = P - P*A*P; |
|
| 54 |
lam_msg.precision = Bi' * C * Bi; |
|
| 55 |
D = eye(self_size) - P*A; |
|
| 56 |
z = msg{n}.lambda.info_state;
|
|
| 57 |
lam_msg.info_state = Bi' * (D*z - D*P*Bmu); |
|
| 58 |
end |
|
| 59 |
end |
|
| _FullBNT/BNT/CPDs/@gaussian_CPD/CPD_to_pi.m | ||
|---|---|---|
| 1 |
function pi = CPD_to_pi(CPD, msg_type, n, ps, msg, evidence) |
|
| 2 |
% CPD_TO_PI Compute the pi vector (gaussian) |
|
| 3 |
% function pi = CPD_to_pi(CPD, msg_type, n, ps, msg, evidence) |
|
| 4 |
|
|
| 5 |
switch msg_type |
|
| 6 |
case 'd', |
|
| 7 |
error('gaussian_CPD can''t create discrete msgs')
|
|
| 8 |
case 'g', |
|
| 9 |
[m, Q, W] = gaussian_CPD_params_given_dps(CPD, [ps n], evidence); |
|
| 10 |
cps = ps(CPD.cps); |
|
| 11 |
cpsizes = CPD.sizes(CPD.cps); |
|
| 12 |
pi.mu = m; |
|
| 13 |
pi.Sigma = Q; |
|
| 14 |
for k=1:length(cps) % only get pi msgs from cts parents |
|
| 15 |
%bk = block(k, cpsizes); |
|
| 16 |
bk = CPD.cps_block_ndx{k};
|
|
| 17 |
Bk = W(:, bk); |
|
| 18 |
m = msg{n}.pi_from_parent{k};
|
|
| 19 |
pi.Sigma = pi.Sigma + Bk * m.Sigma * Bk'; |
|
| 20 |
pi.mu = pi.mu + Bk * m.mu; % m.mu = u(k) |
|
| 21 |
end |
|
| 22 |
end |
|
| _FullBNT/BNT/CPDs/@gaussian_CPD/CPD_to_scgpot.m | ||
|---|---|---|
| 1 |
function pot = CPD_to_scgpot(CPD, domain, ns, cnodes, evidence) |
|
| 2 |
% CPD_TO_CGPOT Convert a Gaussian CPD to a CG potential, incorporating any evidence |
|
| 3 |
% pot = CPD_to_cgpot(CPD, domain, ns, cnodes, evidence) |
|
| 4 |
|
|
| 5 |
self = CPD.self; |
|
| 6 |
dnodes = mysetdiff(1:length(ns), cnodes); |
|
| 7 |
odom = domain(~isemptycell(evidence(domain))); |
|
| 8 |
cdom = myintersect(cnodes, domain); |
|
| 9 |
cheaddom = myintersect(self, domain); |
|
| 10 |
ctaildom = mysetdiff(cdom,cheaddom); |
|
| 11 |
ddom = myintersect(dnodes, domain); |
|
| 12 |
cobs = myintersect(cdom, odom); |
|
| 13 |
dobs = myintersect(ddom, odom); |
|
| 14 |
ens = ns; % effective node size |
|
| 15 |
ens(cobs) = 0; |
|
| 16 |
ens(dobs) = 1; |
|
| 17 |
|
|
| 18 |
% Extract the params compatible with the observations (if any) on the discrete parents (if any) |
|
| 19 |
% parents are all but the last domain element |
|
| 20 |
ps = domain(1:end-1); |
|
| 21 |
dps = myintersect(ps, ddom); |
|
| 22 |
dops = myintersect(dps, odom); |
|
| 23 |
|
|
| 24 |
map = find_equiv_posns(dops, dps); |
|
| 25 |
dpvals = cat(1, evidence{dops});
|
|
| 26 |
index = mk_multi_index(length(dps), map, dpvals); |
|
| 27 |
|
|
| 28 |
dpsize = prod(ens(dps)); |
|
| 29 |
cpsize = size(CPD.weights(:,:,1), 2); % cts parents size |
|
| 30 |
ss = size(CPD.mean, 1); % self size |
|
| 31 |
% the reshape acts like a squeeze |
|
| 32 |
m = reshape(CPD.mean(:, index{:}), [ss dpsize]);
|
|
| 33 |
C = reshape(CPD.cov(:, :, index{:}), [ss ss dpsize]);
|
|
| 34 |
W = reshape(CPD.weights(:, :, index{:}), [ss cpsize dpsize]);
|
|
| 35 |
|
|
| 36 |
|
|
| 37 |
% Convert each conditional Gaussian to a canonical potential |
|
| 38 |
pot = cell(1, dpsize); |
|
| 39 |
for i=1:dpsize |
|
| 40 |
%pot{i} = linear_gaussian_to_scgcpot(m(:,i), C(:,:,i), W(:,:,i), cdom, ns, cnodes, evidence);
|
|
| 41 |
pot{i} = scgcpot(ss, cpsize, 1, m(:,i), W(:,:,i), C(:,:,i));
|
|
| 42 |
end |
|
| 43 |
|
|
| 44 |
pot = scgpot(ddom, cheaddom, ctaildom, ens, pot); |
|
| 45 |
|
|
| 46 |
|
|
| 47 |
function pot = linear_gaussian_to_scgcpot(mu, Sigma, W, domain, ns, cnodes, evidence) |
|
| 48 |
% LINEAR_GAUSSIAN_TO_CPOT Convert a linear Gaussian CPD to a stable conditional potential element. |
|
| 49 |
% pot = linear_gaussian_to_cpot(mu, Sigma, W, domain, ns, cnodes, evidence) |
|
| 50 |
|
|
| 51 |
p = 1; |
|
| 52 |
A = mu; |
|
| 53 |
B = W; |
|
| 54 |
C = Sigma; |
|
| 55 |
ns(odom) = 0; |
|
| 56 |
%pot = scgcpot(, ns(domain), p, A, B, C); |
|
| 57 |
|
|
| 58 |
|
|
| _FullBNT/BNT/CPDs/@gaussian_CPD/CVS/Entries | ||
|---|---|---|
| 1 |
/CPD_to_lambda_msg.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 2 |
/CPD_to_pi.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 3 |
/CPD_to_scgpot.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 4 |
/adjustable_CPD.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 5 |
/convert_CPD_to_table_hidden_ps.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 6 |
/convert_to_pot.m/1.1.1.1/Sun Mar 9 23:03:16 2003// |
|
| 7 |
/convert_to_table.m/1.1.1.1/Sun May 11 23:31:54 2003// |
|
| 8 |
/display.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 9 |
/gaussian_CPD.m/1.1.1.1/Wed Jun 15 21:13:06 2005// |
|
| 10 |
/gaussian_CPD_params_given_dps.m/1.1.1.1/Sun May 11 23:13:40 2003// |
|
| 11 |
/get_field.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 12 |
/learn_params.m/1.1.1.1/Thu Jun 10 01:28:10 2004// |
|
| 13 |
/log_prob_node.m/1.1.1.1/Tue Sep 10 17:44:00 2002// |
|
| 14 |
/maximize_params.m/1.1.1.1/Tue May 20 14:10:06 2003// |
|
| 15 |
/maximize_params_debug.m/1.1.1.1/Fri Jan 31 00:13:10 2003// |
|
| 16 |
/reset_ess.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 17 |
/sample_node.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 18 |
/set_fields.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 19 |
/update_ess.m/1.1.1.1/Tue Jul 22 22:55:46 2003// |
|
| 20 |
D |
|
| _FullBNT/BNT/CPDs/@gaussian_CPD/CVS/Entries.Log | ||
|---|---|---|
| 1 |
A D/Old//// |
|
| 2 |
A D/private//// |
|
| _FullBNT/BNT/CPDs/@gaussian_CPD/CVS/Repository | ||
|---|---|---|
| 1 |
FullBNT/BNT/CPDs/@gaussian_CPD |
|
| _FullBNT/BNT/CPDs/@gaussian_CPD/CVS/Root | ||
|---|---|---|
| 1 |
:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt |
|
| _FullBNT/BNT/CPDs/@gaussian_CPD/Old/CPD_to_lambda_msg.m | ||
|---|---|---|
| 1 |
function lam_msg = CPD_to_lambda_msg(CPD, msg_type, n, ps, msg, p) |
|
| 2 |
% CPD_TO_LAMBDA_MSG Compute lambda message (gaussian) |
|
| 3 |
% lam_msg = compute_lambda_msg(CPD, msg_type, n, ps, msg, p) |
|
| 4 |
% Pearl p183 eq 4.52 |
|
| 5 |
|
|
| 6 |
switch msg_type |
|
| 7 |
case 'd', |
|
| 8 |
error('gaussian_CPD can''t create discrete msgs')
|
|
| 9 |
case 'g', |
|
| 10 |
self_size = CPD.sizes(end); |
|
| 11 |
if all(msg{n}.lambda.precision == 0) % no info to send on
|
|
| 12 |
lam_msg.precision = zeros(self_size); |
|
| 13 |
lam_msg.info_state = zeros(self_size, 1); |
|
| 14 |
return; |
|
| 15 |
end |
|
| 16 |
cpsizes = CPD.sizes(CPD.cps); |
|
| 17 |
dpval = 1; |
|
| 18 |
Q = CPD.cov(:,:,dpval); |
|
| 19 |
Sigmai = Q; |
|
| 20 |
wmu = zeros(self_size, 1); |
|
| 21 |
for k=1:length(ps) |
|
| 22 |
pk = ps(k); |
|
| 23 |
if pk ~= p |
|
| 24 |
bk = block(k, cpsizes); |
|
| 25 |
Bk = CPD.weights(:, bk, dpval); |
|
| 26 |
m = msg{n}.pi_from_parent{k};
|
|
| 27 |
Sigmai = Sigmai + Bk * m.Sigma * Bk'; |
|
| 28 |
wmu = wmu + Bk * m.mu; % m.mu = u(k) |
|
| 29 |
end |
|
| 30 |
end |
|
| 31 |
% Sigmai = Q + sum_{k \neq i} B_k Sigma_k B_k'
|
|
| 32 |
i = find_equiv_posns(p, ps); |
|
| 33 |
bi = block(i, cpsizes); |
|
| 34 |
Bi = CPD.weights(:,bi, dpval); |
|
| 35 |
|
|
| 36 |
if 0 |
|
| 37 |
P = msg{n}.lambda.precision;
|
|
| 38 |
if isinf(P) % inv(P)=Sigma_lambda=0 |
|
| 39 |
precision_temp = inv(Sigmai); |
|
| 40 |
lam_msg.precision = Bi' * precision_temp * Bi; |
|
| 41 |
lam_msg.info_state = precision_temp * (msg{n}.lambda.mu - wmu);
|
|
| 42 |
else |
|
| 43 |
A = inv(P + inv(Sigmai)); |
|
| 44 |
precision_temp = P + P*A*P; |
|
| 45 |
lam_msg.precision = Bi' * precision_temp * Bi; |
|
| 46 |
self_size = length(P); |
|
| 47 |
C = eye(self_size) + P*A; |
|
| 48 |
z = msg{n}.lambda.info_state;
|
|
| 49 |
lam_msg.info_state = C*z - C*P*wmu; |
|
| 50 |
end |
|
| 51 |
end |
|
| 52 |
|
|
| 53 |
if isinf(msg{n}.lambda.precision)
|
|
| 54 |
Sigma_lambda = zeros(self_size, self_size); % infinite precision => 0 variance |
|
| 55 |
mu_lambda = msg{n}.lambda.mu; % observed_value;
|
|
| 56 |
else |
|
| 57 |
Sigma_lambda = inv(msg{n}.lambda.precision);
|
|
| 58 |
mu_lambda = Sigma_lambda * msg{n}.lambda.info_state;
|
|
| 59 |
end |
|
| 60 |
precision_temp = inv(Sigma_lambda + Sigmai); |
|
| 61 |
lam_msg.precision = Bi' * precision_temp * Bi; |
|
| 62 |
lam_msg.info_state = Bi' * precision_temp * (mu_lambda - wmu); |
|
| 63 |
end |
|
| 64 |
|
|
| _FullBNT/BNT/CPDs/@gaussian_CPD/Old/CVS/Entries | ||
|---|---|---|
| 1 |
/CPD_to_lambda_msg.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 2 |
/gaussian_CPD.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 3 |
/log_prob_node.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 4 |
/maximize_params.m/1.1.1.1/Thu Jan 30 22:38:16 2003// |
|
| 5 |
/update_ess.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 6 |
/update_tied_ess.m/1.1.1.1/Wed May 29 15:59:52 2002// |
|
| 7 |
D |
|
| _FullBNT/BNT/CPDs/@gaussian_CPD/Old/CVS/Repository | ||
|---|---|---|
| 1 |
FullBNT/BNT/CPDs/@gaussian_CPD/Old |
|
| _FullBNT/BNT/CPDs/@gaussian_CPD/Old/CVS/Root | ||
|---|---|---|
| 1 |
:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt |
|
| _FullBNT/BNT/CPDs/@gaussian_CPD/Old/gaussian_CPD.m | ||
|---|---|---|
| 1 |
function CPD = gaussian_CPD(varargin) |
|
| 2 |
% GAUSSIAN_CPD Make a conditional linear Gaussian distrib. |
|
| 3 |
% |
|
| 4 |
% To define this CPD precisely, call the continuous (cts) parents (if any) X, |
|
| 5 |
% the discrete parents (if any) Q, and this node Y. Then the distribution on Y is: |
|
| 6 |
% - no parents: Y ~ N(mu, Sigma) |
|
| 7 |
% - cts parents : Y|X=x ~ N(mu + W x, Sigma) |
|
| 8 |
% - discrete parents: Y|Q=i ~ N(mu(i), Sigma(i)) |
|
| 9 |
% - cts and discrete parents: Y|X=x,Q=i ~ N(mu(i) + W(i) x, Sigma(i)) |
|
| 10 |
% |
|
| 11 |
% CPD = gaussian_CPD(bnet, node, ...) will create a CPD with random parameters, |
|
| 12 |
% where node is the number of a node in this equivalence class. |
|
| 13 |
% |
|
| 14 |
% The list below gives optional arguments [default value in brackets]. |
|
| 15 |
% (Let ns(i) be the size of node i, X = ns(X), Y = ns(Y) and Q = prod(ns(Q)).) |
|
| 16 |
% |
|
| 17 |
% mean - mu(:,i) is the mean given Q=i [ randn(Y,Q) ] |
|
| 18 |
% cov - Sigma(:,:,i) is the covariance given Q=i [ repmat(eye(Y,Y), [1 1 Q]) ] |
|
| 19 |
% weights - W(:,:,i) is the regression matrix given Q=i [ randn(Y,X,Q) ] |
|
| 20 |
% cov_type - if 'diag', Sigma(:,:,i) is diagonal [ 'full' ] |
|
| 21 |
% tied_cov - if 1, we constrain Sigma(:,:,i) to be the same for all i [0] |
|
| 22 |
% clamp_mean - if 1, we do not adjust mu(:,i) during learning [0] |
|
| 23 |
% clamp_cov - if 1, we do not adjust Sigma(:,:,i) during learning [0] |
|
| 24 |
% clamp_weights - if 1, we do not adjust W(:,:,i) during learning [0] |
|
| 25 |
% cov_prior_weight - weight given to I prior for estimating Sigma [0.01] |
|
| 26 |
% |
|
| 27 |
% e.g., CPD = gaussian_CPD(bnet, i, 'mean', [0; 0], 'clamp_mean', 'yes') |
|
| 28 |
% |
|
| 29 |
% For backwards compatibility with BNT2, you can also specify the parameters in the following order |
|
| 30 |
% CPD = gaussian_CPD(bnet, self, mu, Sigma, W, cov_type, tied_cov, clamp_mean, clamp_cov, clamp_weight) |
|
| 31 |
% |
|
| 32 |
% Sometimes it is useful to create an "isolated" CPD, without needing to pass in a bnet. |
|
| 33 |
% In this case, you must specify the discrete and cts parents (dps, cps) and the family sizes, followed |
|
| 34 |
% by the optional arguments above: |
|
| 35 |
% CPD = gaussian_CPD('self', i, 'dps', dps, 'cps', cps, 'sz', fam_size, ...)
|
|
| 36 |
|
|
| 37 |
|
|
| 38 |
if nargin==0 |
|
| 39 |
% This occurs if we are trying to load an object from a file. |
|
| 40 |
CPD = init_fields; |
|
| 41 |
clamp = 0; |
|
| 42 |
CPD = class(CPD, 'gaussian_CPD', generic_CPD(clamp)); |
|
| 43 |
return; |
|
| 44 |
elseif isa(varargin{1}, 'gaussian_CPD')
|
|
| 45 |
% This might occur if we are copying an object. |
|
| 46 |
CPD = varargin{1};
|
|
| 47 |
return; |
|
| 48 |
end |
|
| 49 |
CPD = init_fields; |
|
| 50 |
|
|
| 51 |
CPD = class(CPD, 'gaussian_CPD', generic_CPD(0)); |
|
| 52 |
|
|
| 53 |
|
|
| 54 |
% parse mandatory arguments |
|
| 55 |
if ~isstr(varargin{1}) % pass in bnet
|
|
| 56 |
bnet = varargin{1};
|
|
| 57 |
self = varargin{2};
|
|
| 58 |
args = varargin(3:end); |
|
| 59 |
ns = bnet.node_sizes; |
|
| 60 |
ps = parents(bnet.dag, self); |
|
| 61 |
dps = myintersect(ps, bnet.dnodes); |
|
| 62 |
cps = myintersect(ps, bnet.cnodes); |
|
| 63 |
fam_sz = ns([ps self]); |
|
| 64 |
else |
|
| 65 |
disp('parsing new style')
|
|
| 66 |
for i=1:2:length(varargin) |
|
| 67 |
switch varargin{i},
|
|
| 68 |
case 'self', self = varargin{i+1};
|
|
| 69 |
case 'dps', dps = varargin{i+1};
|
|
| 70 |
case 'cps', cps = varargin{i+1};
|
|
| 71 |
case 'sz', fam_sz = varargin{i+1};
|
|
| 72 |
end |
|
| 73 |
end |
|
| 74 |
ps = myunion(dps, cps); |
|
| 75 |
args = varargin; |
|
| 76 |
end |
|
| 77 |
|
|
| 78 |
CPD.self = self; |
|
| 79 |
CPD.sizes = fam_sz; |
|
| 80 |
|
|
| 81 |
% Figure out which (if any) of the parents are discrete, and which cts, and how big they are |
|
| 82 |
% dps = discrete parents, cps = cts parents |
|
| 83 |
CPD.cps = find_equiv_posns(cps, ps); % cts parent index |
|
| 84 |
CPD.dps = find_equiv_posns(dps, ps); |
|
| 85 |
ss = fam_sz(end); |
|
| 86 |
psz = fam_sz(1:end-1); |
|
| 87 |
dpsz = prod(psz(CPD.dps)); |
|
| 88 |
cpsz = sum(psz(CPD.cps)); |
|
| 89 |
|
|
| 90 |
% set default params |
|
| 91 |
CPD.mean = randn(ss, dpsz); |
|
| 92 |
CPD.cov = 100*repmat(eye(ss), [1 1 dpsz]); |
|
| 93 |
CPD.weights = randn(ss, cpsz, dpsz); |
|
| 94 |
CPD.cov_type = 'full'; |
|
| 95 |
CPD.tied_cov = 0; |
|
| 96 |
CPD.clamped_mean = 0; |
|
| 97 |
CPD.clamped_cov = 0; |
|
| 98 |
CPD.clamped_weights = 0; |
|
| 99 |
CPD.cov_prior_weight = 0.01; |
|
| 100 |
|
|
| 101 |
nargs = length(args); |
|
| 102 |
if nargs > 0 |
|
| 103 |
if ~isstr(args{1})
|
|
| 104 |
% gaussian_CPD(bnet, self, mu, Sigma, W, cov_type, tied_cov, clamp_mean, clamp_cov, clamp_weights) |
|
| 105 |
if nargs >= 1 & ~isempty(args{1}), CPD.mean = args{1}; end
|
|
| 106 |
if nargs >= 2 & ~isempty(args{2}), CPD.cov = args{2}; end
|
|
| 107 |
if nargs >= 3 & ~isempty(args{3}), CPD.weights = args{3}; end
|
|
| 108 |
if nargs >= 4 & ~isempty(args{4}), CPD.cov_type = args{4}; end
|
|
| 109 |
if nargs >= 5 & ~isempty(args{5}) & strcmp(args{5}, 'tied'), CPD.tied_cov = 1; end
|
|
| 110 |
if nargs >= 6 & ~isempty(args{6}), CPD.clamped_mean = 1; end
|
|
| 111 |
if nargs >= 7 & ~isempty(args{7}), CPD.clamped_cov = 1; end
|
|
| 112 |
if nargs >= 8 & ~isempty(args{8}), CPD.clamped_weights = 1; end
|
|
| 113 |
else |
|
| 114 |
CPD = set_fields(CPD, args{:});
|
|
| 115 |
end |
|
| 116 |
end |
|
| 117 |
|
|
| 118 |
% Make sure the matrices have 1 dimension per discrete parent. |
|
| 119 |
% Bug fix due to Xuejing Sun 3/6/01 |
|
Also available in: Unified diff