diff m-toolbox/classes/@pest/pest.m @ 0:f0afece42f48

Import.
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Wed, 23 Nov 2011 19:22:13 +0100
parents
children a71a40911c27
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/m-toolbox/classes/@pest/pest.m	Wed Nov 23 19:22:13 2011 +0100
@@ -0,0 +1,551 @@
+% PEST constructor for parameter estimates (pest) class.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DESCRIPTION: PEST constructor for parameter estimates (pest) class.
+%
+% CONSTRUCTOR:
+%
+%       pe = pest()
+%       pe = pest(filename)
+%       pe = pest(plist-object)
+%       pe = pest(y, paramNames)
+%       pe = pest(y, paramNames, dy)
+%       pe = pest(y, paramNames, dy, cov)
+%       pe = pest(y, paramNames, dy, cov, chi2)
+%       pe = pest(y, paramNames, dy, cov, chi2, dof)
+%
+% INPUTS:
+%
+%       y          - best fit parameters
+%       paramNames - names of the parameters
+%       dy         - standard errors of the parameters
+%       cov        - covariance matrix of the parameters
+%       chi2       - reduced chi^2 of the final fit
+%       dof        - degrees of freedom
+%
+% <a href="matlab:utils.helper.displayMethodInfo('pest', 'pest')">Parameters Description</a>
+%
+% VERSION:     $Id: pest.m,v 1.33 2011/08/22 05:22:23 hewitson Exp $
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+classdef pest < ltpda_uoh
+  
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  %                            Property definition                            %
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  
+  %---------- Protected read-only Properties ----------
+  properties (SetAccess = protected, Dependent = true)
+  end
+  
+  %---------- Protected read-only Properties ----------
+  properties (GetAccess = public, SetAccess = protected)
+    dy                % standard errors of the parameters.
+    y      = [];      % best fit parameters
+    names  = {};      % names of the parameters, if any
+    yunits = unit.initObjectWithSize(1,0);  % the units of each parameter
+    pdf    = [];      % posterior probability distribution of the parameters
+    cov    = [];      % covariance matrix of the parameters
+    corr   = [];      % correlation matrix of the parameters
+    chi2   = [];      % reduced chi^2 of the final fit
+    dof    = [];      % degrees of freedom
+    chain  = [];      % monte carlo markov chain
+    models = [];      % models that were fit
+  end
+  
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  %                          Check property setting                           %
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  
+  methods
+    % y
+    function set.y(obj, val)
+      try
+        % The genericSet method sets the value with a cell-array
+        val = [val{:}];
+      end
+      if ~isnumeric(val) || (~isvector(val) && ~isempty(val))
+        error('### The value for the property ''y'' must be a numeric vector');
+      end
+      if ~isempty(val)
+        obj.y = reshape(val, [], 1);
+      else
+        obj.y = val;
+      end
+    end
+    % dy
+    function set.dy(obj, val)
+      try
+        % The genericSet method sets the value with a cell-array
+        val = [val{:}];
+      end
+      if ~isnumeric(val) || (~isvector(val) && ~isempty(val))
+        error('### The value for the property ''dy'' must be a numeric vector');
+      end
+      if ~isempty(val)
+        obj.dy = reshape(val, [], 1);
+      else
+        obj.dy = val;
+      end
+    end
+    % names
+    function set.names(obj, val)
+      if numel(val) == 1 && iscell(val{1})
+        val = val{1};
+      end
+      if isempty(val)
+        val = {};
+      end
+      if ~(iscell(val) || ischar(val))
+        error('### The value for the property ''names'' must be a cell of parameter names.');
+      end
+      if iscell(val)
+        obj.names = val;
+      else
+        obj.names = cellstr(val);
+      end
+    end
+    % yunits
+    function set.yunits(obj, val)
+      if numel(val) == 1 && iscell(val) && iscell(val{1})
+        val = val{1};
+      end
+      if isempty(val)
+        obj.yunits = unit.initObjectWithSize(size(val,1), size(val,2));
+      elseif ischar(val)
+        obj.yunits = unit(val);
+      elseif isa(val, 'unit')
+        obj.yunits = copy(val,1);
+      elseif iscell(val)
+        obj.yunits = unit(val{:});
+      else
+        error('### The yunits value must be a vector of unit-objects or a string');
+      end
+    end
+    % pdf
+    function set.pdf(obj, val)
+      try
+        % The genericSet method sets the value with a cell-array
+        val = [val{:}];
+      end
+      if ~isnumeric(val) || ndims(val) ~= 2
+        error('### The value for the property ''pdf'' must be a numeric matrix');
+      end
+      obj.pdf = val;
+    end
+    % cov
+    function set.cov(obj, val)
+      try
+        % The genericSet method sets the value with a cell-array
+        val = [val{:}];
+      end
+      if ~isnumeric(val) || ndims(val) ~= 2
+        error('### The value for the property ''Cov'' must be a numeric matrix');
+      end
+      obj.cov = val;
+    end
+    % corr
+    function set.corr(obj, val)
+      try
+        % The genericSet method sets the value with a cell-array
+        val = [val{:}];
+      end
+      if ~isnumeric(val) || ndims(val) ~= 2
+        error('### The value for the property ''Corr'' must be a numeric matrix');
+      end
+      obj.corr = val;
+    end
+    % chi2
+    function set.chi2(obj, val)
+      try
+        % The genericSet method sets the value with a cell-array
+        val = [val{:}];
+      end
+      if ~isnumeric(val) || (any(size(val) ~= [1 1]) && ~isempty(val))
+        error('### The value for the property ''chi2'' must be a single double');
+      end
+      obj.chi2 = val;
+    end
+    % dof
+    function set.dof(obj, val)
+      try
+        % The genericSet method sets the value with a cell-array
+        val = [val{:}];
+      end
+      if ~isnumeric(val) || (any(size(val) ~= [1 1]) && ~isempty(val))
+        error('### The value for the property ''dof'' must be a single double');
+      end
+      obj.dof = val;
+    end
+    % dof
+    function set.chain(obj, val)
+      try
+        % The genericSet method sets the value with a cell-array
+        val = [val{:}];
+      end
+      if ~isnumeric(val)
+        error('### The value for the property ''chain'' must be a double');
+      end
+      obj.chain = val;
+    end
+    
+    % models
+    function set.models(obj, val)
+      try
+        % The genericSet method sets the value with a cell-array
+        val = [val{:}];
+      end
+      if ~(isa(val, 'ltpda_uoh') || isempty(val))
+        error('### The value for the property ''models'' must be ltpda_uoh object');
+      end
+      if ~isempty(val)
+        obj.models = val;
+      else
+        obj.models = [];
+      end
+    end
+  end
+  
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  %                     Compute the Dependent properties                      %
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  
+  methods
+    %     function val = get.dy(obj)
+    %       val = sprintf('Please define a method which gets the dy from the object: %s', obj.name);
+    %     end
+  end
+  
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  %                                Constructor                                %
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  
+  methods
+    function obj = pest(varargin)
+      
+      import utils.const.*
+      utils.helper.msg(msg.OMNAME, 'running %s/%s', mfilename('class'), mfilename);
+      
+      % Collect all pest objects
+      [objs, dummy, rest] = utils.helper.collect_objects(varargin(:), 'pest');
+      
+      if isempty(rest) && ~isempty(objs)
+        % Do copy constructor and return
+        utils.helper.msg(msg.OPROC1, 'copy constructor');
+        obj = copy(objs, 1);
+        for kk=1:numel(obj)
+          obj(kk).addHistory(pest.getInfo('pest', 'None'), [], [], obj(kk).hist);
+        end
+        return
+      end
+      
+      switch nargin
+        case 0
+          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+          %%%%%%%%%%%%%%%%%%%%%%%%%%%%   no input   %%%%%%%%%%%%%%%%%%%%%%%%%%%*
+          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+          utils.helper.msg(msg.OPROC1, 'empty constructor');
+          obj.addHistory(pest.getInfo('pest', 'None'), plist(), [], []);
+          
+        case 1
+          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+          %%%%%%%%%%%%%%%%%%%%%%%%%%%   One input   %%%%%%%%%%%%%%%%%%%%%%%%%%%
+          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+          
+          if ischar(varargin{1})
+            %%%%%%%%%%   obj = pest('foo.mat')   %%%%%%%%%%
+            %%%%%%%%%%   obj = pest('foo.xml')   %%%%%%%%%%
+            utils.helper.msg(msg.OPROC1, 'constructing from file %s', varargin{1});
+            obj = fromFile(obj, varargin{1});
+            
+          elseif isstruct(varargin{1})
+            %%%%%%%%%%   obj = pest(struct)   %%%%%%%%%%
+            utils.helper.msg(msg.OPROC1, 'constructing from struct');
+            obj = obj.fromStruct(varargin{1});
+            
+          elseif isa(varargin{1}, 'plist')
+            %%%%%%%%%%  obj = pest(plist-object)   %%%%%%%%%%
+            
+            pl = varargin{1};
+            
+            if pl.isparam('filename')
+              utils.helper.msg(msg.OPROC1, 'constructing from file %s', varargin{1});
+              obj = fromFile(obj, pl);
+              
+            elseif pl.isparam('hostname') || pl.isparam('conn')
+              utils.helper.msg(msg.OPROC1, 'constructing from repository %s', pl.find('hostname'));
+              obj = obj.fromRepository(pl);
+              
+            elseif pl.isparam('built-in')
+              utils.helper.msg(msg.OPROC1, 'constructing from built-in model');
+              obj = fromModel(obj, pl);
+              
+            elseif pl.isparam('y')
+              utils.helper.msg(msg.OPROC1, 'constructing from values');
+              obj = obj.fromValues(pl);
+              
+            else
+              obj.setProperties(pl);
+              obj.addHistory(pest.getInfo('pest', 'None'), pl, [], []);
+            end
+            
+          elseif isnumeric(varargin{1})
+            %%%%%%%%%%   obj = pest(y)   %%%%%%%%%%
+            utils.helper.msg(msg.OPROC1, 'constructing from y');
+            obj.y = varargin{1};
+            pl = plist('y', varargin{1});
+            obj.fromValues(pl);
+            
+          else
+            error('### Unknown single argument constructor.');
+          end
+          
+        case 2
+          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+          %%%%%%%%%%%%%%%%%%%%%%%%%%%   two input   %%%%%%%%%%%%%%%%%%%%%%%%%%%
+          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+          if (isa(varargin{1}, 'database') || isa(varargin{1}, 'mpipeline.repository.RepositoryConnection')) && isnumeric(varargin{2})
+            %%%%%%%%%%  obj = pest(<database-object>, [IDs])   %%%%%%%%%%
+            obj = obj.fromRepository(plist('conn', varargin{1}, 'id', varargin{2}));
+            
+          elseif isnumeric(varargin{1}) && (iscell(varargin{2}) || ischar(varargin{2}))
+            %%%%%%%%%%   obj = pest(y, paramNames)   %%%%%%%%%%
+            utils.helper.msg(msg.OPROC1, 'constructing from y and param names');
+            pl = plist('y', varargin{1}, 'paramNames', varargin{2});
+            obj.fromValues(pl);
+            
+          elseif isa(varargin{1}, 'pest') && isa(varargin{2}, 'plist') && isempty(varargin{2}.params)
+            %%%%%%%%%%  obj = pest(pest, <empty-plist>)   %%%%%%%%%%
+            obj = pest(varargin{1});
+            
+          elseif isa(varargin{1}, 'org.apache.xerces.dom.DeferredElementImpl') && ...
+                 isa(varargin{2}, 'history')
+            %%%%%%%%%%   obj = pest(DOM node, history-objects)   %%%%%%%%%%
+            obj = fromDom(obj, varargin{1}, varargin{2});
+            
+          elseif isa(varargin{1}, 'ltpda_uoh') && isa(varargin{2}, 'plist')
+            %%%%%%%%%%%   obj = pest(<ltpda_uoh>-object, plist-object)   %%%%%%%%%%
+            % always recreate from plist
+            
+            % If we are trying to load from file, and the file exists, do
+            % that. Otherwise, copy the input object.
+            if varargin{2}.isparam('filename')
+              if exist(fullfile('.', find(varargin{2}, 'filename')), 'file')==2
+                obj = pest(varargin{2});
+              else
+                obj = pest(varargin{1});
+              end
+            else
+              obj = pest(varargin{2});
+            end
+            
+          else
+            error('### Unknown 2 argument constructor.');
+          end
+          
+        case 3
+          if  isnumeric(varargin{1})                       && ...
+              (iscell(varargin{2}) || ischar(varargin{2})) && ...
+              isnumeric(varargin{3})
+            %%%%%%%%%%   obj = pest(y, paramNames, dy)   %%%%%%%%%%
+            utils.helper.msg(msg.OPROC1, 'constructing from y, param names and dy');
+            pl = plist(...
+              'y',          varargin{1}, ...
+              'paramNames', varargin{2}, ...
+              'dy',         varargin{3});
+            obj.fromValues(pl);
+          else
+            error('### Unknown 3 argument constructor.');
+          end
+          
+        case 4
+          if  isnumeric(varargin{1})                       && ...
+              (iscell(varargin{2}) || ischar(varargin{2})) && ...
+              isnumeric(varargin{3})                       && ...
+              isnumeric(varargin{4})
+            %%%%%%%%%%   obj = pest(y, paramNames, dy)   %%%%%%%%%%
+            utils.helper.msg(msg.OPROC1, 'constructing from y, param names, dy and cov');
+            pl = plist(...
+              'y',          varargin{1}, ...
+              'paramNames', varargin{2}, ...
+              'dy',         varargin{3}, ...
+              'cov',        varargin{4});
+            obj.fromValues(pl);
+          else
+            error('### Unknown 4 argument constructor.');
+          end
+          
+        case 5
+          if  isnumeric(varargin{1})                       && ...
+              (iscell(varargin{2}) || ischar(varargin{2})) && ...
+              isnumeric(varargin{3})                       && ...
+              isnumeric(varargin{4})                       && ...
+              isnumeric(varargin{5})
+            %%%%%%%%%%   obj = pest(y, paramNames, dy)   %%%%%%%%%%
+            utils.helper.msg(msg.OPROC1, 'constructing from y, param names, dy, cov and chi2');
+            pl = plist(...
+              'y',          varargin{1}, ...
+              'paramNames', varargin{2}, ...
+              'dy',         varargin{3}, ...
+              'cov',        varargin{4}, ...
+              'chi2',       varargin{5});
+            obj.fromValues(pl);
+          else
+            error('### Unknown 5 argument constructor.');
+          end
+          
+        case 6
+          if  isnumeric(varargin{1})                       && ...
+              (iscell(varargin{2}) || ischar(varargin{2})) && ...
+              isnumeric(varargin{3})                       && ...
+              isnumeric(varargin{4})                       && ...
+              isnumeric(varargin{5})                       && ...
+              isnumeric(varargin{6})
+            %%%%%%%%%%   obj = pest(y, paramNames, dy)   %%%%%%%%%%
+            utils.helper.msg(msg.OPROC1, 'constructing from y, param names, dy, cov, chi2 and dof');
+            pl = plist(...
+              'y',          varargin{1}, ...
+              'paramNames', varargin{2}, ...
+              'dy',         varargin{3}, ...
+              'cov',        varargin{4}, ...
+              'chi2',       varargin{5}, ...
+              'dof',        varargin{6});
+            obj.fromValues(pl);
+          else
+            error('### Unknown 6 argument constructor.');
+          end
+          
+        otherwise
+          error('### Unknown number of arguments.');
+      end
+      
+    end % End constructor
+  end % End public methods
+  
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  %                              Methods  (Public, hidden)                    %
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  
+  methods (Hidden = true)
+    varargout = attachToDom(varargin)
+  end
+  
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  %                              Methods (protected)                          %
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  
+  methods (Access = protected)
+    varargout = fromStruct(varargin)
+    varargout = fromDom(varargin)
+  end
+  
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  %                               Methods (private)                           %
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  
+  methods (Access = private)
+    % Constructors
+    varargout = fromValues(varargin)
+    varargout = genericSet(varargin)
+  end
+  
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  %                            Methods (static)                               %
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  methods (Static)
+    
+    function mdls = getBuiltInModels(varargin)
+      mdls = ltpda_uo.getBuiltInModels('pest');
+    end
+    
+    function out = VEROUT()
+      out = '$Id: pest.m,v 1.33 2011/08/22 05:22:23 hewitson Exp $';
+    end
+    
+    function ii = getInfo(varargin)
+      ii = utils.helper.generic_getInfo(varargin{:}, 'pest');
+    end
+    
+    function out = SETS()
+      out = [SETS@ltpda_uoh, {'From Values'}];
+    end
+    
+    
+    function plout = getDefaultPlist(set)
+      persistent pl;
+      persistent lastset;
+      if exist('pl', 'var')==0 || isempty(pl) || ~strcmp(lastset, set)
+        pl = pest.buildplist(set);
+        lastset = set;
+      end
+      plout = pl;
+    end
+    
+    function out = buildplist(set)
+      
+      if ~utils.helper.ismember(lower(pest.SETS), lower(set))
+        error('### Unknown set [%s]', set);
+      end
+      
+      out = plist();
+      out = pest.addGlobalKeys(out);
+      out = buildplist@ltpda_uoh(out, set);
+      
+      switch lower(set)
+        case 'from values'
+          % y
+          p = param({'y','Best fit parameters'}, paramValue.EMPTY_DOUBLE);
+          out.append(p);
+          % parameter names
+          p = param({'paramNames','Names of the parameters'}, paramValue.EMPTY_CELL);
+          out.append(p);
+          % dy
+          p = param({'dy','Standard errors of the parameters'}, paramValue.EMPTY_DOUBLE);
+          out.append(p);
+          % cov
+          p = param({'cov','Covariance matrix of the parameters'}, paramValue.EMPTY_DOUBLE);
+          out.append(p);
+          % chi2
+          p = param({'chi2','Reduced chi^2 of the final fit'}, paramValue.EMPTY_DOUBLE);
+          out.append(p);
+          % dof
+          p = param({'dof','Degrees of freedom'}, paramValue.EMPTY_DOUBLE);
+          out.append(p);
+          % models
+          p = param({'models',['Models used for the fit in which the coefficients were calculated<br>' ...
+            'Please notice that the models need to be stored in a <tt>smodel</tt> object!']}, smodel);
+          out.append(p);
+          % pdf
+          p = param({'pdf','Probability density function, as output by MCMC methods'}, paramValue.EMPTY_DOUBLE);
+          out.append(p);
+          % yunits
+          p = param({'yunits','A cell-array of units for the parameters.'}, paramValue.EMPTY_CELL);
+          out.append(p);
+          
+      end
+    end % function out = getDefaultPlist(varargin)
+    
+    function obj = initObjectWithSize(n,m)
+      obj = pest.newarray([n m]);
+    end
+    
+  end % End static methods
+  
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  %                         Methods (static, private)                         %
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  
+  methods (Static, Access = private)
+  end % End static, private methods
+  
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  %                         Methods (static, hidden)                          %
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  
+  methods (Static = true, Hidden = true)
+    varargout = loadobj(varargin)
+    varargout = update_struct(varargin);
+  end
+  
+end