You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
5.9 KiB
212 lines
5.9 KiB
%-------------------------------------------------------------
|
|
% This is the file subsolv.m
|
|
%
|
|
% Version Dec 2006.
|
|
% Krister Svanberg <krille@math.kth.se>
|
|
% Department of Mathematics, KTH,
|
|
% SE-10044 Stockholm, Sweden.
|
|
%
|
|
function [xmma,ymma,zmma,lamma,xsimma,etamma,mumma,zetmma,smma] = ...
|
|
subsolv(m,n,epsimin,low,upp,alfa,beta,p0,q0,P,Q,a0,a,b,c,d);
|
|
%
|
|
% This function subsolv solves the MMA subproblem:
|
|
%
|
|
% minimize SUM[ p0j/(uppj-xj) + q0j/(xj-lowj) ] + a0*z +
|
|
% + SUM[ ci*yi + 0.5*di*(yi)^2 ],
|
|
%
|
|
% subject to SUM[ pij/(uppj-xj) + qij/(xj-lowj) ] - ai*z - yi <= bi,
|
|
% alfaj <= xj <= betaj, yi >= 0, z >= 0.
|
|
%
|
|
% Input: m, n, low, upp, alfa, beta, p0, q0, P, Q, a0, a, b, c, d.
|
|
% Output: xmma,ymma,zmma, slack variables and Lagrange multiplers.
|
|
%
|
|
een = ones(n,1);
|
|
eem = ones(m,1);
|
|
epsi = 1;
|
|
epsvecn = epsi*een;
|
|
epsvecm = epsi*eem;
|
|
x = 0.5*(alfa+beta);
|
|
y = eem;
|
|
z = 1;
|
|
lam = eem;
|
|
xsi = een./(x-alfa);
|
|
xsi = max(xsi,een);
|
|
eta = een./(beta-x);
|
|
eta = max(eta,een);
|
|
mu = max(eem,0.5*c);
|
|
zet = 1;
|
|
s = eem;
|
|
itera = 0;
|
|
while epsi > epsimin
|
|
epsvecn = epsi*een;
|
|
epsvecm = epsi*eem;
|
|
ux1 = upp-x;
|
|
xl1 = x-low;
|
|
ux2 = ux1.*ux1;
|
|
xl2 = xl1.*xl1;
|
|
uxinv1 = een./ux1;
|
|
xlinv1 = een./xl1;
|
|
plam = p0 + P'*lam ;
|
|
qlam = q0 + Q'*lam ;
|
|
gvec = P*uxinv1 + Q*xlinv1;
|
|
dpsidx = plam./ux2 - qlam./xl2 ;
|
|
rex = dpsidx - xsi + eta;
|
|
rey = c + d.*y - mu - lam;
|
|
rez = a0 - zet - a'*lam;
|
|
relam = gvec - a*z - y + s - b;
|
|
rexsi = xsi.*(x-alfa) - epsvecn;
|
|
reeta = eta.*(beta-x) - epsvecn;
|
|
remu = mu.*y - epsvecm;
|
|
rezet = zet*z - epsi;
|
|
res = lam.*s - epsvecm;
|
|
residu1 = [rex' rey' rez]';
|
|
residu2 = [relam' rexsi' reeta' remu' rezet res']';
|
|
residu = [residu1' residu2']';
|
|
residunorm = sqrt(residu'*residu);
|
|
residumax = max(abs(residu));
|
|
ittt = 0;
|
|
while residumax > 0.9*epsi & ittt < 500
|
|
ittt=ittt + 1;
|
|
itera=itera + 1;
|
|
ux1 = upp-x;
|
|
xl1 = x-low;
|
|
ux2 = ux1.*ux1;
|
|
xl2 = xl1.*xl1;
|
|
ux3 = ux1.*ux2;
|
|
xl3 = xl1.*xl2;
|
|
uxinv1 = een./ux1;
|
|
xlinv1 = een./xl1;
|
|
uxinv2 = een./ux2;
|
|
xlinv2 = een./xl2;
|
|
plam = p0 + P'*lam ;
|
|
qlam = q0 + Q'*lam ;
|
|
gvec = P*uxinv1 + Q*xlinv1;
|
|
GG = P*spdiags(uxinv2,0,n,n) - Q*spdiags(xlinv2,0,n,n);
|
|
dpsidx = plam./ux2 - qlam./xl2 ;
|
|
delx = dpsidx - epsvecn./(x-alfa) + epsvecn./(beta-x);
|
|
dely = c + d.*y - lam - epsvecm./y;
|
|
delz = a0 - a'*lam - epsi/z;
|
|
dellam = gvec - a*z - y - b + epsvecm./lam;
|
|
diagx = plam./ux3 + qlam./xl3;
|
|
diagx = 2*diagx + xsi./(x-alfa) + eta./(beta-x);
|
|
diagxinv = een./diagx;
|
|
diagy = d + mu./y;
|
|
diagyinv = eem./diagy;
|
|
diaglam = s./lam;
|
|
diaglamyi = diaglam+diagyinv;
|
|
if m < n
|
|
blam = dellam + dely./diagy - GG*(delx./diagx);
|
|
bb = [blam' delz]';
|
|
Alam = spdiags(diaglamyi,0,m,m) + GG*spdiags(diagxinv,0,n,n)*GG';
|
|
AA = [Alam a
|
|
a' -zet/z ];
|
|
solut = AA\bb;
|
|
dlam = solut(1:m);
|
|
dz = solut(m+1);
|
|
dx = -delx./diagx - (GG'*dlam)./diagx;
|
|
else
|
|
diaglamyiinv = eem./diaglamyi;
|
|
dellamyi = dellam + dely./diagy;
|
|
Axx = spdiags(diagx,0,n,n) + GG'*spdiags(diaglamyiinv,0,m,m)*GG;
|
|
azz = zet/z + a'*(a./diaglamyi);
|
|
axz = -GG'*(a./diaglamyi);
|
|
bx = delx + GG'*(dellamyi./diaglamyi);
|
|
bz = delz - a'*(dellamyi./diaglamyi);
|
|
AA = [Axx axz
|
|
axz' azz ];
|
|
bb = [-bx' -bz]';
|
|
solut = AA\bb;
|
|
dx = solut(1:n);
|
|
dz = solut(n+1);
|
|
dlam = (GG*dx)./diaglamyi - dz*(a./diaglamyi) + dellamyi./diaglamyi;
|
|
end
|
|
%
|
|
dy = -dely./diagy + dlam./diagy;
|
|
dxsi = -xsi + epsvecn./(x-alfa) - (xsi.*dx)./(x-alfa);
|
|
deta = -eta + epsvecn./(beta-x) + (eta.*dx)./(beta-x);
|
|
dmu = -mu + epsvecm./y - (mu.*dy)./y;
|
|
dzet = -zet + epsi/z - zet*dz/z;
|
|
ds = -s + epsvecm./lam - (s.*dlam)./lam;
|
|
xx = [ y' z lam' xsi' eta' mu' zet s']';
|
|
dxx = [dy' dz dlam' dxsi' deta' dmu' dzet ds']';
|
|
%
|
|
stepxx = -1.01*dxx./xx;
|
|
stmxx = max(stepxx);
|
|
stepalfa = -1.01*dx./(x-alfa);
|
|
stmalfa = max(stepalfa);
|
|
stepbeta = 1.01*dx./(beta-x);
|
|
stmbeta = max(stepbeta);
|
|
stmalbe = max(stmalfa,stmbeta);
|
|
stmalbexx = max(stmalbe,stmxx);
|
|
stminv = max(stmalbexx,1);
|
|
steg = 1/stminv;
|
|
%
|
|
xold = x;
|
|
yold = y;
|
|
zold = z;
|
|
lamold = lam;
|
|
xsiold = xsi;
|
|
etaold = eta;
|
|
muold = mu;
|
|
zetold = zet;
|
|
sold = s;
|
|
%
|
|
itto = 0;
|
|
resinew = 2*residunorm;
|
|
while resinew > residunorm & itto < 50
|
|
itto = itto+1;
|
|
x = xold + steg*dx;
|
|
y = yold + steg*dy;
|
|
z = zold + steg*dz;
|
|
lam = lamold + steg*dlam;
|
|
xsi = xsiold + steg*dxsi;
|
|
eta = etaold + steg*deta;
|
|
mu = muold + steg*dmu;
|
|
zet = zetold + steg*dzet;
|
|
s = sold + steg*ds;
|
|
ux1 = upp-x;
|
|
xl1 = x-low;
|
|
ux2 = ux1.*ux1;
|
|
xl2 = xl1.*xl1;
|
|
uxinv1 = een./ux1;
|
|
xlinv1 = een./xl1;
|
|
plam = p0 + P'*lam ;
|
|
qlam = q0 + Q'*lam ;
|
|
gvec = P*uxinv1 + Q*xlinv1;
|
|
dpsidx = plam./ux2 - qlam./xl2 ;
|
|
rex = dpsidx - xsi + eta;
|
|
rey = c + d.*y - mu - lam;
|
|
rez = a0 - zet - a'*lam;
|
|
relam = gvec - a*z - y + s - b;
|
|
rexsi = xsi.*(x-alfa) - epsvecn;
|
|
reeta = eta.*(beta-x) - epsvecn;
|
|
remu = mu.*y - epsvecm;
|
|
rezet = zet*z - epsi;
|
|
res = lam.*s - epsvecm;
|
|
residu1 = [rex' rey' rez]';
|
|
residu2 = [relam' rexsi' reeta' remu' rezet res']';
|
|
residu = [residu1' residu2']';
|
|
resinew = sqrt(residu'*residu);
|
|
steg = steg/2;
|
|
end
|
|
residunorm=resinew;
|
|
residumax = max(abs(residu));
|
|
steg = 2*steg;
|
|
end
|
|
if ittt > 198
|
|
epsi
|
|
ittt
|
|
end
|
|
epsi = 0.1*epsi;
|
|
end
|
|
xmma = x;
|
|
ymma = y;
|
|
zmma = z;
|
|
lamma = lam;
|
|
xsimma = xsi;
|
|
etamma = eta;
|
|
mumma = mu;
|
|
zetmma = zet;
|
|
smma = s;
|
|
%-------------------------------------------------------------
|
|
|
|
|