Mercurial > hg > ltpda
diff m-toolbox/classes/@matrix/fromCSD.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/@matrix/fromCSD.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,332 @@ +% FROMCSD Construct a matrix filter from cross-spectral density matrix +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% FUNCTION: fromCSD +% +% DESCRIPTION: Construct matrix filter from cross-spectral density. Such a +% filter can be used for multichannel noise generation in combination with +% the MultiChannelNoise constructor of the matrix class. +% +% +% CALL: a = fromCSD(a, pl) +% +% PARAMETER: pl: plist containing 'csd' +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function a = fromCSD(a, pli) + + VERSION = '$Id: fromCSD.m,v 1.8 2010/10/29 16:09:12 ingo Exp $'; + + % get AO info + iobj = matrix.getInfo('matrix', 'From CSD'); + + % Set the method version string in the minfo object + iobj.setMversion([VERSION '-->' iobj.mversion]); + + % Add default values + pl = parse(pli, iobj.plists); + + % Get parameters and set params for fit + csdm = find(pl, 'csd'); + if isa(csdm,'matrix') % get elements out of the input matrix + csdao = csdm.objs; + else + csdao = csdm; + end + fs = find(pl, 'fs'); + + target = lower(find(pl, 'targetobj')); % decide to perform s domain or z domain identification + % if target is parfrac output a matrix of parfarc objs (s domain + % identification) + % if target is miir output a matrix of filterbank parallel miir objects + % (z domain identification) + + usesym = lower(find(pl, 'UseSym')); + + if (fs == 0) && strcmpi(target,'miir') + error('### Please provide a valid sampling frequency for CSD constructor.'); + elseif isempty(fs) && strcmpi(target,'miir') + error('### Please provide a valid sampling frequency for CSD constructor.'); + end + + % get units for filters + tgiunit = find(pl,'iunits'); + tgounit = find(pl,'ounits'); + + params = struct(); + + params.Nmaxiter = find(pl, 'MaxIter'); + params.minorder = find(pl, 'MinOrder'); + params.maxorder = find(pl, 'MaxOrder'); + params.spolesopt = find(pl, 'PoleType'); + params.weightparam = find(pl, 'Weights'); + + % set the target output + if strcmpi(target,'miir') + params.TargetDomain = 'z'; + elseif strcmpi(target,'parfrac') + params.TargetDomain = 's'; + else + error('### Unknown option for ''targetobj''.'); + end + + % Tolerance for MSE Value + lrscond = find(pl, 'FITTOL'); + % give an error for strange values of lrscond + if lrscond<0 + error('### Negative values for FITTOL are not allowed. ') + end + % handling data + lrscond = -1*log10(lrscond); + % give a warning for strange values of lrscond + if lrscond<0 + warning('You are searching for a MSE lower than %s', num2str(10^(-1*lrscond))) + end + params.lrscond = lrscond; + + % Tolerance for the MSE relative variation + msevar = find(pl, 'MSEVARTOL'); + % handling data + msevar = -1*log10(msevar); + % give a warning for strange values of msevar + if msevar<0 + warning('You are searching for MSE relative variation lower than %s', num2str(10^(-1*msevar))) + end + params.msevar = msevar; + + if isempty(params.msevar) + params.ctp = 'chival'; + else + params.ctp = 'chivar'; + end + + if(find(pl, 'plot')) + params.plot = 1; + else + params.plot = 0; + end + + params.fs = fs; + params.dterm = 0; % it is better to fit without direct term + + % check if symbolic calculation is required + if strcmpi(usesym,'on') + params.usesym = 1; + elseif strcmpi(usesym,'off') + params.usesym = 0; + else + error('### Unknown option for ''UseSym''.'); + end + + % extracting csd + if numel(csdao)==1 % one dimensional psd + csd = csdao.y; + freq = csdao.x; + dim = 'one'; + else % multichannel system + dim = 'multi'; + [nn,mm] = size(csdao); + if nn~=mm + error('### CSD Matrix must be square. ') + end + freq = csdao.index(1).x; + for ii = 1:nn + for jj = 1:nn + tcsd = csdao.index(ii,jj).y; + % willing to work with columns + [aa,bb] = size(tcsd); + if aa<bb + tcsd = tcsd.'; + end + csd(ii,jj,:) = tcsd; + end + end + + end + + + % call csd2tf + % ostruct is a struct array whose fields contain the residues and poles + % of estimated TFs. Since the fit is porformed on the columns of the TF + % matrix, each element of the array contains the residues and poles + % corresponding to the functions on the given column of the TF matrix. + + %ostruct = utils.math.csd2tf(csd,freq,params); + + ostruct = utils.math.csd2tf2(csd,freq,params); + + + % the filter for each channel is implemented by the rows of the TF matrix + + switch dim + case 'one' + + switch target + case 'miir' + % --- filter --- + res = ostruct.res; + poles = ostruct.poles; + % construct a struct array of miir filters vectors + pfilts(numel(res),1) = miir; + for kk=1:numel(res) + ft = miir(res(kk), [ 1 -poles(kk)], fs); + ft.setIunits(unit(tgiunit)); + ft.setOunits(unit(tgounit)); + pfilts(kk,1) = ft; + clear ft + end + filt = filterbank(pfilts,'parallel'); + + a = matrix(filt); + + % Add history + a.addHistory(iobj, pl, [], [csdao(:).hist]); + + case 'parfrac' + res = ostruct.res; + poles = ostruct.poles; + + fbk = parfrac(res,poles,0); + fbk.setIunits(unit(tgiunit)); + fbk.setOunits(unit(tgounit)); + + a = matrix(fbk); + + % Add history + a.addHistory(iobj, pl, [], [csdm(:).hist]); + end + + + case 'multi' + + switch target + case 'miir' + % init filters array + %fbk(nn*nn,1) = filterbank; + %fbk = filterbank.newarray([nn nn]); + + for zz=1:nn*nn % run over system dimension + % --- get column filter coefficients --- + % each column of mres\mpoles are the coefficients of a given filter + clear res poles + res = ostruct(zz).res; + poles = ostruct(zz).poles; + + % construct a struct array of miir filters vectors + %ft(numel(res),1) = miir; + for kk=1:numel(res) + ft(kk,1) = miir(res(kk), [1 -poles(kk)], fs); + ft(kk,1).setIunits(unit(tgiunit)); + ft(kk,1).setOunits(unit(tgounit)); + end + + fbk(zz,1) = filterbank(ft,'parallel'); + clear ft + + end + + mfbk = reshape(fbk,nn,nn); + + a = matrix(mfbk); + + % % overide default name + % if strcmpi(pl.find('name'), 'None') + % pl.pset('name', sprintf('fromCSD(%s)', csdao.name)); + % end + % % overide default description + % if isempty(pl.find('description')) + % pl.pset('description', csdao.description); + % end + + % Add history + a.addHistory(iobj, pl, [], [csdao(:).hist]); + + case 'parfrac' + % init filters array + %fbk(nn*nn,1) = parfrac; + + for zz=1:nn*nn % run over system dimension + % --- get column filter coefficients --- + % each column of mres\mpoles are the coefficients of a given filter + clear res poles + res = ostruct(zz).res; + poles = ostruct(zz).poles; + + fbk(zz,1) = parfrac(res,poles,0); + fbk(zz,1).setIunits(unit(tgiunit)); + fbk(zz,1).setOunits(unit(tgounit)); + + end + + mfbk = reshape(fbk,nn,nn); + + a = matrix(mfbk); + + % % overide default name + % if strcmpi(pl.find('name'), 'None') + % pl.pset('name', sprintf('fromCSD(%s)', csdao.name)); + % end + % % overide default description + % if isempty(pl.find('description')) + % pl.pset('description', csdao.description); + % end + + % Add history + a.addHistory(iobj, pl, [], [csdao(:).hist]); + end + + end + + % Set properties from the plist + warning('off', utils.const.warnings.METHOD_NOT_FOUND); + % remove parameters we already used + pl_set = copy(pl,1); + if pl_set.isparam('csd') + pl_set.remove('csd'); + end + if pl_set.isparam('fs') + pl_set.remove('fs'); + end + if pl_set.isparam('targetobj') + pl_set.remove('targetobj'); + end + if pl_set.isparam('UseSym') + pl_set.remove('UseSym'); + end + if pl_set.isparam('iunits') + pl_set.remove('iunits'); + end + if pl_set.isparam('ounits') + pl_set.remove('ounits'); + end + if pl_set.isparam('MaxIter') + pl_set.remove('MaxIter'); + end + if pl_set.isparam('MinOrder') + pl_set.remove('MinOrder'); + end + if pl_set.isparam('MaxOrder') + pl_set.remove('MaxOrder'); + end + if pl_set.isparam('PoleType') + pl_set.remove('PoleType'); + end + if pl_set.isparam('Weights') + pl_set.remove('Weights'); + end + if pl_set.isparam('FITTOL') + pl_set.remove('FITTOL'); + end + if pl_set.isparam('MSEVARTOL') + pl_set.remove('MSEVARTOL'); + end + if pl_set.isparam('plot') + pl_set.remove('plot'); + end + a.setProperties(pl_set); + warning('on', utils.const.warnings.METHOD_NOT_FOUND); + + +end + +