Mercurial > hg > camir-aes2014
comparison toolboxes/FullBNT-1.0.7/bnt/CPDs/@boolean_CPD/boolean_CPD.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e9a9cd732c1e |
---|---|
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 |