wolffd@0: function fg = mk_fgraph(G, node_sizes, factors, varargin) wolffd@0: % MK_FGRAPH Make a factor graph wolffd@0: % fg = mk_fgraph(G, node_sizes, factors, ...) wolffd@0: % wolffd@0: % A factor graph is a bipartite graph, with one side containing variables, wolffd@0: % and the other containing functions of (subsets of) these variables. wolffd@0: % For details, see "Factor Graphs and the Sum-Product Algorithm", wolffd@0: % F. Kschischang and B. Frey and H-A. Loeliger, wolffd@0: % IEEE Trans. Info. Theory, 2001 wolffd@0: % wolffd@0: % G(i,j) = 1 if there is an arc from variable i to factor j wolffd@0: % wolffd@0: % node_sizes(i) is the number of values node i can take on, wolffd@0: % or the length of node i if i is a continuous-valued vector. wolffd@0: % wolffd@0: % 'factors' is the list of factors (kernel functions) wolffd@0: % wolffd@0: % The list below gives optional arguments [default value in brackets]. wolffd@0: % wolffd@0: % equiv_class - equiv_class(i)=j means factor node i gets its params from factors{j} [1:F] wolffd@0: % discrete - the list of nodes which are discrete random variables [1:N] wolffd@0: % wolffd@0: % e.g., fg = mk_fgraph(G, [2 2], {bnet.CPD{1},bnet.CPD{2}}, 'discrete', [1 2]) wolffd@0: wolffd@0: fg.G = G; wolffd@0: fg.node_sizes = node_sizes; wolffd@0: fg.factors = factors; wolffd@0: [fg.nvars fg.nfactors] = size(G); wolffd@0: wolffd@0: % default values for parameters wolffd@0: fg.equiv_class = 1:fg.nfactors; wolffd@0: fg.dnodes = 1:fg.nvars; wolffd@0: wolffd@0: if nargin >= 4 wolffd@0: args = varargin; wolffd@0: nargs = length(args); wolffd@0: for i=1:2:nargs wolffd@0: switch args{i}, wolffd@0: case 'equiv_class', fg.equiv_class = args{i+1}; wolffd@0: case 'discrete', fg.dnodes = args{i+1}; wolffd@0: otherwise, wolffd@0: error(['invalid argument name ' args{i}]); wolffd@0: end wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: % so that determine_pot_type will work... wolffd@0: fg.utility_nodes = []; wolffd@0: %fg.decision_nodes = []; wolffd@0: %fg.chance_nodes = fg.nvars; wolffd@0: wolffd@0: fg.dom = cell(1, fg.nfactors); wolffd@0: for f=1:fg.nfactors wolffd@0: fg.dom{f} = find(G(:,f)); wolffd@0: end wolffd@0: fg.dep = cell(1, fg.nvars); wolffd@0: for x=1:fg.nvars wolffd@0: fg.dep{x} = find(G(x,:)); wolffd@0: end wolffd@0: fg.cnodes = mysetdiff(1:fg.nvars, fg.dnodes);