function G = mkfactorgraph(U,X,A)
% MKFACTORGRAPH Generates a factor graph from discriminants and features
%
% G = MKFACTORGRAPH(U,X) where U is a list (cell) of
% factordiscriminant objects and X is a list of factorfeature
% objects. An error occurs if a feature's template does not match
% any discrminant's template.
%
% G = MKFACTORGRAPH(U,X,A) where A indicates whether all factor
% features should be used, generating an error if an appropriate
% discriminant cannot be found. If A==0, features with no matching
% discriminant are ignored.

% $Id: mkfactorgraph.m 35 2011-07-29 15:56:28Z weinman $
 
% Jerod Weinman
% jerod@acm.org
% Copyright 2008, 2009, 2011
 
%    This file is part of MatLibFactorGraph.
%
%    MatLibFactorGraph is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    MatLibFactorGraph is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with MatLibFactorGraph.  If not, see <http://www.gnu.org/licenses/>.

  if any(cellfun(@(uu) ~isa(uu,'factordiscr'),U))
    error('U must contain factordiscr objects');
  end;
  
  if any(cellfun(@(xx) ~isa(xx,'factorfeature'),X))
    error('X must contain factorfeature objects');
  end;

  if nargin<3
    A = 1;
  end;
  
  F = {};
  
  N = 0;
  for f=1:length(X)
    
    Tf = get(X{f},'template');
    
    u = find(cellfun(@(uu) get(uu,'template')==Tf,U));
    
    if isempty(u)
      if A
        error('Factor feature %d has no matching discriminant',f);
      else
        continue;
      end;
    end;
    
    N = max([N ; get(X{f},'variables')]);
    
    F{end+1} = mkfactor(U{u},X{f});
    
  end;
  
  G = factorgraph(N,F);
