about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD
diff options
context:
space:
mode:
Diffstat (limited to 'sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD')
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m34
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m~70
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_lambda_msg.m19
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_pi.m12
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/noisyor_CPD.m79
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/sum_prod_CPD_and_pi_msgs.m25
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;
+