Mercurial > hg > ltpda
diff m-toolbox/classes/@parfrac/parfrac.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/@parfrac/parfrac.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,524 @@ +% PARFRAC partial fraction representation of a transfer function. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% DESCRIPTION: PARFRAC partial fraction representation of a transfer function. +% +% R(1) R(2) R(n) +% H(s) = -------- + -------- + ... + -------- + K(s) +% s - P(1) s - P(2) s - P(n) +% +% SUPER CLASSES: ltpda_tf < ltpda_uoh < ltpda_uo < ltpda_obj +% +% CONSTRUCTOR: +% +% r = parfrac() - creates an empty parfrac object +% r = parfrac(res, poles, dir) - construct from residuals, poles +% and direct terms +% r = parfrac(..., 'name') - construct including name +% r = parfrac(..., iunits, ounits) - include input and output units +% r = parfrac(pl) - create a parfrac object from the +% description given in the parameter list. +% r = parfrac(pzm) - create a parfrac from a pzmodel. +% r = parfrac(rat) - create a parfrac from a rational TF. +% +% +% The poles can be specified in a array or a cell as a real or complex number. +% +% Example: r = parfrac([1 2+1i 2-1i], [6 1+3i 1-3i], []); +% +% <a href="matlab:utils.helper.displayMethodInfo('parfrac', 'parfrac')">Parameters Description</a> +% +% VERSION: $Id: parfrac.m,v 1.57 2011/10/25 11:50:55 luigi Exp $ +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +classdef parfrac < ltpda_tf + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Property definition % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + %---------- Public (read/write) Properties ---------- + properties + end + + %---------- Protected read-only Properties ---------- + properties (SetAccess = protected) + res = []; % residuals [R] + poles = []; % poles (real or complex numbers) [P] + pmul = []; % Represents the pole multiplicity + dir = 0; % direct terms [K] + end + + %---------- Private Properties ---------- + properties (GetAccess = protected, SetAccess = protected) + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Check property setting % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + methods + function set.res(obj, val) + if ~isnumeric(val) && ~isempty(val) + error('### The value for the property ''res'' must be a numeric array.'); + end + if size(val,1) == 1 + val = val.'; + end + obj.res = val; + end + function set.poles(obj, val) + if ~(isnumeric(val) || iscell(val)) && ~isempty(val) + error('### The value for the property ''poles'' must be a numeric array.'); + end + if size(val,1) == 1 + val = val.'; + end + obj.poles = val; + end + function set.dir(obj, val) + if ~isnumeric(val) && ~isempty(val) + error('### The value for the property ''dir'' must be a numeric array.'); + end + if isempty(val) + obj.dir = val; + end + if size(val,1) == 1 + val = val.'; + end + obj.dir = val; + end + function set.pmul(obj, val) + if ~isnumeric(val) && ~isempty(val) + error('### The value for the property ''pmul'' must be a numeric array.'); + end + if size(val,1) == 1 + val = val.'; + end + obj.pmul = val; + end + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Constructor % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + methods + function obj = parfrac(varargin) + + import utils.const.* + utils.helper.msg(msg.OMNAME, 'running %s/%s', mfilename('class'), mfilename); + + % Collect all parfract objects + [parfracs, invars, rest] = utils.helper.collect_objects(varargin(:), 'parfrac'); + + if isempty(rest) && ~isempty(parfracs) + % Do copy constructor and return + utils.helper.msg(msg.OPROC1, 'copy constructor'); + obj = copy(parfracs, 1); + for kk=1:numel(obj) + obj(kk).addHistory(parfrac.getInfo('parfrac', 'None'), [], [], obj(kk).hist); + end + return + end + + switch nargin + case 0 + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%% Zero inputs %%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + utils.helper.msg(msg.OPROC1, 'empty constructor'); + obj.addHistory(parfrac.getInfo('parfrac', 'None'), plist(), [], []); + + case 1 + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%% One inputs %%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + if ischar(varargin{1}) + %%%%%%%%%% pzm = parfract('foo.mat') %%%%%%%%%% + %%%%%%%%%% pzm = parfract('foo.xml') %%%%%%%%%% + utils.helper.msg(msg.OPROC1, 'constructing from file %s', varargin{1}); + obj = fromFile(obj, varargin{1}); + + elseif isstruct(varargin{1}) + %%%%%%%%%% r = parfrac(struct) %%%%%%%%%% + utils.helper.msg(msg.OPROC1, 'constructing from struct'); + obj = fromStruct(obj, varargin{1}); + + elseif isa(varargin{1}, 'rational') + %%%%%%%%%% r = parfrac(rational-object) %%%%%%%%%% + utils.helper.msg(msg.OPROC1, 'constructing from rational'); + obj = fromRational(obj, plist('rational', varargin{1})); + + elseif isa(varargin{1}, 'pzmodel') + %%%%%%%%%% r = parfrac(pzmodel-object) %%%%%%%%%% + utils.helper.msg(msg.OPROC1, 'constructing from pzmodel'); + obj = fromPzmodel(obj, plist('pzmodel', varargin{1})); + + elseif isa(varargin{1}, 'plist') + %%%%%%%%%% r = parfrac(plist) %%%%%%%%%% + pl = varargin{1}; + + % Selection of construction method + if pl.isparam('filename') + utils.helper.msg(msg.OPROC1, 'constructing from file %s', pl.find('filename')); + 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('res') || pl.isparam('poles') || pl.isparam('dir') + utils.helper.msg(msg.OPROC1, 'constructing from residuals/poles/direct'); + obj = fromResidualsPolesDirect(obj, pl); + + elseif pl.isparam('pzmodel') + utils.helper.msg(msg.OPROC1, 'constructing from pole/zero model'); + obj = fromPzmodel(obj, pl); + + elseif pl.isparam('rational') + utils.helper.msg(msg.OPROC1, 'constructing from rational object'); + obj = fromRational(obj, pl); + + elseif pl.isparam('built-in') + utils.helper.msg(msg.OPROC1, 'constructing from built-in model'); + obj = fromModel(obj, pl); + + elseif pl.isparam('Plist') + ipl = find(pl, 'Plist'); + obj = parfrac(ipl); + + else + obj.setObjectProperties(pl); + obj.addHistory(parfrac.getInfo('parfrac', 'None'), pl, [], []); + end + else + error('### Unknown single argument constructor.'); + end + + case 2 + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%%% Two inputs %%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if (isa(varargin{1}, 'database') || isa(varargin{1}, 'mpipeline.repository.RepositoryConnection')) && isnumeric(varargin{2}) + %%%%%%%%%% f = parfrac(<database-object>, [IDs]) %%%%%%%%%% + % parfrac(<database-object>, [IDs]) + utils.helper.msg(msg.OPROC1, 'retrieve from repository'); + obj = obj.fromRepository(plist('conn', varargin{1}, 'id', varargin{2})); + + elseif (isa(varargin{1}, 'parfrac') || isa(varargin{1}, 'rational')) && isa(varargin{2}, 'plist') && isempty(varargin{2}.params) + %%%%%%%%%% f = parfrac(parfrac-object, <empty plist>) %%%%%%%%%% + obj = parfrac(varargin{1}); + + elseif isa(varargin{1}, 'org.apache.xerces.dom.DeferredElementImpl') && ... + isa(varargin{2}, 'history') + %%%%%%%%%% obj = parfrac(DOM node, history-objects) %%%%%%%%%% + obj = fromDom(obj, varargin{1}, varargin{2}); + + elseif isa(varargin{1}, 'ltpda_uoh') && isa(varargin{2}, 'plist') + %%%%%%%%%%% parfrac(<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 = parfrac(varargin{2}); + else + obj = parfrac(varargin{1}); + end + else + obj = parfrac(varargin{2}); + end + elseif isnumeric(varargin{1}) && isnumeric(varargin{2}) + % r = parfrac(num, den) + utils.helper.msg(msg.OPROC1, 'constructing from residuals/poles/direct'); + pl = plist('res', varargin{1}, 'poles', varargin{2}); + obj = fromResidualsPolesDirect(obj, pl); + + else + error('### Unknown 2 argument constructor.'); + end + + case 3 + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%% Three inputs %%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + %%%%%%%%%% r = parfrac(num, den, dir) %%%%%%%%%% + utils.helper.msg(msg.OPROC1, 'constructing from residuals/poles/direct'); + pl = plist('res', varargin{1}, 'poles', varargin{2}, 'dir', varargin{3}); + obj = fromResidualsPolesDirect(obj, pl); + + case 4 + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%% Four inputs %%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + %%%%%%%%%% r = parfrac(num, den, dir, name) %%%%%%%%%% + utils.helper.msg(msg.OPROC1, 'constructing from residuals/poles/direct'); + pl = plist('res', varargin{1}, 'poles', varargin{2}, 'dir', varargin{3}, 'name', varargin{4}); + obj = fromResidualsPolesDirect(obj, pl); + + case 6 + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%%%% five inputs %%%%%%%%%%%%%%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%%%%%%%%% pzm = parfrac(res, poles, dir, name, iunits, ounits) %%%%%%%%%% + utils.helper.msg(msg.OPROC1, 'constructing from residuals/poles/direct'); + pl = plist('res', varargin{1}, 'poles', varargin{2}, 'dir', varargin{3}, ... + 'name', varargin{4}, ... + 'iunits', varargin{5}, 'ounits', varargin{6}); + obj = fromResidualsPolesDirect(obj, pl); + + otherwise + [parfracs, invars, rest] = utils.helper.collect_objects(varargin, 'parfrac'); + + %%% Do we have a list of PARFRAC objects as input + if ~isempty(parfracs) && isempty(rest) + obj = parfrac(parfracs); + else + error('### Unknown number of arguments.'); + end + end + + end % End constructor + + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Methods (protected) % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + methods (Access = protected) + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Methods (static) % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + methods (Static) + + function mdls = getBuiltInModels(varargin) + mdls = ltpda_uo.getBuiltInModels('parfrac'); + end + + function out = VEROUT() + out = '$Id: parfrac.m,v 1.57 2011/10/25 11:50:55 luigi Exp $'; + end + + function ii = getInfo(varargin) + ii = utils.helper.generic_getInfo(varargin{:}, 'parfrac'); + end + + function out = SETS() + out = [SETS@ltpda_uoh, ... + {'From Rational'}, ... + {'From Pzmodel'}, ... + {'From Residuals/Poles/Direct'}]; + end + + + function plout = getDefaultPlist(set) + persistent pl; + persistent lastset; + if exist('pl', 'var')==0 || isempty(pl) || ~strcmp(lastset, set) + pl = parfrac.buildplist(set); + lastset = set; + end + plout = pl; + end + + function out = buildplist(set) + + if ~utils.helper.ismember(lower(parfrac.SETS), lower(set)) + error('### Unknown set [%s]', set); + end + + out = plist(); + out = parfrac.addGlobalKeys(out); + out = buildplist@ltpda_uoh(out, set); + + + switch lower(set) + case 'from rational' + % rational + p = param({'rational','Rational transfer-function model object to design from.'}, {1, {rational}, paramValue.OPTIONAL}); + out.append(p); + % Iunits + p = param({'iunits','The input units of the model.'}, paramValue.EMPTY_STRING); + out.append(p); + + % Ounits + p = param({'ounits','The output units of the model.'}, paramValue.EMPTY_STRING); + out.append(p); + case 'from pzmodel' + % pzmodel + p = param({'pzmodel','Pole/zero model object to design from.'}, {1, {pzmodel}, paramValue.OPTIONAL}); + out.append(p); + % Iunits + p = param({'iunits','The input units of the model.'}, paramValue.EMPTY_STRING); + out.append(p); + + % Ounits + p = param({'ounits','The output units of the model.'}, paramValue.EMPTY_STRING); + out.append(p); + case 'from residuals/poles/direct' + + % res + p = param({'res','Residual terms.'}, paramValue.EMPTY_DOUBLE); + out.append(p); + + % Poles + p = param({'poles','Poles (real or complex numbers).'}, paramValue.EMPTY_DOUBLE); + out.append(p); + + % Dir + p = param({'dir','Direct terms.'}, paramValue.DOUBLE_VALUE(0)); + out.append(p); + % Iunits + p = param({'iunits','The input units of the model.'}, paramValue.EMPTY_STRING); + out.append(p); + + % Ounits + p = param({'ounits','The output units of the model.'}, paramValue.EMPTY_STRING); + out.append(p); + end + end % function out = getDefaultPlist(varargin) + + function obj = initObjectWithSize(n,m) + obj = parfrac.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 + + methods (Hidden = true) + varargout = attachToDom(varargin) + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Methods (public) % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + methods + varargout = char(varargin) + varargout = display(varargin) + varargout = copy(varargin) + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Methods (protected) % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + methods (Access = protected) + varargout = respCore(varargin) + varargout = fromStruct(varargin) + varargout = fromDom(varargin) + end + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Methods (private) % + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + methods (Access = private) + % Constructors + varargout = fromResidualsPolesDirect(varargin) + varargout = fromRational(varargin) + varargout = fromPzmodel(varargin) + end + +end % End classdef + +% From XML File +% ------------- +% +% Construct a parfrac by loading it from an XML file. +% +% 'filename' - construct a parfrac from a filename. +% [default: empty string] +% +% Example: plist('filename', 'parfrac1.xml') +% +% From MAT File +% ------------- +% +% Construct a parfrac by loading it from a MAT file. +% +% 'filename' - construct a parfrac from a filename. +% [default: empty string] +% +% Example: plist('filename', 'parfrac1.mat') +% +% +% From Repository +% --------------- +% +% Construct a parfrac by retrieving it from an LTPDA repository. +% +% 'Hostname' - the repository hostname. Only those objects which +% are parfracs are returned. +% [default: 'localhost']; +% +% Additional parameters: +% +% 'Database' - The database name [default: 'ltpda'] +% 'ID' - A vector of object IDs. [default: []] +% 'CID' - Retrieve all parfrac objects from a particular +% collection. +% 'Binary' - Set to 'yes' to retrieve from stored binary +% representation (not always available). +% +% From Rational +% ------------ +% +% Construct a parfrac TF from a rational TF +% +% 'rational' - the rational model to convert +% [default: empty rational object] +% +% Example: rat = rational([1 2 3], [4 5 6 7], 'my rational') +% plist('rational', rat) +% +% From Pzmodel +% ------------ +% +% Construct a parfrac TF from a pzmodel +% +% 'pzmodel' - the pzmodel to convert +% [default: empty pole/zero model (pzmodel)] +% +% Example: pzm = pzmodel(1, {1 2 3}, {4 5}) +% plist('pzmodel', pzm) +% +% From Residuals/Poles/Direct +% -------------------------------- +% +% Construct a parfrac from arrays of coefficients +% +% 'res' - vector of residuals [default: []] +% 'poles' - vector/cell of real or complex numbers [default: []] +% 'dir' - vector of direct terms [default: []] +% 'name' - name of model [default: 'None'] +% +% From Plist +% ---------- +% +% 'Plist' - construct from a plist. The value passed should be a plist +% object. [default: empty plist] +% +% Example: pzm = pzmodel(1, {1 2 3}, {4 5}) +% pl = plist('pzmodel', pzm) +% plist('PLIST', pl)