[37] | 1 | function output = callpenbmi(interfacedata); |
---|
| 2 | |
---|
| 3 | % Author Johan Löfberg |
---|
| 4 | % $Id: callpenbmi.m,v 1.5 2005/05/07 13:53:20 joloef Exp $ |
---|
| 5 | |
---|
| 6 | % Retrieve needed data |
---|
| 7 | options = interfacedata.options; |
---|
| 8 | F_struc = interfacedata.F_struc; |
---|
| 9 | c = interfacedata.c; |
---|
| 10 | Q = interfacedata.Q; |
---|
| 11 | K = interfacedata.K; |
---|
| 12 | x0 = interfacedata.x0; |
---|
| 13 | monomtable = interfacedata.monomtable; |
---|
| 14 | ub = interfacedata.ub; |
---|
| 15 | lb = interfacedata.lb; |
---|
| 16 | |
---|
| 17 | |
---|
| 18 | % Bounded variables converted to constraints |
---|
| 19 | if ~isempty(ub) |
---|
| 20 | [F_struc,K] = addbounds(F_struc,K,ub,lb); |
---|
| 21 | end |
---|
| 22 | |
---|
| 23 | if K.f>0 |
---|
| 24 | F_struc = [-F_struc(1:K.f,:);F_struc]; |
---|
| 25 | F_struc(1:K.f,1) = F_struc(1:K.f,1)+sqrt(eps); |
---|
| 26 | K.l = K.l + 2*K.f; |
---|
| 27 | K.f = 0; |
---|
| 28 | end |
---|
| 29 | |
---|
| 30 | nonlinearindicies = find(sum(monomtable,2)>1); |
---|
| 31 | linearindicies = setdiff(1:length(c),nonlinearindicies); |
---|
| 32 | c0 = c; |
---|
| 33 | c = c(linearindicies); |
---|
| 34 | |
---|
| 35 | % Any non-linear scalar inequalities? |
---|
| 36 | % Move these to the BMI part |
---|
| 37 | if K.l>0 |
---|
| 38 | nonlinear_scalars = find(any(full(F_struc(1:K.l,[nonlinearindicies(:)'+1])),2)); |
---|
| 39 | if ~isempty(nonlinear_scalars) |
---|
| 40 | Kold = K; |
---|
| 41 | linear_scalars = setdiff(1:K.l,nonlinear_scalars); |
---|
| 42 | F_struc = [F_struc(linear_scalars,:);F_struc(nonlinear_scalars,:);F_struc(K.l+1:end,:)]; |
---|
| 43 | K.l = K.l-length(nonlinear_scalars); |
---|
| 44 | if (length(K.s)==1) & (K.s==0) |
---|
| 45 | K.s = [repmat(1,1,length(nonlinear_scalars))]; |
---|
| 46 | else |
---|
| 47 | K.s = [repmat(1,1,length(nonlinear_scalars)) K.s]; |
---|
| 48 | end |
---|
| 49 | end |
---|
| 50 | end |
---|
| 51 | |
---|
| 52 | if ~isempty(F_struc) |
---|
| 53 | penstruct = sedumi2pen(F_struc(:,[1 linearindicies(:)'+1]),K,c,x0); |
---|
| 54 | else |
---|
| 55 | penstruct = sedumi2pen([],K,c,x0); |
---|
| 56 | end |
---|
| 57 | |
---|
| 58 | if ~isempty(nonlinearindicies) |
---|
| 59 | bmi = sedumi2pen(F_struc(:,[nonlinearindicies(:)'+1]),K,[],[]); |
---|
| 60 | penstruct.ki_dim = bmi.ai_dim; |
---|
| 61 | % Nonlinear index |
---|
| 62 | penstruct.ki_dim = bmi.ai_dim; |
---|
| 63 | penstruct.ki_row = bmi.ai_row; |
---|
| 64 | penstruct.ki_col = bmi.ai_col; |
---|
| 65 | penstruct.ki_nzs = bmi.ai_nzs; |
---|
| 66 | penstruct.ki_val = bmi.ai_val; |
---|
| 67 | for i = 1:length(bmi.ai_idx) |
---|
| 68 | nl = nonlinearindicies(1+bmi.ai_idx(i)); |
---|
| 69 | v = find(monomtable(nl,:)); |
---|
| 70 | if length(v)==1 |
---|
| 71 | v(2)=v(1); |
---|
| 72 | end |
---|
| 73 | |
---|
| 74 | penstruct.ki_idx(i)=v(1); |
---|
| 75 | penstruct.kj_idx(i)=v(2); |
---|
| 76 | |
---|
| 77 | end |
---|
| 78 | else |
---|
| 79 | penstruct.ki_dim = 0*penstruct.ai_dim; |
---|
| 80 | penstruct.ki_row = []; |
---|
| 81 | penstruct.ki_col = []; |
---|
| 82 | penstruct.ki_nzs = []; |
---|
| 83 | penstruct.ki_val = []; |
---|
| 84 | penstruct.ki_idx = []; |
---|
| 85 | penstruct.kj_idx = []; |
---|
| 86 | penstruct.kj_val = []; |
---|
| 87 | end |
---|
| 88 | |
---|
| 89 | if nnz(Q)>0 |
---|
| 90 | [row,col,vals] = find(triu(Q)); |
---|
| 91 | penstruct.q_nzs = length(row); |
---|
| 92 | penstruct.q_val = vals; |
---|
| 93 | penstruct.q_col = col-1; |
---|
| 94 | penstruct.q_row = row-1; |
---|
| 95 | else |
---|
| 96 | penstruct.q_nzs = 0; |
---|
| 97 | penstruct.q_val = 0; |
---|
| 98 | penstruct.q_col = 0; |
---|
| 99 | penstruct.q_row = 0; |
---|
| 100 | end |
---|
| 101 | |
---|
| 102 | ops = struct2cell(options.penbmi);ops = [ops{1:end}]; |
---|
| 103 | penstruct.ioptions = ops(1:12); |
---|
| 104 | penstruct.foptions = ops(13:end); |
---|
| 105 | penstruct.ioptions(4) = max(0,min(3,options.verbose+1)); |
---|
| 106 | if penstruct.ioptions(4)==1 |
---|
| 107 | penstruct.ioptions(4)=0; |
---|
| 108 | end |
---|
| 109 | |
---|
| 110 | % **************************************** |
---|
| 111 | % UNCOMMENT THIS IF USING PENBMI version 1 |
---|
| 112 | % **************************************** |
---|
| 113 | % penstruct.ioptions = penstruct.ioptions(1:8); |
---|
| 114 | % penstruct.foptions = penstruct.foptions(1:8); |
---|
| 115 | |
---|
| 116 | if ~isempty(x0) |
---|
| 117 | penstruct.x0 = x0(linearindicies); |
---|
| 118 | penstruct.x0 = penstruct.x0(:)'; |
---|
| 119 | end |
---|
| 120 | |
---|
| 121 | % FIX |
---|
| 122 | if penstruct.mconstr == 0 |
---|
| 123 | penstruct.msizes = []; |
---|
| 124 | end |
---|
| 125 | |
---|
| 126 | if options.savedebug |
---|
| 127 | save penbmidebug penstruct |
---|
| 128 | end |
---|
| 129 | |
---|
| 130 | showprogress('Calling PENBMI',options.showprogress); |
---|
| 131 | solvertime = clock; |
---|
| 132 | try |
---|
| 133 | if all(c==0) |
---|
| 134 | [xout, fx, u, iresults, fresults, iflag] = pen(penstruct,1); |
---|
| 135 | else |
---|
| 136 | [xout, fx, u, iresults, fresults, iflag] = pen(penstruct,0); |
---|
| 137 | end |
---|
| 138 | catch |
---|
| 139 | % Fix for bug i tomlab |
---|
| 140 | if all(c==0) |
---|
| 141 | [xout, fx, u, iresults, fresults, iflag] = pen(penstruct); |
---|
| 142 | else |
---|
| 143 | [xout, fx, u, iresults, fresults, iflag] = pen(penstruct); |
---|
| 144 | end |
---|
| 145 | end |
---|
| 146 | solvertime = etime(clock,solvertime); |
---|
| 147 | |
---|
| 148 | % Get dual variable |
---|
| 149 | % First, get the nonlinear scalars treated as BMIs |
---|
| 150 | if exist('nonlinear_scalars') |
---|
| 151 | if ~isempty(nonlinear_scalars) |
---|
| 152 | u = u(:); |
---|
| 153 | n_orig_scalars = length(nonlinear_scalars)+K.l; |
---|
| 154 | linear_scalars = setdiff(1:n_orig_scalars,nonlinear_scalars); |
---|
| 155 | u_nonlinear=u(K.l+1:K.l+length(nonlinear_scalars)); |
---|
| 156 | u(K.l+1:K.l+length(nonlinear_scalars))=[]; |
---|
| 157 | u_linear = u(1:K.l); |
---|
| 158 | u_scalar = zeros(1,n_orig_scalars); |
---|
| 159 | u_scalar(linear_scalars)=u_linear; |
---|
| 160 | u_scalar(nonlinear_scalars)=u_nonlinear; |
---|
| 161 | u = [u_scalar(:);u(1+K.l:end)]; |
---|
| 162 | K = Kold; |
---|
| 163 | end |
---|
| 164 | end |
---|
| 165 | |
---|
| 166 | u = u(:); |
---|
| 167 | D_struc = u(1:1:K.l); |
---|
| 168 | if length(K.s)>0 |
---|
| 169 | if K.s(1)>0 |
---|
| 170 | pos = K.l+1; |
---|
| 171 | for i = 1:length(K.s) |
---|
| 172 | temp = zeros(K.s(i),K.s(i)); |
---|
| 173 | vecZ = u(pos:pos+0.5*K.s(i)*(K.s(i)+1)-1); |
---|
| 174 | top = 1; |
---|
| 175 | for j = 1:K.s(i) |
---|
| 176 | len = K.s(i)-j+1; |
---|
| 177 | temp(j:end,j)=vecZ(top:top+len-1);top=top+len; |
---|
| 178 | end |
---|
| 179 | temp = (temp+temp');j = find(speye(K.s(i)));temp(j)=temp(j)/2; |
---|
| 180 | D_struc = [D_struc;temp(:)]; |
---|
| 181 | pos = pos + (K.s(i)+1)*K.s(i)/2; |
---|
| 182 | end |
---|
| 183 | end |
---|
| 184 | end |
---|
| 185 | |
---|
| 186 | |
---|
| 187 | %Recover solution |
---|
| 188 | if isempty(nonlinearindicies) |
---|
| 189 | x = xout(:); |
---|
| 190 | else |
---|
| 191 | x = zeros(length(c0),1); |
---|
| 192 | for i = 1:length(linearindicies) |
---|
| 193 | x(linearindicies(i)) = xout(i); |
---|
| 194 | end |
---|
| 195 | end |
---|
| 196 | |
---|
| 197 | problem = 0; |
---|
| 198 | switch iflag |
---|
| 199 | case 0 |
---|
| 200 | problem = 0; % OK |
---|
| 201 | case {1,3} |
---|
| 202 | problem = 4; |
---|
| 203 | case 2 |
---|
| 204 | problem = 1; % INFEASIBLE |
---|
| 205 | case 4 |
---|
| 206 | problem = 3; % Numerics |
---|
| 207 | case 5 |
---|
| 208 | problem = 7; |
---|
| 209 | case {6,7} |
---|
| 210 | problem = 11; |
---|
| 211 | otherwise |
---|
| 212 | problem = -1; |
---|
| 213 | end |
---|
| 214 | infostr = yalmiperror(problem,'PENBMI/TOMLAB'); |
---|
| 215 | |
---|
| 216 | if options.savesolveroutput |
---|
| 217 | solveroutput.xout = xout; |
---|
| 218 | solveroutput.fx = fx; |
---|
| 219 | solveroutput.u = u; |
---|
| 220 | solveroutput.iresults = iresults; |
---|
| 221 | solveroutput.fresults = fresults; |
---|
| 222 | solveroutput.iflag = iflag; |
---|
| 223 | else |
---|
| 224 | solveroutput = []; |
---|
| 225 | end |
---|
| 226 | |
---|
| 227 | if options.savesolverinput |
---|
| 228 | solverinput.penstruct = penstruct; |
---|
| 229 | else |
---|
| 230 | solverinput = []; |
---|
| 231 | end |
---|
| 232 | |
---|
| 233 | % Standard interface |
---|
| 234 | output.Primal = x(:); |
---|
| 235 | output.Dual = D_struc; |
---|
| 236 | output.Slack = []; |
---|
| 237 | output.problem = problem; |
---|
| 238 | output.infostr = infostr; |
---|
| 239 | output.solverinput = solverinput; |
---|
| 240 | output.solveroutput= solveroutput; |
---|
| 241 | output.solvertime = solvertime; |
---|