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