📄 sbls.m
字号:
function [x,k,timev] =sbls (A,b,l,u,rep,opt)%%SBLS Sparse solver for linear least squares with box constrints.% %Z%%M% Version %I% %G%% Mikael Lundquist, Linkoping University.% e-mail: milun@math.liu.se%% x = sbls(A,b,l,u,rep,opt) solves the least squares problem% min || Ax-b || , subject to l <= x <= u% x 2% A m-by-n sparse matrix, rank(A) <= n.% b m-by-1 vector% u,l upper and lower bound, n-by-1 vector% rep = 1 produces a report in each iteration (optional)%% opt = 0 uses normal equations (CSNE) instead of QR factorization% when solving the sub problems (optional) nu = 3;if nargin < 6, opt = 0;endif nargin < 5, rep = 0;endif rep==1, fprintf(' Iter ||x+s-u|| ||AT...|| gap\n')end% -- Initiation [m,n] = size(A); if length(l)==1, l=ones(n,1)*l; end if length(u)==1, u=ones(n,1)*u; end % - Compute column minimum degree ordering for sparse factorization q = colmmd(A); A = A(:,q); if (opt == 0),% - Form matrix of normal equations ATA = A'*A; end u = u(q); l = l(q); if nargin == 7, xexact = xexact(q); end% - Shift to make the lower bounds equal to zero u = u - l; b = b - A*l;% - Definition of the starting point (x0,w0) x = u/2; s = u-x; res = A'*(A*x-b); v = abs(res); y = v-res;% ind=(res>0);% v(ind)=res(ind);% y(~ind)=-res(~ind);clear res% - Computation of the initial gap gap = y'*s+x'*v; stop1 = 0; stop2 = 0; oldgap = gap*2;% --- Start interior point iterations k = 0; while ((abs(gap) > n*1.0e-18) | (stop1 > n*1.0e-12) | (stop2 > n*1.0e-12)) k = k + 1; if k==100,break;end, if (oldgap/gap<1) & (gap<1e-3), fprintf('sbls can not converge.'); break; end oldgap=gap; % --- Predictor phase % - Computation of the right-hand side and deltax vxinv = v./x; ysinv = y./s; d2 = vxinv + ysinv; d= sqrt(d2); bd1 = b-A*x; bd2 = (-y + ysinv.*(u-x))./d; bd = [bd1 ; bd2];% - Computation of the damped matrix and its Cholesky factor AD = [A ; sparse(1:length(d),1:length(d),d)]; if (opt == 0), R = chol(ATA + sparse(1:length(d2),1:length(d2),d2)); else R=qr(AD,0); end dx = csolve(AD,R,bd); % - Computation of ds, dv and dy ds = (u - x - s) - dx; dv = - v - vxinv.*dx; dy = - y - ysinv.*ds;% - Computation of the step theta theta = 0.9999995 *dth(x,dx,s,ds,v,dv,y,dy);% --- Corrector phase % - Computation of mu and some useful vectors tempgap=(x+theta*dx)'*(v+theta*dv) +(s+theta*ds)'*(y+theta*dy); mu = (tempgap/gap)^nu*(gap/(2*n)); mue = mu*ones(n,1); c1 = (mue - dx.*dv)./x; c2 = (mue - ds.*dy)./s;% - Computation of the right-hand side and dx bd2 = bd2 + (c1 - c2)./d; bd = [bd1 ; bd2 ]; dx = csolve(AD,R,bd);% - Computation of ds, dv and dy ds = (u - x - s) - dx; dv = c1 - v - vxinv.*dx; dy = c2 - y - ysinv.*ds;% - Computation of the step theta theta = 0.9999995 *dth(x,dx,s,ds,v,dv,y,dy);% - Update of x, s, v and y x = x + theta * dx; s = s + theta * ds; v = v + theta * dv; y = y + theta * dy;% - Computation of the stopping criteria and report stop1 = norm (x + s - u); stop2 = norm (A'*(A*x - b) + y - v); gap = x'*v + s'*y; if (rep == 1), fprintf(' %12e %12e %12e\n',stop1,stop2,gap); end end %while% - Shift the solution back x(q) = x + l;% end function sbls% --------------------------------------------------------------------------------function teta=dth(x,deltax,y,deltay,s,deltas,v,deltav)%dth Help function to sbls% %Z%%M% Version %I% %G%% Mikael Lundquist, Linkoping University.% e-mail: milun@math.liu.se i=find(deltax <-eps);if ~isempty(i), tetax=min(-x(i)./deltax(i));endi=find(deltay <-eps);if ~isempty(i), tetay=min(-y(i)./deltay(i));endi=find(deltas <-eps);if ~isempty(i), tetas=min(-s(i)./deltas(i));endi=find(deltav <-eps);if ~isempty(i), tetav=min(-v(i)./deltav(i));endteta=min([tetax tetay tetas tetav]);if isempty(teta),teta=0,else teta=min([teta 1]);end% --------------------------------------------------------------------------------function x = csolve(A,R,b,it)%CSOLVE Computes the CSNE solution to a least squares problem.% %Z%%M% Version %I% %G%% Mikael Lundquist, Linkoping University.% e-mail: milun@math.liu.se%% x=csolve(A,R,b) computes the CSNE solution to min||Ax-b||% by R'*Rx=A'b with one step of iterative refinement. [m,n] = size(A); x = zeros(n,1);% - sne solution ATb=(b'*A)'; y=R'\ATb; x=R\y;% - Iterative refinement (not used) for i=1:-1, r=b-A*x; y=R'\(A'*r); dx=R\y; x=x+dx; end% end of function solve
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -