diff m-toolbox/classes/+utils/@math/fisher_2x2.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/fisher_2x2.m	Wed Nov 23 19:22:13 2011 +0100
@@ -0,0 +1,141 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Compute Fisher matrix
+%
+%  Parameters are:
+%   i1        - input 1st channel (ao)
+%   i2        - input 2nd channel (ao)
+%   n         - noise both channels (matrix 2x1)
+%   mdl       - model (matrix or ssm)
+%   params    - parameters
+%   numparams - numerical value of parameters
+%   freqs     - frequnecies being evaluated
+%   N         - number of fft frequencies
+%   pl        - plist
+%
+% M Nofrarias 15-06-09
+%
+% $Id: fisher_2x2.m,v 1.3 2011/09/19 06:19:13 miquel Exp $
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+function FisMat = fisher_2x2(i1,i2,n,mdl,params,numparams,freqs,N,pl,inNames,outNames)
+
+import utils.const.*
+
+% Compute psd
+n1  = psd(n.getObjectAtIndex(1,1), pl);
+n2  = psd(n.getObjectAtIndex(2,1), pl);
+n12 = cpsd(n.getObjectAtIndex(1,1),n.getObjectAtIndex(2,1), pl);
+
+% interpolate to given frequencies
+% noise
+S11 = interp(n1,plist('vertices',freqs));
+S12 = interp(n12,plist('vertices',freqs));
+S22 = interp(n2,plist('vertices',freqs));
+S21 = conj(S12);
+
+% get some parameters used below
+fs = S11.fs;
+
+if ~isempty(mdl) && all(strcmp(class(mdl),'matrix'))
+    % compute built-in matrix
+    for i = 1:numel(mdl.objs)
+        % set Xvals
+        h(i) = mdl.getObjectAtIndex(i).setXvals(freqs);
+        % set alias
+        h(i).assignalias(mdl.objs(i),plist('xvals',freqs));
+        % set paramaters
+        h(i).setParams(params,numparams);
+    end
+    % differentiate and eval
+    for i = 1:length(params)
+        utils.helper.msg(msg.IMPORTANT, sprintf('computing symbolic differentiation with respect %s',params{i}), mfilename('class'), mfilename);
+        % differentiate symbolically
+        dH11 = diff(h(1),params{i});
+        dH12 = diff(h(3),params{i});  % taking into account matrix index convention h(2) > H(2,1)
+        dH21 = diff(h(2),params{i});
+        dH22 = diff(h(4),params{i});
+        % evaluate
+        d11(i) = eval(dH11);
+        d12(i) = eval(dH12);
+        d21(i) = eval(dH21);
+        d22(i) = eval(dH22);
+    end
+    
+elseif ~isempty(mdl) && all(strcmp(class(mdl),'ssm'))
+    
+    meval = copy(mdl,1);
+    % set parameter values
+    meval.doSetParameters(params, numparams);
+    % get the differentiation step
+    step = find(pl,'step');
+    % case no diff. step introduced
+    if isempty(step)
+        utils.helper.msg(msg.IMPORTANT, ...
+            sprintf('computing optimal differentiation steps'), mfilename('class'), mfilename);
+        ranges = find(pl,'stepRanges');
+        if isempty(ranges)
+            error('### Please input upper and lower ranges for the parameters: ''ranges''')
+        end
+        ngrid = find(pl,'ngrid');
+        if isempty(ngrid)
+            error('### Please input a number of points for the grid to compute the diff. step : ''ngrid''')
+        end
+        % look for numerical differentiation step
+        step = utils.math.diffStepFish(i1,i2,S11,S12,S21,S22,N,meval,params,ngrid,ranges,freqs,inNames,outNames);
+    end
+    
+    % differentiate and eval
+    for i = 1:length(params)
+        utils.helper.msg(msg.IMPORTANT, ...
+            sprintf('computing numerical differentiation with respect %s, Step:%4.2d ',params{i},step(i)), mfilename('class'), mfilename);
+        % differentiate numerically
+        dH = meval.parameterDiff(plist('names', params(i),'values',step(i)));
+        % create plist with correct outNames (since parameterDiff change them)
+        out1 = strrep(outNames{1},'.', sprintf('_DIFF_%s.',params{i})); % 2x2 case
+        out2 =strrep(outNames{2},'.', sprintf('_DIFF_%s.',params{i}));
+        spl = plist('set', 'for bode', ...
+            'outputs', {out1,out2}, ...
+            'inputs', inNames, ...
+            'reorganize', true,...
+            'f', freqs);
+        % do bode
+        d  = bode(dH, spl);
+        % assign according matlab's matrix notation: H(1,1)->h(1)  H(2,1)->h(2)  H(1,2)->h(3)  H(2,2)->h(4)
+        d11(i) = d.objs(1);
+        d21(i) = d.objs(2);
+        d12(i) = d.objs(3);
+        d22(i) = d.objs(4);
+    end
+    
+else
+    error('### please introduce models for the transfer functions')
+end
+
+% scaling of PSD
+% PSD = 2/(N*fs) * FFT *conj(FFT)
+C11 = N*fs/2.*S11.y;
+C22 = N*fs/2.*S22.y;
+C12 = N*fs/2.*S12.y;
+C21 = N*fs/2.*S21.y;
+
+% compute elements of inverse cross-spectrum matrix
+InvS11 = (C22./(C11.*C22 - C12.*C21));
+InvS22 = (C11./(C11.*C22 - C12.*C21));
+InvS12 = (C21./(C11.*C22 - C12.*C21));
+InvS21 = (C12./(C11.*C22 - C12.*C21));
+
+% compute Fisher Matrix
+for i =1:length(params)
+    for j =1:length(params)
+        
+        v1v1 = conj(d11(i).y.*i1.y + d12(i).y.*i2.y).*(d11(j).y.*i1.y + d12(j).y.*i2.y);
+        v2v2 = conj(d21(i).y.*i1.y + d22(i).y.*i2.y).*(d21(j).y.*i1.y + d22(j).y.*i2.y);
+        v1v2 = conj(d11(i).y.*i1.y + d12(i).y.*i2.y).*(d21(j).y.*i1.y + d22(j).y.*i2.y);
+        v2v1 = conj(d21(i).y.*i1.y + d22(i).y.*i2.y).*(d11(j).y.*i1.y + d12(j).y.*i2.y);
+        
+        FisMat(i,j) = sum(real(InvS11.*v1v1 + InvS22.*v2v2 - InvS12.*v1v2 - InvS21.*v2v1));
+    end
+end
+
+end
\ No newline at end of file