diff options
Diffstat (limited to 'sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD')
13 files changed, 251 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m new file mode 100644 index 00000000..93a6dcef --- /dev/null +++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m @@ -0,0 +1,34 @@ +function CPT = CPD_to_CPT(CPD) +% CPD_TO_CPT Convert the discrete CPD to tabular form (noisyor) +% CPT = CPD_to_CPT(CPD) +% +% CPT(U1,...,Un, X) = Pr(X|U1,...,Un) where the Us are the parents (excluding leak). + +if ~isempty(CPD.CPT) + CPT = CPD.CPT; % remember to flush cache if params change (e.g., during learning) + return; +end + +q = [CPD.leak_inhibit CPD.inhibit(:)']; +% q(i) is the prob. that the i'th parent will be inhibited (flipped from 1 to 0). +% q(1) is the leak inhibition probability, and length(q) = n + 1. + +if length(q)==1 + CPT = [q 1-q]; + return; +end + +n = length(q); +Bn = ind2subv(2*ones(1,n), 1:(2^n))-1; % all n bit vectors, with the left most column toggling fastest (LSB) +CPT = zeros(2^n, 2); +% Pr(X=0 | U_1 .. U_n) = prod_{i: U_i = on} q_i = prod_i q_i ^ U_i = exp(u' * log(q_i)) +% This method is problematic when q contains zeros + +Q = repmat(q(:)', 2^n, 1); +Q(logical(~Bn)) = 1; +CPT(:,1) = prod(Q,2); +CPT(:,2) = 1-CPT(:,1); + +CPT = reshape(CPT(2:2:end), 2*ones(1,n)); % skip cases in which the leak is off + +CPD.CPT = CPT; diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m~ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m~ new file mode 100644 index 00000000..6f4cacd4 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m~ @@ -0,0 +1,70 @@ +function CPT = CPD_to_CPT(CPD) +% CPD_TO_CPT Convert the discrete CPD to tabular form (noisyor) +% CPT = CPD_to_CPT(CPD) +% +% CPT(U1,...,Un, X) = Pr(X|U1,...,Un) where the Us are the parents (excluding leak). + +if ~isempty(CPD.CPT) + CPT = CPD.CPT; % remember to flush cache if params change (e.g., during learning) + return; +end + +q = [CPD.leak_inhibit CPD.inhibit(:)']; +% q(i) is the prob. that the i'th parent will be inhibited (flipped from 1 to 0). +% q(1) is the leak inhibition probability, and length(q) = n + 1. + +if length(q)==1 + CPT = [q 1-q]; + return; +end + +n = length(q); +Bn = ind2subv(2*ones(1,n), 1:(2^n))-1; % all n bit vectors, with the left most column toggling fastest (LSB) +CPT = zeros(2^n, 2); +% Pr(X=0 | U_1 .. U_n) = prod_{i: U_i = on} q_i = prod_i q_i ^ U_i = exp(u' * log(q_i)) +% This method is problematic when q contains zeros + +Q = repmat(q(:)', 2^n, 1); +Q(logical(~Bn)) = 1; +CPT(:,1) = prod(Q,2); +CPT(:,2) = 1-CPT(:,1); + +CPT = reshape(CPT(2:2:end), 2*ones(1,n)); % skip cases in which the leak is off + +CPD.CPT = CPT; + +function CPT = CPD_to_CPT(CPD) +% CPD_TO_CPT Convert the discrete CPD to tabular form (noisyor) +% CPT = CPD_to_CPT(CPD) +% +% CPT(U1,...,Un, X) = Pr(X|U1,...,Un) where the Us are the parents (excluding leak). + +if ~isempty(CPD.CPT) + CPT = CPD.CPT; % remember to flush cache if params change (e.g., during learning) + return; +end + +q = [CPD.leak_inhibit CPD.inhibit(:)']; +% q(i) is the prob. that the i'th parent will be inhibited (flipped from 1 to 0). +% q(1) is the leak inhibition probability, and length(q) = n + 1. + +if length(q)==1 + CPT = [q 1-q]; + return; +end + +n = length(q); +Bn = ind2subv(2*ones(1,n), 1:(2^n))-1; % all n bit vectors, with the left most column toggling fastest (LSB) +CPT = zeros(2^n, 2); +% Pr(X=0 | U_1 .. U_n) = prod_{i: U_i = on} q_i = prod_i q_i ^ U_i = exp(u' * log(q_i)) +% This method is problematic when q contains zeros + +Q = repmat(q(:)', 2^n, 1); +Q(logical(~Bn)) = 1; +CPT(:,1) = prod(Q,2); +CPT(:,2) = 1-CPT(:,1); + +CPT = reshape(CPT(2:2:end), 2*ones(1,n)); % skip cases in which the leak is off + +CPD.CPT = CPT; + diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_lambda_msg.m b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_lambda_msg.m new file mode 100644 index 00000000..8046c860 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_lambda_msg.m @@ -0,0 +1,19 @@ +function lam_msg = CPD_to_lambda_msg(CPD, msg_type, n, ps, msg, p, evidence) +% CPD_TO_LAMBDA_MSG Compute lambda message (noisyor) +% lam_msg = CPD_to_lambda_msg(CPD, msg_type, n, ps, msg, p) +% Pearl p190 top eqn + +switch msg_type + case 'd', + l0 = msg{n}.lambda(1); + l1 = msg{n}.lambda(2); + Pi = sum_prod_CPD_and_pi_msgs(CPD, n, ps, msg, p); + i = find(p==ps); % p is n's i'th parent + q = CPD.inhibit(i); + lam_msg = zeros(2,1); + for u=0:1 + lam_msg(u+1) = l1 - (q^u)*(l1 - l0)*Pi; + end + case 'g', + error('noisyor_CPD can''t create Gaussian msgs') +end diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_pi.m b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_pi.m new file mode 100644 index 00000000..6955f115 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_pi.m @@ -0,0 +1,12 @@ +function pi = CPD_to_pi(CPD, msg_type, n, ps, msg, evidence) +% CPD_TO_PI Compute pi vector (noisyor) +% pi = CPD_to_pi(CPD, msg_type, n, ps, msg) +% Pearl p188 eqn 4.57 + +switch msg_type + case 'd', + pi = sum_prod_CPD_and_pi_msgs(CPD, n, ps, msg); + pi = [pi 1-pi]'; + case 'g', + error('can''t convert noisy-or CPD to Gaussian pi') +end diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries new file mode 100644 index 00000000..4cfae75b --- /dev/null +++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries @@ -0,0 +1,5 @@ +/CPD_to_CPT.m/1.1.1.1/Mon Aug 2 22:23:32 2004// +/CPD_to_lambda_msg.m/1.1.1.1/Wed May 29 15:59:54 2002// +/CPD_to_pi.m/1.1.1.1/Wed May 29 15:59:54 2002// +/noisyor_CPD.m/1.1.1.1/Wed May 29 15:59:54 2002// +D diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries.Log new file mode 100644 index 00000000..b2cd71e0 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries.Log @@ -0,0 +1 @@ +A D/private//// diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Repository new file mode 100644 index 00000000..a3f1a38a --- /dev/null +++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Repository @@ -0,0 +1 @@ +FullBNT/BNT/CPDs/@noisyor_CPD diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Root new file mode 100644 index 00000000..f3bd14a6 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Root @@ -0,0 +1 @@ +:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/noisyor_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/noisyor_CPD.m new file mode 100644 index 00000000..aecf9b6d --- /dev/null +++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/noisyor_CPD.m @@ -0,0 +1,79 @@ +function CPD = noisyor_CPD(bnet, self, leak_inhibit, inhibit) +% NOISYOR_CPD Make a noisy-or CPD +% CPD = NOISYOR_CPD(BNET, NODE_NUM, LEAK_INHIBIT, INHIBIT) +% +% A noisy-or node turns on if any of its parents are on, provided they are not inhibited. +% The prob. that the i'th parent gets inhibited (flipped from 1 to 0) is inhibit(i). +% The prob that the leak node (a dummy parent that is always on) gets inhibit is leak_inhibit. +% These params default to random values if omitted. +% +% Example: suppose C has parents A and B, and the +% link of A->C fails with prob pA and the link B->C fails with pB. +% Then the noisy-OR gate defines the following distribution +% +% A B P(C=0) +% 0 0 1.0 +% 1 0 pA +% 0 1 pB +% 1 1 pA * PB +% +% Currently, learning is not supported for noisy-or nodes +% (since the M step is somewhat complicated). +% +% For simple generalizations of the noisy-OR model, see e.g., +% - Srinivas, "A generalization of the noisy-OR model", UAI 93 +% - Meek and Heckerman, "Learning Causal interaction models", UAI 97. + + + +if nargin==0 + % This occurs if we are trying to load an object from a file. + CPD = init_fields; + CPD = class(CPD, 'noisyor_CPD', discrete_CPD(1, [])); + return; +elseif isa(bnet, 'noisyor_CPD') + % This might occur if we are copying an object. + CPD = bnet; + return; +end +CPD = init_fields; + + +ps = parents(bnet.dag, self); +fam = [ps self]; +ns = bnet.node_sizes; +assert(all(ns(fam)==2)); +assert(isempty(myintersect(fam, bnet.cnodes))); + +if nargin < 3, leak_inhibit = rand(1, 1); end +if nargin < 4, inhibit = rand(1, length(ps)); end + +CPD.self = self; +CPD.inhibit = inhibit; +CPD.leak_inhibit = leak_inhibit; + + +% For BIC +CPD.nparams = 0; +CPD.nsamples = 0; + +CPD.CPT = []; % cached copy, to speed up CPD_to_CPT + +clamped = 1; +CPD = class(CPD, 'noisyor_CPD', discrete_CPD(clamped, ns([ps self]))); + + + +%%%%%%%%%%% + +function CPD = init_fields() +% This ensures we define the fields in the same order +% no matter whether we load an object from a file, +% or create it from scratch. (Matlab requires this.) + +CPD.self = []; +CPD.inhibit = []; +CPD.leak_inhibit = []; +CPD.nparams = []; +CPD.nsamples = []; +CPD.CPT = []; diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Entries new file mode 100644 index 00000000..b56c53ed --- /dev/null +++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Entries @@ -0,0 +1,2 @@ +/sum_prod_CPD_and_pi_msgs.m/1.1.1.1/Wed May 29 15:59:54 2002// +D diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Repository new file mode 100644 index 00000000..716dfddd --- /dev/null +++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Repository @@ -0,0 +1 @@ +FullBNT/BNT/CPDs/@noisyor_CPD/private diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Root new file mode 100644 index 00000000..f3bd14a6 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Root @@ -0,0 +1 @@ +:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/sum_prod_CPD_and_pi_msgs.m b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/sum_prod_CPD_and_pi_msgs.m new file mode 100644 index 00000000..9ca31d3c --- /dev/null +++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/sum_prod_CPD_and_pi_msgs.m @@ -0,0 +1,25 @@ +function pi = sum_prod_CPD_and_pi_msgs(CPD, n, ps, msg, except) +% SUM_PROD_CPD_AND_PI_MSGS Compute pi = sum_{u\p} P(n|u) prod_{ui in ps\p} pi_msg(ui->n) +% pi = sum_prod_CPD_and_pi_msgs(CPD, n, ps, msg, p) +% +% pi = prod_i (qi pi_msg(ui->n) + 1 - pi_msg(ui->n)) = prod_i (1 - ci pi_msg(ui->n)) +% is the product of the endorsement withheld (Pearl p188 eqn 4.56) +% We skip p from this product, if specified. + +if nargin < 5, except = -1; end +pi = 1; +for i=1:length(ps) + p = ps(i); + if p ~= except + pi_from_parent = msg{n}.pi_from_parent{i}; + q = CPD.inhibit(i); + c = 1-q; + pi = pi * (1 - c*pi_from_parent(2)); + end +end +% The pi msg that a leak node sends to its child is [0 1] +% since its own pi is [0 1] and its lambda to self is [0 1]. +q = CPD.leak_inhibit; +% 1 - c*pi_from_parent = 1-c*1 = q +pi = pi * q; + |
