pdsco.m

来自「% Atomizer Main Directory, Version .802 」· M 代码 · 共 1,246 行 · 第 1/4 页

M
1,246
字号
   tlin = - z - pdsAAA'*y;else   rlin =   b - feval( Aname, 1, m, n, x );   tlin = - z - feval( Aname, 2, m, n, y );end%------------------------------------------------------------------------% Initialize mu% and the nonlinear residuals  r    = rlin - delta^2*y,%                              t    = tlin + gamma^2*x + grad,%                              v    = mu*e - X*z.%% 09 May 1998: Initialize mu to a fraction of x'z/n (as others do).% 14 May 1998: Make delta decrease with mu.% 03 Jun 1998: Keep delta <= delta0.% 13 Jun 1998: Keep mu >= mulast.% 14 Apr 2000: mufirst = mu0 * (x'z)/n is too small if initial r, t are big.%              Revert to balancing two parts of rhs of KKT system:%              (  b - Ax   )     ( 0  )     (  r  )%              (g - A'y - z)  =  ( 0  )  +  (  t  ).%              (mu e  -  Xz)     (mu e)     (- Xz )%% 25 Jan 2001: Now that b and obj are scaled (and hence x,y,z),%              we should be able to use an absolute value: mufirst = mu0;%              But 0.1 worked poorly on StarTest1 (with x0min = z0min = 0.1).%% 29 Jan 2001: We might as well use mu0 = x0min * z0min;%              so that most variables are centered after a warm start.%------------------------------------------------------------------------r       = rlin - delta2*y;t       = tlin + grad;           % grad includes gamma2*xXz      = x.*z;%f      = norm([r; t; Xz]);      % Original norm.%f      = norm([r; t; Xz],1);    % Probably should have been that.%mufirst= mu0 * f / n;           % Replaces  mufirst = mu0 * (sum(Xz) / n);mufirst = mu0;                   % Absolute value.mulast  = 0.1 * opttol;mulast  = min( mulast, mufirst );mu      = mufirst;LSdamp  = max( sqrt(mu), delta );LSdamp  = min( LSdamp  , delta0);LSdamp2 = LSdamp^2;r       = rlin - LSdamp2*y;      % 25 Jan 2001: Should have been there earlier.v       = mu   - Xz;f       = norm([r; t; v]);       % f = merit function for the linesearch.% Initialize other things.PDitns    = 0;converged = 0;atol      = atol1;atol2     = max( atol2, atolmin );%  Iteration log.stepx   = 0;stepz   = 0;nf      = 0;itncg   = 0;nfail   = 0;head1   = '\n\nItn   mu stepx stepz  Pinf  Dinf';head2   = '  Cinf   Objective    nf  center';if direct, head3 = ''; else head3 =['  atol ' solver ' Inexact']; endfprintf([ head1 head2 head3 ])mininf  = 1e-99;regterm = gamma2 * (x'*x)  +  LSdamp2 * (y'*y);objreg  = obj  +  0.5 * regterm;objtrue = objreg * theta;maxXz   = max(Xz);minXz   = min(Xz);center  = maxXz / minXz;Pinf    = norm(r,inf);   Pinf = max( Pinf, mininf );Dinf    = norm(t,inf);   Dinf = max( Dinf, mininf );Cinf    = maxXz;         Cinf = max( Cinf, mininf );fprintf('\n%3g                 ', PDitns       )fprintf('%6.1f%6.1f' , log10(Pinf), log10(Dinf))fprintf('%6.1f%15.7e', log10(Cinf), objtrue    )fprintf('   %8.1f'   , center                  )if kminor   fprintf('\n\nStart of first minor itn...\n')   keyboardend%-----------------------------------------------------------------------% Main loop.%-----------------------------------------------------------------------while ~converged   PDitns = PDitns + 1;%  x1 = x;  y1 = y;  z1 = z;  % Save for debugging at end of iteration.%  t1 = t;  r1 = r;  v1 = v;% 31 Jan 2001: Set atol according to actual progress, a la Inexact Newton.% 07 Feb 2001: 0.1 not small enough for Satellite problem.  Try 0.01.   r3norm = max([Pinf  Dinf  Cinf]);   atol   = min([atol r3norm*0.01]);   atol   = max([atol  atolmin   ]);%-----------------------------------------------------------------------%  Define a damped Newton iteration for solving%     ( r, t, v ) = 0,%  keeping  x, z > 0.  We eliminate dz%  to obtain the system%%     [-H   A'] [ dx ] = [ w ],    d2I = delta^2 I,   w = t - v./x;%     [ A  d2I] [ dy ] = [ r ]%%  which is equivalent to%%     [-dI  DA'] [ s  ] = [  Dw   ],    dI = delta I,%     [ AD  dI ] [ dy ] = [r/delta]     D  = H^{-1/2),  dx = delta D s,%%  and also equivalent to the least-squares problem%%     min || [ DA']dy  -  [  Dw   ] ||.                                (*)%         || [ dI ]       [r/delta] ||%% 17 Mar 1998: We solve the latter as the damped least-squares problem%%     min || [ DA']dybar  -  [D wbar] ||,  wbar = w - (A'r)/delta^2,   (**)%         || [ dI ]          [  0   ] ||     dy = dybar + r/delta^2,%%    to allow lsqr to work with the smaller operator DA'.%% 30 Mar 1998: LSproblem = 1 or 2 selects (*) or (**) respectively.%              (*)  seems safer if delta is small, but%              (**) is more efficient (and safe) if delta = 1, say.%% 31 Mar 1998: LSproblem = 11 or 12 selects alternative LS problem%%     min || [ AD ]s  -  [    r    ] ||,     dx = Ds,                 (***)%         || [ dI ]      [-delta Dw] ||      dy = (r - Adx) / delta^2%% and associated damped LS problem:%%     min || [ AD ]sbar  -  [ rbar ] ||,      s = sbar - Dw,         (****)%         || [ dI ]         [  0   ] ||    rbar = r + AD^2 w.%% 06 Apr 1998: LSproblem = 21 selects equivalent LS problem%%     min || [    A     ]dx  -  [    r    ] ||,                     (*****)%         || [delta Dinv]       [-delta Dw] ||     dy = (r - Adx) / delta^2%-----------------------------------------------------------------------   H       = Q  +  z./x;   w       = t  -  v./x;   Hinv    = 1 ./ H;   D       = sqrt(Hinv);   pdsDDD1 = D;   rw      = [explicit  LSproblem  LSmethod  LSdamp m n 0];  % Passed to LSQR.   if LSproblem == 1      %-----------------------------------------------------------------      %  Solve (*) for dy.      %-----------------------------------------------------------------      Dw   = D.*w;      if direct         DD   = sparse( 1:n, 1:n, D, n, n );         AD   = AAA*DD;         if useChol            d2I  = LSdamp2 * em;            d2I  = sparse( 1:m, 1:m, d2I, m, m );            ADDA = AD * AD'  +  d2I;            if PDitns==1,  P = symmmd(ADDA);  end  % Do ordering only once.            [R,indef] = chol(ADDA(P,P));            if indef               fprintf('\n\n   chol says AD^2A'' is not positive definite')               break            end            rhs  = r  +  AAA * (Hinv.*w);%           dy   = ADDA \ rhs;            dy   = R \ (R' \ rhs(P));   dy(P) = dy;         	 else % useQR            dI   = LSdamp * em;            rhs  = [ Dw; r/LSdamp ];            dy   = [ AD'; diag(dI) ] \ rhs;         end         Ady  = AAA'*dy;         dx   = Hinv .* (Ady - w);         Adx  = AAA*dx;      else % Iterative solve using LSQR.         rhs     = [ Dw; r/LSdamp ];         damp    = 0;         if explicit            % A is a sparse matrix.	    precon     = true;	    if precon    % Construct diagonal preconditioner for LSQR	       DD      = sparse( 1:n, 1:n, D, n, n );	       AD      = pdsAAA*DD;	       AD2     = AD.^2;	       wD      = sum( (AD2') )';   % Sum of squares of each row of AD	       wD      = sqrt( wD + LSdamp2 );	       pdsDDD2 = 1 ./ wD;	    end         else                   % A is an operator	    precon    = false;  	 end	 rw(7)        = precon;         info.atolmin = atolmin;	 info.r3norm  = f;    % Must be the 2-norm here.	 [ dy, istop, itncg, outfo ] = ...	     pdsxxxlsqr( nb, m, 'pdsxxxlsqrmat', Aname, rw, rhs, damp, ... 	                 atol, btol, conlim, itnlim, show, info );	 if precon, dy = pdsDDD2 .* dy; end	 if istop == 3  |  istop == 7   % conlim or itnlim	    fprintf('\n    LSQR stopped early:  istop = %3d', istop)	 end	 atolold = outfo.atolold;	 atol    = outfo.atolnew;	 r3ratio = outfo.r3ratio;         Ady = feval( Aname, 2, m, n, dy );   % A'dy	 dx  = Hinv .* (Ady - w);             %   dx	 Adx = feval( Aname, 1, m, n, dx );   % A dx      end % LSproblem 1      else      disp( 'This LSproblem not yet implemented' )      break   end%-----------------------------------------------------------------------   CGitns = CGitns + itncg;%-----------------------------------------------------------------------%  dx and dy are now known.  Get dz.%  dz  = xinv.*(v - z.*dx);  % is the classical formula -- no good???%-----------------------------------------------------------------------   if LSproblem ~= 31      dz  = t - Ady + Q.*dx;   end%-----------------------------------------------------------------------%   Find the maximum step.%-----------------------------------------------------------------------   stepx = 1.0e+20;   stepz = 1.0e+20;   blocking  =  find( dx < 0 );   if length( blocking ) > 0      steps  =  x(blocking) ./ (- dx(blocking));      stepx  =  min( steps );   end   blocking  =  find( dz < 0 );   if length( blocking ) > 0      steps  =  z(blocking) ./ (- dz(blocking));      stepz  =  min( steps );   end   stepxmax =  stepx;   stepzmax =  stepz;   stepx    =  min( steptol * stepx, 1 );   stepz    =  min( steptol * stepz, 1 );%-----------------------------------------------------------------------%  Optimize stepx and stepz (Byung's 1-D search).%-----------------------------------------------------------------------   if (stepx > stepz)      normAdx2   = Adx'*Adx;      rtAdx      = r'*Adx;      dxz        = dx .* z;      normdxz2   = dxz'*dxz;      gammadx    = gamma2 * dx;      gammadx2   = gammadx' * gammadx;      vtdxz      = v'*dxz;      ttgammadx  = t'*gammadx;      numerator  = rtAdx + vtdxz - ttgammadx;      denominat  = normAdx2 + normdxz2 + gammadx2;      alphax     = (1 - stepz) * numerator / denominat;      stepxmax   = stepz + alphax;      stepxmax   = max(stepxmax, stepz);      stepx      = min(stepxmax, stepx);   elseif (stepx < stepz)      normdy2    = dy'*dy;      rtdy       = r'*dy;      xdz        = x .* dz;      normxdz2   = xdz'*xdz;      vtxdz      = v'*xdz;      Adydz      = Ady + dz;      ttAdydz    = t'*Adydz;      Adydz2     = Adydz'*Adydz;      numerator  = rtdy + vtxdz + ttAdydz;      denominat  = normdy2 + normxdz2 + Adydz2;      alphaz     = (1 - stepx) * numerator / denominat;      stepzmax   = stepx + alphaz;      stepzmax   = max(stepzmax, stepx);      stepz      = min(stepzmax, stepz);   end

⌨️ 快捷键说明

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