www.pudn.com > ConstrainedEM.zip > calc_p_and_pll2.m
function [ pots , pll ] =calc_p_and_pll4(data,param,scmf,c_inds,nc_inds,singles)
% this is a version of calc_p_and_ll2. it is functionally equivalent.
% the difference is that this version is amendable to any sort of numerical problems whatsoever.
% this function gets rid of the observables ( including chunklett information ) by
% turning them into potentials over the hiddens. The potentials over networked
% hiddens are used later in the inference , and are not the p( hidden i | model j )
% yet. The potentials over unnetworked hiddens are used here ( to calculate the
% donation of these points to the ll ) and later as p( hidden i | model j).
% scmf - single cov mat flag.
% c_inds - a cell array of chunklets. each cell contains data index of a chunklet
% nc_inds - the indexes of points that aren't in any chunklet.
% singles - indexes of hiddens which aren't connected to others.
% global parameters :
% nets - the net objects ( pots indexes + engine ) to use for inference
% pruned flag - a flag indicating that the nets have been pruned already . used
% when reduced arcs is 2
% reduced arcs - if 0 no prunning is done. if 1 prunning is done. if 2 , prunning is
% done only if pruned flag is set
% late_oracle - late or early oracle prior calculation.
% outputs :
% pots - for every hidden : p(h , O=o ) ( when normailized : p(h|O) )
% pll - partial log liklihood : the log likelihood without the partition function
% effect. the components of the pll are
% single hidden nodes donation + the donation of underflow preventing constants
% from hidden connected nodes which have chunklets + connected hidden nodes donation
% this is a second version of this file, and it is supposed to cope with
% numerical instabilities. To do this, the computation of the expectation weights is
% seperated from the computation of the ll.
global nets;
global OriginalNets;
global pruned_flag;
global reduce_arcs;
global late_oracle;
global exit_flags;
global HiddensW;
global aa_flag;
s=size(param);
k=s(1);
s=size(data);
n=s(1);
d=s(2);
ch_num=length(c_inds);
pots=zeros(ch_num+length(nc_inds),k);
pll=0;
% calculate p(O|h) for every point and p( O , h) for non chunkletted points.
for j=1:k
if scmf==1
cov_index=1;
else
cov_index=j;
end
tempData=data-ones(n,1)*param{j,1}; % subtract the mean
covDet=abs(det(param{cov_index,2}));
if( ( covDet<=(0.01^d) ) & (~scmf) )
if bitand(exit_flags,16)==0 % covmat is close to singular
%disp(sprintf( 'covmat %d is close to singular at calc_p_and_pll\n',cov_index));
exit_flags=bitor(exit_flags,16); % set bit 4.
end
end
expContent=-0.5*sum(tempData*inv(param{cov_index,2}).*tempData,2); % the exponent content
LogProbs(:,j)= -(d/2)*log(2*pi) -0.5*log(det(param{cov_index,2}))+expContent;
LogProbs(nc_inds,j)=LogProbs(nc_inds,j)+log(param{j,3});
end
% copy the unchunkleted points probabilities to hn probabilities.
LogPots(ch_num+1:ch_num+length(nc_inds),:)=LogProbs(nc_inds,:);
% calculate p (o,h ) for chunkletted data
if ch_num~=0
for j=1:ch_num;
inds=c_inds{j};
log_tmp=LogProbs(inds,:);
log_alpha=log(cell2mat(param(:,3))');
if late_oracle
exp_content=sum(log_tmp)+size(log_tmp,1)*log_alpha;
else
exp_content=sum(log_tmp)+log_alpha;
end
LogPots(j,:)=exp_content;
end
end
m=max(LogPots');
LogPots=LogPots- m'*ones(1,k);
addition_to_ll=sum(m); % ll=log ( sum(k) of exp(m)*exp( alpha_k + sum(i) log (p(x_i|h=k)) )
pots=exp(LogPots);
% add to pll log likihood of single hiddens (and their observables )
point_sum=sum(pots(singles,:)');
% Canoot happend
inds2=find(point_sum==0);
if ~isempty(inds2)
probabilities(nc_inds(inds2),:)=1;
pll=-inf;
return;
end
% end of 'cannot happend'
pll=pll+sum(log(point_sum))+addition_to_ll;
pots(singles,:)=pots(singles,:)./( point_sum'*ones(1,k) ); %normalize the pots into probabilities.
%ll = sum(log(sum(probabilities'))); % the formula without special care for underflow (zeros)
% do inference in local nets, turning pots to probabilities
% pll gets the donation of connected hidden nodes.
for i=1:length(nets)
if (reduce_arcs==1)|( (reduce_arcs==2)&(pruned_flag==0))
nets{i}.engine=reduce_local_net2(OriginalNets{i}.engine, pots(nets{i}.h_vars,:));
end
[ pots(nets{i}.h_vars,:) ll_net ]=infer_local_net(nets{i}.engine, pots(nets{i}.h_vars,:));
pll=pll+ll_net;
end
pruned_flag=1;