diff m-toolbox/classes/+utils/@math/loglikelihood_matrix.m @ 0:f0afece42f48

Import.
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Wed, 23 Nov 2011 19:22:13 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/m-toolbox/classes/+utils/@math/loglikelihood_matrix.m	Wed Nov 23 19:22:13 2011 +0100
@@ -0,0 +1,213 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Compute log-likelihood
+%
+% M Nofrarias 15-06-09
+%
+% $Id: loglikelihood_matrix.m,v 1.5 2011/11/16 08:52:50 nikos Exp $
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+function [loglk snr]= loglikelihood_matrix(xn,in,out,noise,model,params,inModel,outModel)
+% parameters
+fs = in(1).objs(1).fs;
+
+% num. experiments
+nexp = numel(in);
+% num. transfer functions
+nmod = numel(model(1).objs(:));
+noutChannels = sqrt(numel(noise(1).objs));
+
+% loop over experiments
+loglk = 0;
+snr = 0;
+for i = 1:nexp
+    if ((numel(in(1).objs) == 1) && numel(out(1).objs) == 1)
+        
+        freqs = in(i).objs(1).data.getX;
+        % evaluate models
+        if(isempty(outModel))
+            h11 = model(1).objs(1).setParams(params,xn).double;
+        elseif (~isempty(outModel))
+            h11 = outModel(1,1).y * model(1).getObjectAtIndex(1,1).setParams(params,xn).double';
+        end
+    
+        % spectra to variance
+        % (N*fs/2)* this multiplication is done now in mcmc
+        C11 = noise(1).objs(1).data.getY;
+    
+        % compute elements of inverse cross-spectrum matrix
+        InvS11 = 1./C11;
+    
+        % compute log-likelihood terms first, all at once does not cancel the
+        % imag part when multiplying x.*conj(x)
+        in1 = in(i).objs(1).data.getY;
+        out1 = out(i).objs(1).data.getY;
+        
+        tmplt1 = h11.*in1;
+        
+        v1v1 = conj(out1 - tmplt1).*(out1 - tmplt1);
+    
+        %computing SNR
+        snrexp = utils.math.stnr(tmplt1,0,out1,0,InvS11,0,0,0);
+    
+        snr = snr + 20*log10(snrexp); 
+          
+        log1exp = sum(InvS11.*v1v1);
+        
+        loglk = loglk + log1exp;
+        
+    elseif ((numel(in(1).objs) == 2) && numel(out(1).objs) == 2)
+        freqs = in(i).objs(1).data.getX;
+        % loop over models
+        
+        if(isempty(outModel))
+            for j = 1:nmod
+                % evaluate models
+                h(:,j) = model(i).objs(j).setParams(params,xn).double;
+            end
+        elseif (~isempty(outModel))
+            h(:,1) = outModel(1,1).y * model(i).getObjectAtIndex(1,1).setParams(params,xn).double';
+            h(:,2) = outModel(2,1).y * model(i).getObjectAtIndex(1,1).setParams(params,xn).double';
+            h(:,3) = outModel(1,2).y * model(i).getObjectAtIndex(2,2).setParams(params,xn).double';
+            h(:,4) = outModel(2,2).y * model(i).getObjectAtIndex(2,2).setParams(params,xn).double';
+        end
+        
+        for j = 1:noutChannels^2
+            % spectra to variance
+            % (N*fs/2)* this multiplication is done now in mcmc
+            C(:,j) = noise(i).objs(j).data.getY;
+        end
+        
+        % compute elements of inverse cross-spectrum matrix
+        detm = (C(:,1).*C(:,4) - C(:,2).*C(:,3));
+        InvS11 = C(:,4)./detm; %1 4
+        InvS22 = C(:,1)./detm; %4 1
+        InvS12 = C(:,2)./detm; %2 2
+        InvS21 = C(:,3)./detm; %3 3
+        
+        % compute log-likelihood terms first, all at once does not cancel the
+        % imag part when multiplying x.*conj(x)
+        in1 = in(i).objs(1).data.getY;
+        in2 = in(i).objs(2).data.getY;
+        out1 = out(i).objs(1).data.getY;
+        out2 = out(i).objs(2).data.getY;
+        
+        tmplt1 = h(:,1).*in1 + h(:,3).*in2;
+        tmplt2 = h(:,2).*in1 + h(:,4).*in2;
+        
+        % matrix index convention: H(1,1)->h(1)  H(2,1)->h(2)  H(1,2)->h(3)  H(2,2)->h(4)
+        v1v1 = conj(out1 - tmplt1).*(out1 - tmplt1);
+        v2v2 = conj(out2 - tmplt2).*(out2 - tmplt2);
+        v1v2 = conj(out1 - tmplt1).*(out2 - tmplt2);
+        v2v1 = conj(out2 - tmplt2).*(out1 - tmplt1);
+        
+        %computing SNR
+        snrexp = utils.math.stnr(tmplt1,tmplt2,out1,out2,InvS11,InvS22,InvS12,InvS21);
+    
+        snr = snr + 20*log10(snrexp); 
+        
+        log1exp = sum(InvS11.*v1v1 + InvS22.*v2v2 - InvS12.*v1v2 - InvS21.*v2v1);
+        
+        loglk = loglk + log1exp;
+        
+    elseif ((numel(in(1).objs) == 4) && numel(out(1).objs) == 3)
+        % here we are implementing only the magnetic case
+        % We have 4 inputs (the 4 conformator waveforms of the magnetic
+        % analysis and
+        % 3 outputs (that correspond to the IFO.x12 and IFO.ETA1 and
+        % IFO.PHI1
+        
+        
+        for j = 1:noutChannels^2
+            % spectra to variance
+            
+            % (N*fs/2)*   this factor multiplication is done now in mcmc,
+            % before splitting
+            C(:,j) = noise(i).objs(j).data.getY;
+        end
+        if( isempty(inModel) && ~isempty(outModel))
+            
+            freqs = in(i).objs(1).data.getX;
+            
+            % faster this way
+            h(:,1) = outModel(1,1).y * model(i).getObjectAtIndex(1,1).setParams(params,xn).double;
+            h(:,2) = outModel(2,1).y * model(i).getObjectAtIndex(1,1).setParams(params,xn).double;
+            h(:,3) = outModel(3,1).y * model(i).getObjectAtIndex(1,1).setParams(params,xn).double;
+            h(:,4) = outModel(1,1).y * model(i).getObjectAtIndex(1,2).setParams(params,xn).double;
+            h(:,5) = outModel(2,1).y * model(i).getObjectAtIndex(1,2).setParams(params,xn).double;
+            h(:,6) = outModel(3,1).y * model(i).getObjectAtIndex(1,2).setParams(params,xn).double;
+            h(:,7) = outModel(1,2).y * model(i).getObjectAtIndex(2,3).setParams(params,xn).double;
+            h(:,8) = outModel(2,2).y * model(i).getObjectAtIndex(2,3).setParams(params,xn).double;
+            h(:,9) = outModel(3,2).y * model(i).getObjectAtIndex(2,3).setParams(params,xn).double;
+            h(:,10) = outModel(1,3).y * model(i).getObjectAtIndex(3,4).setParams(params,xn).double;
+            h(:,11) = outModel(2,3).y * model(i).getObjectAtIndex(3,4).setParams(params,xn).double;
+            h(:,12) = outModel(3,3).y * model(i).getObjectAtIndex(3,4).setParams(params,xn).double;
+            
+            
+            % compute elements of inverse cross-spectrum matrix
+            detm = (C(:,1).*C(:,5).*C(:,9) + ...
+                C(:,2).*C(:,6).*C(:,7) + ...
+                C(:,3).*C(:,4).*C(:,8) -...
+                C(:,7).*C(:,5).*C(:,3) -...
+                C(:,8).*C(:,6).*C(:,1) -...
+                C(:,9).*C(:,4).*C(:,2));
+            
+            
+            InvS11 = (C(:,5).*C(:,9) - C(:,8).*C(:,6))./detm;
+            InvS12 = -(C(:,4).*C(:,9) - C(:,7).*C(:,6))./detm;
+            InvS13 = (C(:,4).*C(:,8) - C(:,7).*C(:,5))./detm;
+            InvS21 = -(C(:,2).*C(:,9) - C(:,8).*C(:,3))./detm;
+            InvS22 = (C(:,1).*C(:,9) - C(:,7).*C(:,3))./detm;
+            InvS23 = -(C(:,1).*C(:,8) - C(:,7).*C(:,2))./detm;
+            InvS31 = (C(:,2).*C(:,6) - C(:,5).*C(:,3))./detm;
+            InvS32 = -(C(:,1).*C(:,6) - C(:,4).*C(:,3))./detm;
+            InvS33 = (C(:,1).*C(:,5) - C(:,4).*C(:,2))./detm;
+            
+            % compute log-likelihood terms first, all at once does not cancel the
+            % imag part when multiplying x.*conj(x)
+            for ll = 1:noutChannels
+                outV(:,ll) = out(i).objs(ll).data.getY;
+            end
+            for kk = 1:model(i).ncols
+                inV(:,kk) = in(i).objs(kk).data.getY;
+            end
+            
+            % faster this way
+            v(:,1) = outV(:,1) - h(:,1).*inV(:,1) - h(:,4).*inV(:,2) - h(:,7).*inV(:,3) - h(:,10).*inV(:,4);
+            v(:,2) = outV(:,2) - h(:,2).*inV(:,1) - h(:,5).*inV(:,2) - h(:,8).*inV(:,3) - h(:,11).*inV(:,4);
+            v(:,3) = outV(:,3) - h(:,3).*inV(:,1) - h(:,6).*inV(:,2) - h(:,9).*inV(:,3) - h(:,12).*inV(:,4);
+            
+            v1v1 = conj(v(:,1)).*v(:,1);
+            v1v2 = conj(v(:,1)).*v(:,2);
+            v1v3 = conj(v(:,1)).*v(:,3);
+            v2v1 = conj(v(:,2)).*v(:,1);
+            v2v2 = conj(v(:,2)).*v(:,2);
+            v2v3 = conj(v(:,2)).*v(:,3);
+            v3v1 = conj(v(:,3)).*v(:,1);
+            v3v2 = conj(v(:,3)).*v(:,2);
+            v3v3 = conj(v(:,3)).*v(:,3);
+            
+            log1exp = sum(InvS11.*v1v1 +...
+                InvS12.*v1v2 +...
+                InvS13.*v1v3 +...
+                InvS21.*v2v1 +...
+                InvS22.*v2v2 +...
+                InvS23.*v2v3 +...
+                InvS31.*v3v1 +...
+                InvS32.*v3v2 +...
+                InvS33.*v3v3);
+            
+            loglk = loglk + log1exp;
+            
+            
+        else
+            error('For the magnetic case, implement an outModel and leave your inModel blank')
+        end
+        
+    else
+        error('Implemented cases: 1 input / 1output, 2 inputs / 2outputs (TN3045 analysis), and 4 inputs / 3 outpus (magnetic complete analysis model. Other cases have not been implemented yet. Sorry for the inconvenience)');
+    end
+    
+end
+end
+