wolffd@0: function CPD = deterministic_CPD(bnet, self, fname, pfail) wolffd@0: % DETERMINISTIC_CPD Make a tabular CPD representing a (noisy) deterministic function wolffd@0: % wolffd@0: % CPD = deterministic_CPD(bnet, self, fname) wolffd@0: % This calls feval(fname, pvals) for each possible vector of parent values. wolffd@0: % e.g., suppose there are 2 ternary parents, then pvals = wolffd@0: % [1 1], [2 1], [3 1], [1 2], [2 2], [3 2], [1 3], [2 3], [3 3] wolffd@0: % If v = feval(fname, pvals(i)), then wolffd@0: % CPD(x | parents=pvals(i)) = 1 if x==v, and = 0 if x<>v wolffd@0: % e.g., suppose X4 = X2 AND (NOT X3). Then wolffd@0: % bnet.CPD{4} = deterministic_CPD(bnet, 4, inline('((x(1)-1) & ~(x(2)-1)) + 1')); wolffd@0: % Note that x(1) refers pvals(1) = X2, and x(2) refers to pvals(2)=X3 wolffd@0: % See also boolean_CPD. wolffd@0: % wolffd@0: % CPD = deterministic_CPD(bnet, self, fname, pfail) wolffd@0: % will put probability mass 1-pfail on f(parents), and distribute pfail over the other values. wolffd@0: % This is useful for simulating noisy deterministic functions. wolffd@0: % If pfail is omitted, it is set to 0. wolffd@0: % wolffd@0: wolffd@0: wolffd@0: if nargin==0 wolffd@0: % This occurs if we are trying to load an object from a file. wolffd@0: CPD = tabular_CPD(bnet, self); wolffd@0: return; wolffd@0: elseif isa(bnet, 'deterministic_CPD') wolffd@0: % This might occur if we are copying an object. wolffd@0: CPD = bnet; wolffd@0: return; wolffd@0: end wolffd@0: wolffd@0: if nargin < 4, pfail = 0; end wolffd@0: wolffd@0: ps = parents(bnet.dag, self); wolffd@0: ns = bnet.node_sizes; wolffd@0: psizes = ns(ps); wolffd@0: self_size = ns(self); wolffd@0: wolffd@0: psucc = 1-pfail; wolffd@0: wolffd@0: CPT = zeros(prod(psizes), self_size); wolffd@0: pvals = zeros(1, length(ps)); wolffd@0: for i=1:prod(psizes) wolffd@0: pvals = ind2subv(psizes, i); wolffd@0: x = feval(fname, pvals); wolffd@0: %fprintf('%d ', [pvals x]); fprintf('\n'); wolffd@0: if psucc == 1 wolffd@0: CPT(i, x) = 1; wolffd@0: else wolffd@0: CPT(i, x) = psucc; wolffd@0: rest = mysetdiff(1:self_size, x); wolffd@0: CPT(i, rest) = pfail/length(rest); wolffd@0: end wolffd@0: end wolffd@0: CPT = reshape(CPT, [psizes self_size]); wolffd@0: wolffd@0: CPD = tabular_CPD(bnet, self, 'CPT',CPT, 'clamped',1); wolffd@0: wolffd@0: