Revision 8:b5b38998ef3b

View differences:

_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
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff