1 | function output = callsedumi(interfacedata) |
---|
2 | |
---|
3 | % Author Johan Löfberg |
---|
4 | % $Id: callsedumi.m,v 1.26 2006/08/10 18:00:19 joloef Exp $ |
---|
5 | |
---|
6 | % Retrieve needed data |
---|
7 | options = interfacedata.options; |
---|
8 | F_struc = interfacedata.F_struc; |
---|
9 | c = interfacedata.c; |
---|
10 | K = interfacedata.K; |
---|
11 | ub = interfacedata.ub; |
---|
12 | lb = interfacedata.lb; |
---|
13 | |
---|
14 | % Create the parameter structure |
---|
15 | pars = options.sedumi; |
---|
16 | pars.fid = double(options.verbose); |
---|
17 | |
---|
18 | % ********************************************* |
---|
19 | % Bounded variables converted to constraints |
---|
20 | % N.B. Only happens when caller is BNB |
---|
21 | % ********************************************* |
---|
22 | if ~isempty(ub) |
---|
23 | [F_struc,K] = addbounds(F_struc,K,ub,lb); |
---|
24 | end |
---|
25 | |
---|
26 | % Avoid bug (by design?) in SeDuMi on 1D second order cones |
---|
27 | if any(K.q == 2) |
---|
28 | [F_struc,K] = fix1Dqcone(F_struc,K); |
---|
29 | end |
---|
30 | |
---|
31 | if options.savedebug |
---|
32 | save sedumidebug F_struc c K pars |
---|
33 | end |
---|
34 | |
---|
35 | % ********************************************* |
---|
36 | % Call SeDuMi |
---|
37 | % ********************************************* |
---|
38 | if options.showprogress;showprogress(['Calling ' interfacedata.solver.tag],options.showprogress);end |
---|
39 | |
---|
40 | solvertime = clock; |
---|
41 | problem = 0; |
---|
42 | try |
---|
43 | [x_s,y_s,info] = sedumi(-F_struc(:,2:end),-c,F_struc(:,1),K,pars); |
---|
44 | catch |
---|
45 | try |
---|
46 | if options.verbose > 0 |
---|
47 | disp(' '); |
---|
48 | disp('SeDuMi had unexplained problems, probably due to linear dependence.') |
---|
49 | disp('YALMIP tweaks the problem and restarts...') |
---|
50 | disp(' '); |
---|
51 | end |
---|
52 | % Boring issue in sedumi for trivial problem min x+y, s.t x+y>0 |
---|
53 | n = length(c); |
---|
54 | [F_struc,K] = addbounds(F_struc,K,ones(n,1)*1e6,-ones(n,1)*1e6); |
---|
55 | [x_s,y_s,info] = sedumi(-F_struc(:,2:end),-c,F_struc(:,1),K,pars); |
---|
56 | x_s((1:2*n)+K.f)=[]; |
---|
57 | K.l=K.l-2*n; |
---|
58 | catch |
---|
59 | disp('Unexplained crash in SeDuMi! (could be memory issues)') |
---|
60 | disp('If you have SDPT3 3.02 on you path, remove it.') |
---|
61 | disp('If this doesn''t work, make sure you have a recent and compiled version') |
---|
62 | end |
---|
63 | end |
---|
64 | if interfacedata.getsolvertime solvertime = etime(clock,solvertime);else solvertime = 0;end |
---|
65 | |
---|
66 | |
---|
67 | % Internal format |
---|
68 | Primal = y_s; |
---|
69 | Dual = x_s; |
---|
70 | |
---|
71 | temp = info.pinf; |
---|
72 | pinf = info.dinf; |
---|
73 | dinf = temp; |
---|
74 | |
---|
75 | % Check for reported errors |
---|
76 | if (pinf==0) & (dinf==0) |
---|
77 | problem = 0; % No problems |
---|
78 | end |
---|
79 | |
---|
80 | % We can only report one error, use priorities |
---|
81 | if (problem==0) & (pinf==1) |
---|
82 | problem = 1; % Primal infeasability |
---|
83 | end |
---|
84 | |
---|
85 | if (problem==0) & (dinf==1) |
---|
86 | problem = 2; % Dual infeasability |
---|
87 | end |
---|
88 | |
---|
89 | if (problem==0) & (info.numerr==1) | (info.numerr==2) |
---|
90 | problem = 4; %Numerical problems |
---|
91 | end |
---|
92 | |
---|
93 | if (problem==0) & (info.iter >= options.sedumi.maxiter) |
---|
94 | % Did we need exactly maxiter iterations to find optimum |
---|
95 | if (pinf==0) & (dinf==0) & (info.numerr==0) |
---|
96 | problem = 0; % Yes |
---|
97 | else |
---|
98 | problem = 3; % No, we are not optimal yet |
---|
99 | end |
---|
100 | end |
---|
101 | |
---|
102 | if (problem==0) & (info.feasratio<0.98) |
---|
103 | problem = 4; |
---|
104 | end |
---|
105 | |
---|
106 | % Fix for cases not really explained in documentation of sedumi? |
---|
107 | if (abs(info.feasratio+1)<0.1) & (pinf==0) & (dinf==0) |
---|
108 | problem = 1; |
---|
109 | end |
---|
110 | if (abs(info.feasratio+1)<0.1) & (pinf==0) & (dinf==0) & (c'*y_s<-1e10) |
---|
111 | problem = 2; |
---|
112 | end |
---|
113 | |
---|
114 | |
---|
115 | infostr = yalmiperror(problem,interfacedata.solver.tag); |
---|
116 | |
---|
117 | % Save ALL data sent to solver |
---|
118 | if options.savesolverinput |
---|
119 | solverinput.A = -F_struc(:,2:end); |
---|
120 | solverinput.c = F_struc(:,1); |
---|
121 | solverinput.b = -c; |
---|
122 | solverinput.K = K; |
---|
123 | solverinput.pars = pars; |
---|
124 | else |
---|
125 | solverinput = []; |
---|
126 | end |
---|
127 | |
---|
128 | % Save ALL data from the solution? |
---|
129 | if options.savesolveroutput |
---|
130 | solveroutput.x = x_s; |
---|
131 | solveroutput.y = y_s; |
---|
132 | solveroutput.info = info; |
---|
133 | else |
---|
134 | solveroutput = []; |
---|
135 | end |
---|
136 | |
---|
137 | % Standard interface |
---|
138 | output.Primal = Primal; |
---|
139 | output.Dual = Dual; |
---|
140 | output.Slack = []; |
---|
141 | output.problem = problem; |
---|
142 | output.infostr = infostr; |
---|
143 | output.solverinput = solverinput; |
---|
144 | output.solveroutput= solveroutput; |
---|
145 | output.solvertime = solvertime; |
---|
146 | |
---|
147 | function [new_F_struc,K] = fix1Dqcone(F_struc,K); |
---|
148 | |
---|
149 | new_F_struc = F_struc(1:(K.l+K.f),:); |
---|
150 | top = K.f + K.l + 1; |
---|
151 | for i = 1:length(K.q) |
---|
152 | if K.q(i) == 2 |
---|
153 | new_F_struc = [new_F_struc;F_struc(top,:);F_struc(top+1,:);F_struc(top,:)*0]; |
---|
154 | K.q(i) = 3; |
---|
155 | top = top + 2; |
---|
156 | else |
---|
157 | new_F_struc = [new_F_struc;F_struc(top:top+K.q(i),:);F_struc(top+1,:);F_struc(top,:)*0]; |
---|
158 | top = top + K.q(i); |
---|
159 | end |
---|
160 | end |
---|
161 | new_F_struc = [new_F_struc;F_struc(top:end,:)]; |
---|