⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simplex.m

📁 此为频谱分析工具箱
💻 M
字号:
function [pout,deltapout,r2,ss,f,func_evals,kvg,ChiSq,v,fv]=simplex(x,ys,pin,func,wt,dp,niter,stol,last)% simplex : Simplex routine (see fmins matlab function)% FMINS uses a Nelder-Mead type simplex search method.% Syntax: [p,deltap,r2,rv,f,iter,kvg,ChiSq,v,fv]=%                   simplex(x,y,Pin,Func,{wt,dp,niter,stol,mode='normal'})%% INPUT:%  x,y (vect)    : data to be fitted.%  Pin (vect)    : initial values for parameter search.%  Func (string) : function name (between quotes), of the form 'f(x,p)'.%% OUTPUT:%  p (vect)      : final parameters.%  r2 (scalar)   : correlation coefficient for fit.%  deltap (v)    : sigma on parameters%  rv (scalar)   : residual variance.%  f (vect)      : function values at the end of fitting process.%  ChiSq         : Chi Squarred%%                            ---------------% OPTIONS IN:%  wt (s or v)   : statistical weights for error calculation (1/sqrt(y) is defualt).%  dp (s or v)   : variation window for parameters, 0 for fixed param (0.1 is default, 0 to fix param)%  niter (integ) : maximal number of iterations (20 is deualt).%  stol  (scal)  : tolerency on square error sum fractional improvement (0.1 is default).%  mode          : 'silent', 'min', 'normal' or 'verbose' (do plot)%% OPTIONS OUT:%  iter (integer): number of iterations processed.%  kvg (boolean) : convergence flag (1 if ok).%  v (matrix)    : set of parameters used in fit%  fv (vector)   : set of RV for each set in 'v'% EF 09.97 from numerical recipies in C and FMINS matlab function% argument processing -----------------------------------------------if nargin < 9, last = []; endif nargin < 8, stol = []; endif nargin < 7, niter = []; endif nargin < 6, dp = []; endif nargin < 5, wt = []; endif isempty(last)  last = 'normal';endif strcmp(last,'silent')  tmp = 0;elseif strcmp(last,'min')  tmp = 1;elseif strcmp(last,'verbose')  tmp = 3;else  tmp = 2;endif tmp>0  fprintf(1,'\nSimplex Multivariable Fit\n');endif isempty(dp)  dp=.1;  if (tmp>1)                            disp('dp = 0.1 (10 %) ');  endendif isempty(wt)  wt=1./sqrt(abs(ys+(ys == 0)));  if (tmp>1)    disp('using standard normalisation (1/sqrt(y))')  endend           % data weightsif isempty(niter)  niter=20;  if (tmp>1)    fprintf(1,'Iterations : %i\n',niter);  endend           % max nb of itersif isempty(stol)  stol=.1;  if (tmp>1)    fprintf(1,' Tolerancy : %g\n',stol);  endend           % tolerancyif length(wt) == 1  wt = wt * ones(length(ys),1);endnzerow = find(wt);zerow = find(wt == 0);if ~isempty(zerow)  if tmp>1    disp('Get selected points');  end  x = x(nzerow);  ys = ys(nzerow);  wt = wt(nzerow);end%change all vectors to columnsx=x(:);y=ys(:);wt=wt(:);pin=pin(:);dp=dp(:);% check data vectors- same length?m=length(y); n=length(pin); p=pin;[m1,m2]=size(x);if (m1~=m)  error('input(x)/output(y) data must have same number of rows ');endif (m > 10000)    warning('HUH ! That makes a lot of points ! I may crash during fit...');endif (m <= n)        disp('Warning : need to extend data...');        newm = ceil(n/m+1)*m;        newx = linspace(x(1), x(length(x)), newm);        newx = newx(:);        y = interpsp(x,y,newx);        wt = interpsp(x,wt,newx);        x=newx;        m = newm;endif (length(dp) == 1)  dp=dp*ones(n,1);end% interface/call to fmins --------------------------------------------------funfcn=func;xsav=x;ysav=y;x=pin;fixed=find(dp == 0);notfixed = (dp ~= 0);tol=dp;tol2=stol;% f=feval(funfcn,xsav,x); r=wt.*(ysav-f); f=r'*r;% FMINS  --------------------------------------------------n = prod(size(x));% Set up a simplex near the initial guess.xin = vect2column(x); % Force xin to be a column vectorv = xin;    % Place input guess in the simplex! (credit L.Pfeffer at Stanford)x(:) = v;f=vect2column(feval(funfcn,xsav,x)); r=wt.*(ysav-f); fv=r'*r;pbest=x;ssbest=fv;fbest=f;niter=niter*length(find(dp));tic% Following improvement suggested by L.Pfeffer at Stanfordusual_delta = tol;             % percent deltas for non-zero termszero_term_delta = tol/50;      % Even smaller delta for zero elements of xfor j = find(dp')   y = xin;   if y(j) ~= 0        y(j) = (1 + usual_delta(j))*y(j);   else        y(j) = zero_term_delta;   end%   y(fixed)=pin(fixed);   v = [v y];   x(:) = y; f = feval(funfcn,xsav,x); r=wt.*(ysav-f); f=r'*r;   fv = [fv  f];   y = xin;   if y(j) ~= 0        y(j) = (1 - usual_delta(j))*y(j);   else        y(j) = -zero_term_delta;   end%   y(fixed)=pin(fixed);   v = [v y];   x(:) = y; f = feval(funfcn,xsav,x); r=wt.*(ysav-f); f=r'*r;   fv = [fv  f];end[fv,j] = sort(fv);v = v(:,j);[np1,n] = size(v);n = n-1;func_evals = n+1;if tmp > 0disp('')disp(sprintf('*Beginning fit (max %d iterations)',niter));if tmp > 1disp('--------------------------------------')disp('Iteration  Time(s)  Residual Variance');fprintf(1,'   %3d      %6.2f   %8.3f %s\n', func_evals, toc, fv(1)/length(ysav),'initial  (best)');endendalpha = 1;  beta = 1/2;  gamma = 2;onesn = ones(1,n);ot = 2:n+1;on = 1:n;% Iterate until the diameter of the simplex is less than tol.while func_evals < niter    if max(abs(fv(1)-fv(ot))) <= tol2        break    end    % One step of the Nelder-Mead simplex algorithm    vbar = (sum(v(:,on)')/n)';    vr = (1 + alpha)*vbar - alpha*v(:,n+1);    vr(fixed)=pin(fixed);    x(:) = vr;    f = vect2column(feval(funfcn,xsav,x)); r=wt.*(ysav-f); fr=r'*r;    func_evals = func_evals + 1;    vk = vr;  fk = fr; how = 'reflect ';    if fr < fv(n)        if fr < fv(1)            ve = gamma*vr + (1-gamma)*vbar;            ve(fixed)=pin(fixed);            x(:) = ve;            f=vect2column(feval(funfcn,xsav,x)); r=wt.*(ysav-f); fe=r'*r;            func_evals = func_evals + 1;            if fe < fv(1)                vk = ve; fk = fe;                how = 'expand  ';            end        end    else        vt = v(:,n+1); ft = fv(n+1);        if fr < ft            vt = vr; ft = fr;        end        vc = beta*vt + (1-beta)*vbar;        vc(fixed)=pin(fixed);        x(:) = vc;        f=vect2column(feval(funfcn,xsav,x)); r=wt.*(ysav-f); fc=r'*r;        func_evals = func_evals + 1;        if fc < fv(n)            vk = vc; fk = fc;            how = 'contract';        else            for j = 2:n                v(:,j) = (v(:,1) + v(:,j))/2;                x(:) = v(:,j);                f=vect2column(feval(funfcn,xsav,x)); r=wt.*(ysav-f); fv(j)=r'*r;            end        func_evals = func_evals + n-1;        vk = (v(:,1) + v(:,n+1))/2;        vk(fixed)=pin(fixed);        x(:) = vk;        f=vect2column(feval(funfcn,xsav,x)); r=wt.*(ysav-f); fk=r'*r;        func_evals = func_evals + 1;        how = 'shrink  ';        end    end    v(:,n+1) = vk;    fv(n+1) = fk;    [fv,j] = sort(fv);    v = v(:,j);    iter=func_evals;    ss=sum(((f-ysav).*wt).^2/length(ysav));    if (tmp > 1) fprintf(1,'   %3d      %6.2f   %8.3f %s', iter, toc, ss,how); end    if (ss <= ssbest) pbest=x; ssbest=ss; fbest=f;  if (tmp>1) fprintf(1,' (best)'); end    end    if (tmp>1) fprintf(1,'\n'); endendx(:) = v(:,1);if func_evals>=niterendif func_evals==niter  if tmp>0    disp(' Getting best fit... ')  end  kvg=0;else  kvg=1;end% --------------------------------------------------% set return values%p=pbest;f=fbest;y=ysav;x=xsav;r=corrcoef(y.*wt,f.*wt);r2=r.*r';ss=sum(((f-ysav).*wt).^2/length(ysav));% now evaluates 'v' params dispersion near final solution : statistic evaluation in simplex% v is nparams columnssig2=std(v');sig = sig2.*notfixed';fv = fv/length(y); % get residual variancesif tmp>0  fprintf(1,'Best RV : %.3f - Worse RV : %.3f \n', min(fv),max(fv));end%-------- Work out Chi squared ------------------------v=length(y)-length(find(dp));   % # of degrees of freedom (#sel points - #free pars)ChiSq = sum( ((y-f).*wt).^2 )/v;pout = vect2column(p);deltapout = vect2column(sig);if (tmp>0)  disp( '* Least Square Estimates of Parameters')  disp('      value      sigma(+/-)')  disp([ pout deltapout ])  disp( '* Correlation Coefficient for fit R^2')  disp(r2)  disp( '* Residual Variance')  disp(ss);  disp('* Chi squared')  disp(ChiSq)endif (tmp>2)  fprintf(1,'Fit results sent to graph...\n');  title('Fit result');  xlabel('X'); ylabel('Y');  plot(x(:,1),y,x(:,1),f);  % plot commandendp=p';if (size(ys,1)==1)  f = f';end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -