www.pudn.com > ConstrainedEM.zip > connected_component_pf.m



function [ partition , grad ]=connected_component_pf( net , elim_order ,p ,no_grad)

% the function calculates the partition function and the gradient of the 
% partition functiona. assumes a network with (1 - delta(i,j) ) on every arc 
% and a (p1,p2,...,pk) potential on every node.

n=size(net,1);  % variables ( nodes ) number
k=length(p);    % parameters ( node values ) number

if no_grad
   grad=[];
end

% create the factors and the d_factors objects

% node potentials 
for i=1:n
    factors(i)=dpot(i, k, p);
    if ~no_grad
       for j=1:k
          d_factors{i,j}=dpot(i,k,[ zeros(1,j-1) 1 zeros(1,k-j) ]);
       end
    end
 end
 
 

%arc potentials
[ x y ]=find(triu(net)~=0);
edge_n=length(x);

for i=n+1:n+edge_n
   factors(i)=dpot([ x(i-n) y(i-n) ],[ k k],ones(k,k)-eye(k));
   if ~no_grad
      for j=1:k
         d_factors{i,j}=dpot([ x(i-n) y(i-n) ],[k k],zeros(k,k));
      end
   end
end


% calculate the pf and the gard

for i=1:n
    % find the indexes of the relevant factors
    fi=[];
    for j=1:length(factors)
       tmp=struct(factors(j));
       %find( my_ismember(elim_order(i),tmp.domain) - ismember(elim_order(i),tmp.domain) ) 
       if my_ismember(elim_order(i),tmp.domain) 
            fi=[ fi j ];
        end
     end
%      if (length(fi)>6)
%         'w'
%      end
     % calculate factor and gradient of the multiplication of relevant factors. 
     if no_grad
        [ fac , gfac ]=mult_d_factors(factors(fi),[],no_grad);
     else
        [ fac , gfac ]=mult_d_factors(factors(fi),d_factors(fi,:),no_grad);
     end
     % sum out relevant index
     tmp_fac=struct(fac);
     rest=setdiff(tmp_fac.domain,elim_order(i));
     fac=marginalize_pot(fac,rest);
     if ~no_grad
        for j=1:k
            gfac{j}=marginalize_pot(gfac{j},rest);
        end
    end
    % adjust the factors list
    rem=setdiff(1:length(factors),fi);
    factors=factors(rem);
    factors(end+1)=fac;
    if ~no_grad
        d_factors=d_factors(rem,:);
        d_factors(end+1,:)=gfac;
    end
end

tmp=struct(factors(1));
partition=tmp.T;
if ~no_grad
   for j=1:k
      tmp=struct( d_factors{1,j});
      grad(j)=tmp.T;
   end
end