Mercurial > hg > ltpda
diff m-toolbox/classes/+utils/@math/startpoles.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/startpoles.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,179 @@ +% STARTPOLES defines starting poles for fitting procedures ctfit, dtfit. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% DESCRIPTION +% +% Defines the starting poles for the fitting procedure with ctfit or +% dtfit. Starting poles definition process is different for s-domain +% and z-domain. +% s-domain identification: +% Starting poles can be real or complex in conjugate couples. Real +% poles are chosen on the [-2*pi*f(1),-2*pi*f(end)] intervall. Complex poles can +% be defined with the real and imaginary parts logspaced or linespaced +% on the intervall [2\pi f(1),2\pi f(end)]. Ratio between real and +% imaginary part can be setted by the user. +% z-domain identification: +% Starting poles can be real or come in complex conjugate couples. Real +% poles are chosen on the [-1,1] intervall. Complex poles are +% chosen inside the unit circle as: +% \alfa e^{j\pi\theta} +% where \theta is linespaced inside the intervall [0,2\pi]. In this +% case two different methods are used: the first method define angles +% as \theta = linspace(0,pi,N/2+1), then take out the first element and +% construct the complex conjugate couples. If N is odd the first +% element is added as real pole. With this method the last two +% conjugates poles have a real part very similar to that of the real +% pole. This may generate problems so a second method is implemented in +% which the angle are generated as \theta = linspace(0,pi,N/2+2). Then +% the first and the last elements of the set are taken out and the +% first element is used only for N odd. The last element instead is +% never used. This allow to have well distributed poles on the unit +% circle. The amplitude parameter \alfa can be set by the user. +% +% CALL: +% +% spoles = startpoles(order,f,params) +% +% INPUT: +% +% order: is the function order, ie. the number of desired poles +% f: is the frequency vector in Hz +% params: is a struct with the setting parameters +% +% params.type = 'CONT' --> Output a set of poles for s-domain +% identification +% params.type = 'DISC' --> Output a set of poles for z-domain +% identification +% +% params.spolesopt = 1 --> generate linear spaced real poles on +% the intervall [-2*pi*f(1),-2*pi*f(end)] for s-domain and [-1,1] for z-domain. +% params.spolesopt = 2 --> in case of s-domain generates logspaced +% complex conjugates poles. In case of z-domain generates complex +% conjugates poles with \theta = linspace(0,pi,N/2+1). +% params.spolesopt = 3 --> in case of s-domain generates linespaced +% complex conjugates poles. In case of z-domain generates complex +% conjugates poles with \theta = linspace(0,pi,N/2+2). We advice to +% make use of this option for z-domain identification. +% +% params.pamp = # --> s-domain: set the ratio \alfa/\beta between +% poles real and imaginary parts. Adviced value is 0.01. +% params.pamp = # --> z-domain: set the amplitude of the poles. +% Adviced value is 0.98. +% +% OUTPUT: +% +% spoles: is the set of starting poles +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% VERSION: $Id: startpoles.m,v 1.6 2010/04/29 09:00:00 luigi Exp $ +% HISTORY: 08-10-2008 L Ferraioli +% Creation +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function spoles = startpoles(order,f,params) + + % Default input struct + defaultparams = struct('spolesopt',1, 'type','CONT', 'pamp', 0.98); + + names = {'spolesopt', 'type', 'pamp'}; + + % collecting input and default params + if ~isempty(params) + for jj=1:length(names) + if isfield(params, names(jj)) + defaultparams.(names{1,jj}) = params.(names{1,jj}); + end + end + end + + type = defaultparams.type; + spolesopt = defaultparams.spolesopt; + pamp = defaultparams.pamp; + + N = order; + + % switching between continuous and discrete + switch type + case 'CONT' + switch spolesopt + + case 0 + disp(' Using external starting poles') + + case 1 % real starting poles + spoles = -1.*2.*pi.*linspace(f(1),f(end),N).'; + + case 2 % complex logspaced starting poles + if f(1)==0 + bet=2.*pi.*logspace(log10(f(2)),log10(f(end)),N/2); + else + bet=2.*pi.*logspace(log10(f(1)),log10(f(end)),N/2); + end + spoles=[]; + for n=1:length(bet) + alf=-bet(n)*pamp; + spoles=[spoles;(alf-1i*bet(n));(alf+1i*bet(n))]; + end + if (N-2*floor(N/2)) ~= 0 +% rpl = rand(1,1); +% if rpl > 0 +% rpl = -1*rpl; +% end + rpl = -1; + spoles = [rpl; spoles]; + end + + case 3 % complex linspaced starting poles + bet=linspace(2*pi*f(1),2*pi*f(end),N/2); + spoles=[]; + for n=1:length(bet) + alf=-bet(n)*pamp; + spoles=[spoles;(alf-1i*bet(n));(alf+1i*bet(n))]; + end + if (N-2*floor(N/2)) ~= 0 +% rpl = rand(1,1); +% if rpl > 0 +% rpl = -1*rpl; +% end + rpl = -1; + spoles = [rpl; spoles]; + end + + end + case 'DISC' + switch spolesopt + + case 0 + disp(' Using external starting poles') + + case 1 % real starting poles + spoles = linspace(-0.99,0.99,N).'; + + case 2 % complex starting poles + ang = linspace(0,pi,N/2+1); + spoles=[]; + for nn=2:length(ang) + spoles=[spoles; exp(1i*ang(nn)); exp(-1i*ang(nn))]; % Taking complex conjugate pairs on the unit circle + end + if (N-2*floor(N/2)) ~= 0 + rpl = exp(1i*ang(1)); + spoles = [rpl; spoles]; + end + spoles = spoles.*pamp; % shifting starting ?poles a little inside the unit circle + + case 3 % complex starting poles + ang = linspace(0,pi,N/2+2); + spoles=[]; + for nn=2:length(ang)-1 + spoles=[spoles; exp(1i*ang(nn)); exp(-1i*ang(nn))]; % Taking complex conjugate pairs on the unit circle + end + if (N-2*floor(N/2)) ~= 0 + rpl = exp(1i*ang(1)); + spoles = [rpl; spoles]; + end + spoles = spoles.*pamp; % shifting starting ?poles a little inside the unit circle + + end + + end + +end \ No newline at end of file