diff m-toolbox/classes/+utils/@math/linlsqsvd.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/linlsqsvd.m	Wed Nov 23 19:22:13 2011 +0100
@@ -0,0 +1,140 @@
+% LINLSQSVD Linear least squares with singular value decomposition
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DESCRIPTION: Linear least square problem with singular value
+% decomposition
+%
+% ALGORITHM: % It solves the problem
+%
+%        Y = HX
+%
+% where X are the parameters, Y the measurements, and H the linear
+% equations relating the two.
+% It is able to perform linear identification of the parameters of a
+% multichannel systems. The results of different experiments on the same
+% system can be passed as input. The algorithm, thanks to the singular
+% value decomposition, extract the maximum amount of information from each
+% single channel and for each experiment. Total information is then
+% combined to get the final result.
+%            
+% CALL: [a,Ca,Corra,Vu,bu,Cbu,Fbu,mse,dof,ppm] = utils.math.linlsqsvd(H1,...,HN,Y);
+%       [a,Ca,Corra,Vu,bu,Cbu,Fbu,mse,dof,ppm] = utils.math.linlsqsvd(H1,...,HN,Y,errthres);
+%       [a,Ca,Corra,Vu,bu,Cbu,Fbu,mse,dof,ppm] = utils.math.linlsqsvd(H1,...,HN,Y,errthres,knwpars);
+% 
+% If the experiment is 1 then H1,...,HN and Y are aos.
+% If the experiments are M, then H1,...,HN and Y are Mx1 matrix objects
+% with the aos relating to the given experiment in the proper position.
+% 
+% INPUT:
+%               - Hi represent the columns of H
+%               - Y represent the measurement set
+%               - sThreshold it's a threshold for singular values. It is a
+%               number, typically 1. It will remove singular values larger
+%               than sThreshold which corresponds to removing svd parameters estimated
+%               with an error larger than sThreshold.
+%               - knwpars A struct array with the fields:
+%                   pos - a number indicating the corresponding position of
+%                     the parameter (corresponding column of H)
+%                   value - the value for the parameter
+%                   err - the uncertainty associated to the parameter
+% 
+% OUTPUT:
+%   a:      params values
+%   Ca:     fit covariance matrix for A
+%   Corra:  fit correlation matrix for A
+%   Vu:     is the complete conversion matrix
+%   Cbu:    is the new variables covariance matrix
+%   Fbu:    is the information matrix for the new variable
+%   mse:    is the fit Mean Square Error
+%   dof:    degrees of freedom for the global estimation
+%   ppm:    number of svd parameters per measurements, provides also the
+%   number of independent combinations of parameters per each singular
+%   measurement. The coefficients of the combinations are then stored in Vu
+% 
+% 09-11-2010 L Ferraioli
+%       CREATION
+%
+% <a href="matlab:utils.helper.displayMethodInfo('matrix', 'linfitsvd')">Parameter Sets</a>
+%
+% VERSION:     $Id: linlsqsvd.m,v 1.2 2011/03/11 09:28:26 luigi Exp $
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+function  [a,Ca,Corra,Vu,bu,Cbu,Fbu,mse,dof,ppm] = linlsqsvd(varargin)
+  
+  
+  
+  %%% get input params
+  if isstruct(varargin{end})
+    kwnpars   = varargin{end};
+    if isnumeric(varargin{end-1})
+      sThreshold = varargin{end-1};
+      A = varargin{1:end-2};
+    else
+      A = varargin{1:end-1};
+      sThreshold = [];
+    end
+  else
+    kwnpars = [];
+    if isnumeric(varargin{end})
+      sThreshold = varargin{end};
+      A = varargin{1:end-1};
+    else
+      A = varargin{:};
+      sThreshold = [];
+    end
+  end
+  
+ 
+  %%% sort between one or multiple experiments
+  exps = struct;
+  
+  if isa(A(1),'ao') % one experiment
+    % Build matrices for lscov
+    C = A(1:end-1);
+    Y = A(end);
+
+    H = C(:).y;
+    y = Y.y;
+    exps.fitbasis = H;
+    exps.fitdata = y;
+  elseif isa(A(1),'matrix') % multiple experiments
+    % run over input objects and experiments
+    for jj=1:numel(A(1).objs)
+      C = [];
+      for ii=1:numel(A)-1
+        D = A(ii).objs(jj).y;
+        % willing to work with columns
+        if size(D,1)<size(D,2)
+          D = D.';
+        end
+        C = [C D];
+      end
+      y = A(end).objs(jj).y;
+      exps(jj).fitbasis = C;
+      exps(jj).fitdata = y;
+    end
+  else
+    error('Unknown input data type!')
+  end
+  
+  %%% do fit
+  if ~isempty(kwnpars) && isfield(kwnpars,'pos')
+    if ~isempty(sThreshold)
+      [a,Ca,Corra,Vu,bu,Cbu,Fbu,mse,dof,ppm] = utils.math.linfitsvd(exps,kwnpars,sThreshold);
+    else
+      [a,Ca,Corra,Vu,bu,Cbu,Fbu,mse,dof,ppm] = utils.math.linfitsvd(exps,kwnpars);
+    end
+  else
+    if ~isempty(sThreshold)
+      [a,Ca,Corra,Vu,bu,Cbu,Fbu,mse,dof,ppm] = utils.math.linfitsvd(exps,sThreshold);
+    else
+      [a,Ca,Corra,Vu,bu,Cbu,Fbu,mse,dof,ppm] = utils.math.linfitsvd(exps);
+    end
+  end
+  
+  
+  
+  
+end
+