Dynamic-Calibration/utils/SDPT3-4.0/Solver/gpcomp.m

179 lines
5.6 KiB
Mathematica
Raw Normal View History

2019-12-18 11:25:45 +00:00
%%*********************************************************************
%% gpcomp: Compute tp=1/gp in Proposition 2 of the paper:
%%
%% R.M. Freund, F. Ordonez, and K.C. Toh,
%% Behavioral measures and their correlation with IPM iteration counts
%% on semi-definite programming problems,
%% Mathematical Programming, 109 (2007), pp. 445--475.
%%
%% [gp,info,Xfeas,blk2,At2,C2,b2] = gpcomp(blk,At,C,b,OPTIONS,solveyes);
%%
%% Xfeas = a feasible X for the primal problem if gp is finite.
%% That is,
%% norm(b-AXfun(blk,At,[],Xfeas))
%% should be small
%%*****************************************************************
%% SDPT3: version 4.0
%% Copyright (c) 1997 by
%% Kim-Chuan Toh, Michael J. Todd, Reha H. Tutuncu
%% Last Modified: 16 Sep 2004
%%*****************************************************************
function [gp,info,Xfeas,blk2,At2,C2,b2] = gpcomp(blk,At,C,b,OPTIONS,solveyes);
if (nargin < 6); solveyes = 1; end
if (nargin < 5)
OPTIONS = sqlparameters;
OPTIONS.vers = 1;
OPTIONS.gaptol = 1e-10;
OPTIONS.printlevel = 3;
end
if isempty(OPTIONS); OPTIONS = sqlparameters; end
if ~isfield(OPTIONS,'solver'); OPTIONS.solver = 'sqlp'; end
if ~isfield(OPTIONS,'printlevel'); OPTIONS.printlevel = 3; end
if ~iscell(C); tmp = C; clear C; C{1} = tmp; end
%%
%% convert ublk to lblk
%%
exist_ublk = 0;
for p = 1:size(blk,1)
pblk = blk(p,:);
if strcmp(pblk{1},'u');
exist_ublk = 1;
fprintf('\n converting ublk into the difference of two non-negative vectors');
blk{p,1} = 'l'; blk{p,2} = 2*sum(blk{p,2});
At{p} = [At{p}; -At{p}];
C{p} = [C{p}; -C{p}];
end
end
%%
m = length(b);
blk2 = blk;
At2 = At;
C2 = cell(size(blk,1),1);
b2 = zeros(m,1);
%%
%%
%%
dd = ones(1,m);
ee = zeros(1,m); EE = cell(size(blk,1),1);
exist_ublk = 0;
nn = zeros(size(blk,1),1);
for p = 1:size(blk,1)
pblk = blk(p,:);
n = sum(pblk{2});
if strcmp(pblk{1},'s')
ee = ee + svec(pblk,speye(n),1)'*At{p};
C2{p,1} = sparse(n,n);
EE{p} = speye(n);
nn(p) = n;
elseif strcmp(pblk{1},'q')
eq = zeros(n,1);
idx1 = 1+[0,cumsum(pblk{2})];
idx1 = idx1(1:length(idx1)-1);
eq(idx1) = ones(length(idx1),1);
ee = ee + 2*eq'*At{p};
C2{p,1} = zeros(n,1);
EE{p} = eq;
nn(p) = length(pblk{2});
elseif strcmp(pblk{1},'l')
ee = ee + ones(1,n)*At{p};
C2{p,1} = zeros(n,1);
EE{p} = ones(n,1);
nn(p) = n;
elseif strcmp(pblk{1},'u')
C2{p,1} = zeros(n,1);
exist_ublk = 1;
EE{p} = sparse(n,1);
nn(p) = n;
end
dd = dd + sqrt(sum(At{p}.*At{p}));
end
dd = 1./min(1e4,max(1,dd));
ee = ee.*dd;
b = b.*dd';
%%
%% scale data
%%
D = spdiags(dd',0,m,m);
for p = 1:size(blk,1)
pblk = blk(p,:);
At2{p} = At2{p}*D;
end
%%
%% New variables in primal problem:
%% [x; tt; theta].
%%
numblk = size(blk,1);
blk2{numblk+1,1} = 'l'; blk2{numblk+1,2} = 2;
At2{numblk+1,1} = [ee; -b'];
C2{numblk+1,1} = [-1; 0];
%%
%% 3 additional inequality constraints in primal problem.
%%
ss = 0;
for p = 1:size(blk,1)
pblk = blk(p,:);
n = sum(pblk{2});
if strcmp(pblk{1},'s')
n2 = sum(pblk{2}.*(pblk{2}+1))/2;
At2{p} = [At2{p}, svec(pblk,speye(n,n),1), sparse(n2,2)];
ss = ss + n;
elseif strcmp(pblk{1},'q')
eq = zeros(n,1);
idx1 = 1+[0,cumsum(pblk{2})];
idx1 = idx1(1:length(idx1)-1);
eq(idx1) = ones(length(idx1),1);
At2{p} = [At2{p}, sparse(eq), sparse(n,2)];
ss = ss + 2*length(pblk{2});
elseif strcmp(pblk{1},'l')
At2{p} = [At2{p}, sparse(ones(n,1)), sparse(n,2)];
ss = ss + n;
elseif strcmp(pblk{1},'u')
At2{p} = [At2{p}, sparse(n,3)];
end
end
At2{numblk+1} = sparse([At2{numblk+1}, [ss;0], [0;1], [1;-1]]);
b2 = [b2; 1; 1; 0];
%%
%% Add in the linear block corresponding to the 3 slack variables.
%%
blk2{numblk+2,1} = 'l'; blk2{numblk+2,2} = 3;
At2{numblk+2,1} = [sparse(3,m), speye(3,3)];
C2{numblk+2,1} = zeros(3,1);
%%
%% Solve SDP
%%
gp = []; info = []; Xfeas = [];
if (solveyes)
if strcmp(OPTIONS.solver,'sqlp')
[X0,y0,Z0] = infeaspt(blk2,At2,C2,b2,2,100);
[obj,X,y,Z,info] = sqlp(blk2,At2,C2,b2,OPTIONS,X0,y0,Z0);
elseif strcmp(OPTIONS.solver,'HSDsqlp')
[obj,X,y,Z,info] = HSDsqlp(blk2,At2,C2,b2,OPTIONS);
else
[obj,X,y,Z,info] = sdpt3(blk2,At2,C2,b2,OPTIONS);
end
obj = -obj;
tt = X{numblk+1}(1); theta = X{numblk+1}(2);
Xfeas = ops(ops(X(1:numblk),'+',EE(1:numblk),tt),'/',theta);
%%
if (obj(1) > 0) | (abs(obj(1)) < 1e-8)
gp = 1/abs(obj(1));
elseif (obj(2) > 0)
gp = 1/obj(2);
else
gp = 1/exp(mean(log(abs(obj))));
end
err = max(info.dimacs([1,3,6]));
if (OPTIONS.printlevel)
fprintf('\n ******** gp = %3.2e, err = %3.1e\n',gp,err);
if (err > 1e-6);
fprintf('\n----------------------------------------------------')
fprintf('\n gp problem is not solved to sufficient accuracy');
fprintf('\n----------------------------------------------------\n')
end
end
end
%%*********************************************************************