157 lines
4.9 KiB
Mathematica
157 lines
4.9 KiB
Mathematica
|
|
%%*****************************************************************************
|
||
|
|
%% misc:
|
||
|
|
%% unscale and produce infeasibility certificates if appropriate
|
||
|
|
%%
|
||
|
|
%%*****************************************************************************
|
||
|
|
|
||
|
|
function [X,y,Z,Xiter,yiter,Ziter,resid,reldist,param] = misc(blk,At,C,b,X,y,Z,permZ,param);
|
||
|
|
|
||
|
|
global printlevel
|
||
|
|
|
||
|
|
obj = param.obj;
|
||
|
|
rel_gap = param.rel_gap;
|
||
|
|
prim_infeas = param.prim_infeas;
|
||
|
|
dual_infeas = param.dual_infeas;
|
||
|
|
ZpATynorm = param.ZpATynorm;
|
||
|
|
inftol = param.inftol;
|
||
|
|
normA = param.normA;
|
||
|
|
normC = param.normC;
|
||
|
|
normb = param.normb;
|
||
|
|
keepiter = param.keepiter;
|
||
|
|
m0 = param.m0;
|
||
|
|
indeprows = param.indeprows;
|
||
|
|
termcode = param.termcode;
|
||
|
|
AX = param.AX;
|
||
|
|
scale_data = param.scale_data;
|
||
|
|
normX0 = param.normX0;
|
||
|
|
normZ0 = param.normZ0;
|
||
|
|
%%
|
||
|
|
if (~keepiter); Xiter = []; yiter = []; Ziter = []; end
|
||
|
|
resid = []; reldist = [];
|
||
|
|
%%
|
||
|
|
Anorm = ops(At,'norm'); xnorm = ops(X,'norm'); ynorm = norm(y);
|
||
|
|
infeas_meas = max(prim_infeas,dual_infeas);
|
||
|
|
if (termcode <= 0)
|
||
|
|
%%
|
||
|
|
%% To detect near-infeasibility when the algorithm provides
|
||
|
|
%% a "better" certificate of infeasibility than of optimality.
|
||
|
|
%%
|
||
|
|
err = max(infeas_meas,rel_gap);
|
||
|
|
iflag = 0;
|
||
|
|
if (obj(2) > 0)
|
||
|
|
homRd = ZpATynorm/(obj(2)/(normb*normC));
|
||
|
|
if (homRd < sqrt(err*inftol))
|
||
|
|
iflag = 1;
|
||
|
|
if (printlevel);
|
||
|
|
fprintf('\n prim_inf,dual_inf,rel_gap = %3.2e, %3.2e, %3.2e',...
|
||
|
|
prim_infeas,dual_infeas,rel_gap);
|
||
|
|
end
|
||
|
|
termcode = 1;
|
||
|
|
param.termcode = 1;
|
||
|
|
end
|
||
|
|
elseif (obj(1) < 0)
|
||
|
|
homrp = norm(AX)/(-obj(1)/(normb*normC));
|
||
|
|
if (homrp < sqrt(err*inftol))
|
||
|
|
if (printlevel);
|
||
|
|
fprintf('\n prim_inf,dual_inf,rel_gap = %3.2e, %3.2e, %3.2e',...
|
||
|
|
prim_infeas,dual_infeas,rel_gap);
|
||
|
|
end
|
||
|
|
iflag = 1;
|
||
|
|
termcode = 2;
|
||
|
|
param.termcode = 2;
|
||
|
|
end
|
||
|
|
end
|
||
|
|
if (iflag == 0)
|
||
|
|
if (scale_data == 1)
|
||
|
|
X = ops(normb,'*',X); y = normC*y./normA; Z = ops(normC,'*',Z);
|
||
|
|
end
|
||
|
|
if (keepiter); Xiter = X; yiter = y; Ziter = Z; end;
|
||
|
|
end
|
||
|
|
end
|
||
|
|
if (termcode == 1)
|
||
|
|
if (printlevel);
|
||
|
|
fprintf('\n Stop: primal problem is suspected of being infeasible');
|
||
|
|
end
|
||
|
|
if (scale_data == 1)
|
||
|
|
b = normb*b; b = b.*normA; y = y./normA;
|
||
|
|
X = ops(normb,'*',X);
|
||
|
|
if (keepiter)
|
||
|
|
yiter = normC*y; Ziter = ops(normC,'*',Z); Xiter = X;
|
||
|
|
end
|
||
|
|
else
|
||
|
|
if (keepiter); Xiter = X; yiter = y; Ziter = Z; end;
|
||
|
|
end
|
||
|
|
rby = 1/(b'*y); y = rby*y; Z = ops(Z,'*',rby);
|
||
|
|
resid = ZpATynorm * rby;
|
||
|
|
reldist = ZpATynorm/(Anorm*ynorm);
|
||
|
|
end
|
||
|
|
if (termcode == 2)
|
||
|
|
if (printlevel);
|
||
|
|
fprintf('\n Stop: dual problem is suspected of being infeasible');
|
||
|
|
end
|
||
|
|
if (scale_data == 1)
|
||
|
|
C = ops(C,'*',normC);
|
||
|
|
y = normC*y./normA; Z = ops(normC,'*',Z);
|
||
|
|
if (keepiter)
|
||
|
|
Xiter = ops(normb,'*',X); yiter = y; Ziter = Z;
|
||
|
|
end
|
||
|
|
else
|
||
|
|
if (keepiter); Xiter = X; yiter = y; Ziter = Z; end;
|
||
|
|
end
|
||
|
|
tCX = blktrace(blk,C,X);
|
||
|
|
X = ops(X,'*',1/(-tCX));
|
||
|
|
resid = norm(normA.*AX)/(-tCX);
|
||
|
|
reldist = norm(AX)/(Anorm*xnorm);
|
||
|
|
end
|
||
|
|
if (termcode == 3)
|
||
|
|
maxblowup = max(ops(X,'norm')/normX0,ops(Z,'norm')/normZ0);
|
||
|
|
if (printlevel)
|
||
|
|
fprintf('\n Stop: primal or dual is diverging, %3.1e',maxblowup);
|
||
|
|
end
|
||
|
|
end
|
||
|
|
if (keepiter)
|
||
|
|
[X,Z,Xiter,Ziter] = unperm(blk,permZ,X,Z,Xiter,Ziter);
|
||
|
|
else
|
||
|
|
[X,Z] = unperm(blk,permZ,X,Z);
|
||
|
|
end
|
||
|
|
if ~isempty(indeprows)
|
||
|
|
ytmp = zeros(m0,1);
|
||
|
|
ytmp(indeprows) = y;
|
||
|
|
y = ytmp;
|
||
|
|
if (keepiter)
|
||
|
|
ytmp = zeros(m0,1);
|
||
|
|
ytmp(indeprows) = yiter;
|
||
|
|
yiter = ytmp;
|
||
|
|
end
|
||
|
|
end
|
||
|
|
%%*****************************************************************************
|
||
|
|
%% unperm: undo the permutations applied in validate.
|
||
|
|
%%
|
||
|
|
%% [X,Z,Xiter,Ziter] = unperm(blk,permZ,X,Z,Xiter,Ziter);
|
||
|
|
%%
|
||
|
|
%% undoes the permutation introduced in validate.
|
||
|
|
%% can also be called if Xiter and Ziter have not been set as
|
||
|
|
%%
|
||
|
|
%% [X,Z] = unperm(blk,permZ,X,Z);
|
||
|
|
%%
|
||
|
|
%% SDPT3: version 3.0
|
||
|
|
%% Copyright (c) 1997 by
|
||
|
|
%% K.C. Toh, M.J. Todd, R.H. Tutuncu
|
||
|
|
%% Last modified: 2 Feb 01
|
||
|
|
%%*****************************************************************************
|
||
|
|
|
||
|
|
function [X,Z,Xiter,Ziter] = unperm(blk,permZ,X,Z,Xiter,Ziter);
|
||
|
|
%%
|
||
|
|
for p = 1:size(blk,1)
|
||
|
|
if (strcmp(blk{p,1},'s') & ~isempty(permZ{p}))
|
||
|
|
per = permZ{p};
|
||
|
|
X{p} = X{p}(per,per);
|
||
|
|
Z{p} = Z{p}(per,per);
|
||
|
|
if (nargin >= 5)
|
||
|
|
Xiter{p} = Xiter{p}(per,per);
|
||
|
|
Ziter{p} = Ziter{p}(per,per);
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
%%*****************************************************************************
|