0001
0002 function [ifail] = solve(obj)
0003
0004 ifail = 0;
0005
0006
0007 if (obj.phase<1)
0008 error('The problem needs to be initialized first.');
0009 else
0010 obj.phase=2;
0011 end
0012
0013 PENALTY_UPDT = obj.allopts.penalty_update;
0014 PENALTY_UPDT_BAR = obj.allopts.penalty_update_bar;
0015 MAX_PBMITER = obj.allopts.max_outer_iter;
0016 PBMALPHA = obj.allopts.outer_stop_limit;
0017 KKTALPHA = obj.allopts.kkt_stop_limit;
0018 MU = obj.allopts.mlt_update;
0019 UINIT = obj.allopts.uinit;
0020 UINIT_BOX = obj.allopts.uinit_box;
0021 UINIT_EQ = obj.allopts.uinit_eq;
0022 UMIN = obj.allopts.umin;
0023 PINIT = obj.allopts.pinit;
0024 PINIT_BAR = obj.allopts.pinit_bar;
0025 USEBARRIER = obj.allopts.usebarrier;
0026
0027 GAP_NOPROGRESS = 1e20;
0028 OBJ_UNBOUNDED = -1e20;
0029 MIN_MAX_FAILED = 3;
0030
0031
0032 obj.clearstats();
0033
0034 nFlag=length(penlab.solvermsg);
0035 starttime=cputime;
0036
0037
0038 nGapNoProgress=0;
0039 nGrowingGap=0;
0040 nMinFailed=0;
0041
0042
0043 bConstrIneq=obj.Nxbox+obj.Nineq+obj.NYbox+obj.NA>0;
0044 bConstrEq=obj.Neq>0;
0045
0046
0047 obj.print(3,Inf,'Problem name: %s',obj.probname);
0048 if (~isempty(obj.comment))
0049 obj.print(3,Inf,'Description: %s',obj.comment);
0050 end
0051 obj.print(3,Inf,'Start time: %s',datestr(now,0));
0052 obj.print_opts(3,Inf);
0053 obj.print(3,Inf,' ');
0054
0055
0056
0057 obj.init(false);
0058
0059
0060
0061
0062
0063 lbx = -Inf(obj.Nx+obj.NYnnz,1);
0064 ubx = Inf(obj.Nx+obj.NYnnz,1);
0065 ind = find(obj.xboxmlt<0);
0066 lbx(ind) = obj.xboxshift(ind);
0067 ind = find(obj.xboxmlt>0);
0068 ubx(ind) = -obj.xboxshift(ind);
0069 if (obj.allopts.xinit_mod)
0070
0071
0072 frac = 0.01;
0073 dist = frac*min(ubx - lbx,1);
0074 obj.xall=max(lbx+dist,obj.xall);
0075 obj.xall=min(ubx-dist,obj.xall);
0076 elseif (~isempty(obj.xboxindbar))
0077
0078
0079 xboxx = obj.xboxshift + obj.xboxmlt .* obj.xall(obj.xboxmap);
0080 ind=find(xboxx(obj.xboxindbar)>=-1e-7);
0081 if (~isempty(ind))
0082
0083 xind=unique(obj.xboxmap(obj.xboxindbar(ind)));
0084 frac = 1e-5;
0085 dist = frac*min(ubx(xind) - lbx(xind),1);
0086 obj.xall(xind)=max(lbx(xind)+dist,obj.xall(xind));
0087 obj.xall(xind)=min(ubx(xind)-dist,obj.xall(xind));
0088 end
0089 end
0090
0091
0092 nNLNineq=sum(obj.ineqmap<=obj.NgNLN);
0093 nNLNeq=sum(obj.eqmap<=obj.NgNLN);
0094 nNLNAineq=sum(obj.Amap<=obj.NANLN);
0095 obj.print(2,Inf,'*******************************************************************************');
0096 obj.print(2,Inf,penlab.solvername);
0097 obj.print(2,Inf,'*******************************************************************************');
0098 obj.print(2,Inf,'Number of variables %7d',obj.Nx);
0099 obj.print(2,Inf,'Number of matrix variables %7d',obj.NY);
0100 obj.print(2,Inf,' - degrees of freedom (var. elements) %7d',obj.NYnnz);
0101 obj.print(2,Inf,'(Function) constraints');
0102 obj.print(2,Inf,' - box inequalities %7d',obj.Nxbox);
0103 obj.print(2,Inf,' - linear inequalities %7d',obj.Nineq-nNLNineq);
0104 obj.print(2,Inf,' - nonlinear inequalities %7d',nNLNineq);
0105 obj.print(2,Inf,' - linear equalities %7d',obj.Neq-nNLNeq);
0106 obj.print(2,Inf,' - nonlinear equalities %7d',nNLNeq);
0107 obj.print(2,Inf,'Matrix constraints');
0108 obj.print(2,Inf,' - box inequalities %7d',obj.NYbox);
0109 obj.print(2,Inf,' - linear inequalities %7d',obj.NA-nNLNAineq);
0110 obj.print(2,Inf,' - nonlinear inequalities %7d',nNLNAineq);
0111 obj.print(2,Inf,' ');
0112 if (obj.Nxbox>0)
0113 obj.print(2,Inf,'Min./Max. box-mult.: %9f / %9f',min(obj.uxbox),max(obj.uxbox));
0114 end
0115 if (obj.Nineq>0)
0116 obj.print(2,Inf,'Min./Max. ineq-mult.: %9f / %9f',min(obj.uineq),max(obj.uineq));
0117 end
0118 if (obj.Neq>0)
0119 obj.print(2,Inf,'Min./Max. equal-mult.: %9f / %9f',min(obj.ueq),max(obj.ueq));
0120 end
0121
0122
0123
0124 obj.eval_alx();
0125 obj.eval_aldx();
0126
0127
0128 f=obj.objx;
0129 constrx=[obj.xboxx;obj.ineqx];
0130 eqx=obj.eqx;
0131 lagrx=obj.ALx;
0132 gradx=obj.ALdx;
0133 gradeqx=obj.eqdx;
0134 uineq_updt = [];
0135 uxbox_updt = [];
0136
0137 obj.rNormG=norm(obj.ALdx);
0138 rFeasM=obj.feas_ay();
0139 obj.rFeas=max([abs(obj.eqx);max(0,obj.xboxx);max(0,obj.ineqx);rFeasM;0]);
0140 rGap=abs(obj.objx-obj.ALx);
0141 if (bConstrIneq)
0142 rPmin=min([obj.pxbox;obj.pineq;obj.PYbox;obj.PA]);
0143 else
0144 rPmin=0;
0145 end
0146 if (bConstrIneq || bConstrEq)
0147
0148
0149
0150 obj.rCompl=max([0;abs(obj.uxbox.*obj.xboxx);abs(obj.uineq.*obj.ineqx);abs(obj.eqx.*obj.ueq)]);
0151
0152 else
0153 obj.rCompl=0;
0154 end
0155
0156 obj.print(3,Inf,'******************** Start *********************');
0157 obj.print(3,Inf,'Objective %27.16E',obj.objx);
0158 obj.print(3,Inf,'Augmented Lagrangian %27.16E',obj.ALx);
0159 obj.print(3,Inf,'|f(x) - Lagr(x)| %27.16E',rGap);
0160 obj.print(3,Inf,'Grad augm. lagr. %27.16E',obj.rNormG);
0161 obj.print(3,Inf,'Feasibility (max) %27.16E',obj.rFeas);
0162 obj.print(3,Inf,'Feasibility eqx %27.16E',max(abs(obj.eqx)));
0163 obj.print(3,Inf,'Feasibility ineq %27.16E',max(max(0,obj.ineqx)));
0164 obj.print(3,Inf,'Feasibility box %27.16E',max(max(0,obj.xboxx)));
0165 obj.print(3,Inf,'Feasibility m.ineq %27.16E',rFeasM);
0166 obj.print(3,Inf,'Complementarity %27.16E',obj.rCompl);
0167 obj.print(3,Inf,'Minimal penalty %27.16E',rPmin);
0168 obj.print(3,Inf,'************************************************');
0169 obj.print(3,Inf,' ');
0170
0171 obj.print(2,3,'*******************************************************************************');
0172 obj.print(2,3,'* it | obj | (U,G(x)) | ||dF|| | feas | pmin | Nwt | InIt |');
0173 obj.print(2,3,'*******************************************************************************');
0174 if (bConstrIneq || bConstrEq)
0175 obj.print(2,3,'| %3d|%13.5e |%9.1e |%9.1e |%9.1e |%9.1e | %4d | %4d |',0,obj.objx,obj.rCompl,obj.rNormG,obj.rFeas,rPmin,obj.miter_last,obj.initer_last);
0176 else
0177 obj.print(2,3,'| %3d|%13.5e | |%9.1e | | | %4d | %4d |',0,obj.objx,obj.rNormG,obj.miter_last,obj.initer_last);
0178 end
0179
0180
0181 nFlag=7;
0182 for pbmiter=1:MAX_PBMITER
0183
0184 f_old = obj.objx;
0185 rGap_old = rGap;
0186
0187 obj.print(3,Inf,'************* Start of outer step %3i **********',pbmiter);
0188
0189
0190
0191
0192 if (obj.Neq==0)
0193
0194
0195
0196
0197 [nFlagMin,rResults]=obj.unconstr_min();
0198 lagrx=rResults(1);
0199 obj.rNormG=rResults(2);
0200
0201
0202
0203 else
0204
0205
0206
0207
0208 [nFlagMin,rResults]=obj.eqconstr_min();
0209 lagrx=rResults(1);
0210 obj.rNormG=rResults(2);
0211
0212
0213
0214 end
0215
0216
0217
0218
0219 obj.eval_alx();
0220 obj.eval_aldx();
0221
0222
0223
0224 if (obj.Nxbox+obj.Nineq~=0)
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235 uineq_updt = obj.phi2_D(obj.ineqx./obj.pineq);
0236 uxbox_updt = obj.phi2_D(obj.xboxx./obj.pxbox);
0237 end
0238
0239
0240
0241
0242 f=obj.objx;
0243 constrx=[obj.xboxx;obj.ineqx];
0244 eqx=obj.eqx;
0245 lagrx=obj.ALx;
0246 gradx=obj.ALdx;
0247 gradeqx=obj.eqdx;
0248
0249 obj.rNormG=norm(obj.ALdx);
0250 rFeasM=obj.feas_ay();
0251 obj.rFeas=max([abs(obj.eqx);max(0,obj.xboxx);max(0,obj.ineqx);rFeasM;0]);
0252 rGap=abs(obj.objx-obj.ALx);
0253 if (bConstrIneq)
0254
0255 rPmin=min([obj.pxbox;obj.pineq;obj.PYbox;obj.PA]);
0256 end
0257 if (bConstrIneq || bConstrEq)
0258
0259
0260 obj.rCompl=max([0;abs(obj.uxbox.*uxbox_updt.*obj.xboxx);abs(obj.uineq.*uineq_updt.*obj.ineqx);abs(obj.eqx.*obj.ueq)]);
0261 end
0262
0263 if (nFlagMin>0)
0264 obj.print(3,Inf,'*****!!!!!!! Result of outer step %3i !!!!!*****',pbmiter);
0265 else
0266 obj.print(3,Inf,'************ Result of outer step %3i **********',pbmiter);
0267 end
0268 obj.print(3,Inf,'Objective %27.16E',obj.objx);
0269 obj.print(3,Inf,'Augmented Lagrangian %27.16E',obj.ALx);
0270 obj.print(3,Inf,'|f(x) - f(x_old)| %27.16E',abs(f-f_old));
0271 obj.print(3,Inf,'|f(x) - Lagr(x)| %27.16E',rGap);
0272 obj.print(3,Inf,'Grad augm. lagr. %27.16E',obj.rNormG);
0273 obj.print(3,Inf,'Feasibility (max) %27.16E',obj.rFeas);
0274 obj.print(3,Inf,'Feasibility eqx %27.16E',max(abs(obj.eqx)));
0275 obj.print(3,Inf,'Feasibility ineq %27.16E',max(max(0,obj.ineqx)));
0276 obj.print(3,Inf,'Feasibility box %27.16E',max(max(0,obj.xboxx)));
0277 obj.print(3,Inf,'Feasibility m.ineq %27.16E',rFeasM);
0278 obj.print(3,Inf,'Complementarity %27.16E',obj.rCompl);
0279 obj.print(3,Inf,'Minimal penalty %27.16E',rPmin);
0280 obj.print(3,Inf,'Newton steps %5d',obj.miter_last);
0281 obj.print(3,Inf,'Inner steps %5d',obj.initer_last);
0282 obj.print(3,Inf,'Linesearch steps %5d',obj.lsiter_last);
0283 obj.print(3,Inf,'Time of the minimization step %14g s',obj.stats_time_miter_last);
0284 obj.print(3,Inf,' - factorizations in the step %14g s',obj.stats_time_fact_last);
0285 if (nFlagMin>0)
0286 obj.print(3,Inf,'*****!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*****');
0287 warn_sign='!';
0288 else
0289 obj.print(3,Inf,'************************************************');
0290 warn_sign=' ';
0291 end
0292 obj.print(3,Inf,' ');
0293
0294 if (bConstrIneq || bConstrEq)
0295 obj.print(2,3,'| %3d|%13.5e |%9.1e |%9.1e |%9.1e |%9.1e | %4d | %4d%s|',pbmiter,obj.objx,obj.rCompl,obj.rNormG,obj.rFeas,rPmin,obj.miter_last,obj.initer_last,warn_sign);
0296 else
0297 obj.print(2,3,'| %3d|%13.5e | |%9.1e | | | %4d | %4d%s|',pbmiter,obj.objx,obj.rNormG,obj.miter_last,obj.initer_last,warn_sign);
0298 end
0299
0300
0301
0302
0303
0304
0305
0306 if (nFlagMin>0)
0307 nMinFailed=nMinFailed+1;
0308 obj.print(3,Inf,'Warning: Unconstr/eqconstr. min failed (flag %i), remaing attepmts: %i',nFlagMin,MIN_MAX_FAILED-nMinFailed);
0309
0310 else
0311 nMinFailed=0;
0312 end
0313 if (nMinFailed >= MIN_MAX_FAILED)
0314 nFlag=5;
0315 break;
0316 end
0317
0318
0319
0320 if (stop_crit(obj.objx, f_old, PBMALPHA) && stop_crit(obj.objx, obj.ALx, 10*PBMALPHA) && (obj.rFeas<1e-4*abs(obj.ALx) || obj.rFeas<1e-3))
0321 if ( (obj.rNormG<KKTALPHA && obj.rCompl<KKTALPHA && obj.rFeas<KKTALPHA) || (obj.rNormG<10*KKTALPHA && obj.rCompl<0.01*KKTALPHA && obj.rFeas<0.01*KKTALPHA) )
0322 nFlag=1;
0323 break;
0324 end
0325 end
0326 if (rGap > GAP_NOPROGRESS)
0327 nGapNoProgress=nGapNoProgress+1;
0328 else
0329 nGapNoProgress=0;
0330 end
0331 if (rGap > rGap_old)
0332 nGrowingGap=nGrowingGap+1;
0333 else
0334 nGrowingGap=0;
0335 end
0336 if (nGapNoProgress>2 || nGrowingGap>40)
0337 nFlag=6;
0338 break;
0339 end
0340 if (obj.ALx<OBJ_UNBOUNDED)
0341 nFlag=4;
0342 break;
0343 end
0344
0345
0346 obj.uxbox = lmlt_update(obj.uxbox,uxbox_updt,obj.xboxindphi,MU,UMIN);
0347 obj.uineq = lmlt_update(obj.uineq,uineq_updt,obj.ineqindphi,MU,UMIN);
0348
0349 obj.lmltm_update();
0350
0351 if (obj.Nxbox>0)
0352 obj.pxbox(obj.xboxindbar) = obj.pxbox(obj.xboxindbar).*PENALTY_UPDT_BAR;
0353 obj.pxbox(obj.xboxindphi) = obj.pxbox(obj.xboxindphi).*PENALTY_UPDT;
0354 end
0355 if (obj.Nineq>0)
0356
0357 obj.pineq(obj.ineqindphi) = obj.pineq(obj.ineqindphi).*PENALTY_UPDT;
0358 end
0359
0360 obj.mpen_update();
0361
0362
0363
0364
0365
0366
0367 obj.ALxtck=0;
0368 obj.ALdxtck=0;
0369 obj.ALddxtck=0;
0370
0371 end
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381 obj.uxbox(obj.xboxindphi) = obj.uxbox(obj.xboxindphi).*uxbox_updt(obj.xboxindphi);
0382 obj.uineq(obj.ineqindphi) = obj.uineq(obj.ineqindphi).*uineq_updt(obj.ineqindphi);
0383
0384
0385 obj.rNormG=norm(obj.ALdx);
0386 obj.rFeas=max([abs(obj.eqx);max(0,obj.xboxx);max(0,obj.ineqx);0]);
0387 rGap=abs(obj.objx-obj.ALx);
0388 if (obj.Nxbox + obj.Nineq>0)
0389
0390 rPmin=min([obj.pxbox;obj.pineq]);
0391 end
0392 if (obj.Nxbox + obj.Nineq + obj.Neq>0)
0393
0394 obj.rCompl=max([abs(obj.uxbox.*obj.xboxx);abs(obj.uineq.*obj.ineqx);abs(obj.eqx.*obj.ueq)]);
0395 end
0396
0397
0398
0399 if (nFlag==1)
0400 if (obj.rNormG>1.0e-4*abs(obj.ALx) && obj.rNormG>1.0e-3)
0401 nFlag=2;
0402 end
0403 if(obj.rFeas>1.0e-4*abs(obj.ALx) && obj.rFeas>1.0e-3)
0404 nFlag=3;
0405 end
0406 end
0407 obj.stats_time_total = cputime - starttime;
0408
0409 obj.print(2,Inf,'*******************************************************************************');
0410 if (nFlag>=1 && nFlag<length(penlab.solvermsg)-1)
0411 obj.print(2,Inf,'PenLab %s',penlab.solvermsg{nFlag});
0412 else
0413 obj.print(2,Inf,'PenLab: Unknow error (%i)',nFlag);
0414 end
0415 obj.print(2,Inf,'*******************************************************************************');
0416 obj.print(2,Inf,'Objective %27.16E',obj.objx);
0417 obj.print(3,Inf,'Augmented Lagrangian %27.16E',obj.ALx);
0418 obj.print(2,Inf,'Relative precision %27.16E',abs(obj.ALx-obj.objx)/max(1,obj.objx));
0419 obj.print(2,Inf,'Compl. Slackness %27.16E',obj.rCompl);
0420 obj.print(2,Inf,'Grad augm. lagr. %27.16E',obj.rNormG);
0421 obj.print(2,Inf,'Feasibility (max) %27.16E',obj.rFeas);
0422 obj.print(3,Inf,'Feasibility eqx %27.16E',max(abs(obj.eqx)));
0423 obj.print(3,Inf,'Feasibility ineq %27.16E',max(max(0,obj.ineqx)));
0424 obj.print(3,Inf,'Feasibility box %27.16E',max(max(0,obj.xboxx)));
0425 obj.print(3,Inf,'Minimal penalty %27.16E',rPmin);
0426 obj.print(2,Inf,'Newton steps %5d',obj.miter);
0427 obj.print(2,Inf,'Inner steps %5d',obj.initer);
0428 obj.print(2,Inf,'Linesearch steps %5d',obj.lsiter);
0429 obj.print(2,Inf,'Number of evaluations of');
0430 obj.print(2,Inf,' - function values %5d',obj.stats_ncall_alx);
0431 obj.print(2,Inf,' - gradient values %5d',obj.stats_ncall_aldx);
0432 obj.print(2,Inf,' - hessian values %5d',obj.stats_ncall_alddx);
0433 obj.print(2,Inf,'Time statistics');
0434 obj.print(2,Inf,' - total process time %14g s',obj.stats_time_total);
0435 obj.print(2,Inf,' - all minimization steps %14g s',obj.stats_time_miters);
0436 obj.print(2,Inf,' - all factorizations %14g s',obj.stats_time_fact);
0437 obj.print(2,Inf,' - function values evaluation %14g s',obj.stats_time_alx);
0438 obj.print(2,Inf,' - gradient values evaluation %14g s',obj.stats_time_aldx);
0439 obj.print(2,Inf,' - hessian values evaluation %14g s',obj.stats_time_alddx);
0440 obj.print(2,Inf,'*******************************************************************************');
0441 obj.print(2,Inf,' ');
0442
0443 obj.phase=3;
0444
0445 ifail = nFlag;
0446 end
0447
0448
0449
0450
0451 function [b]=stop_crit(f1,f2,eps)
0452
0453 b = abs(f1 - f2) < eps*(1+.5*(abs(f2)+abs(f1)));
0454 return
0455 end
0456
0457
0458
0459 function [u] = lmlt_update(u,u_updt,phiind,mu,umin)
0460 if (~isempty(phiind))
0461 utmp = u(phiind).*u_updt(phiind);
0462 utmp = min((1/mu)*u(phiind), utmp);
0463 u(phiind) = max(mu*u(phiind), utmp);
0464
0465 xchange=abs(u)<umin & u~=0;
0466 u(xchange)=sign(u(xchange))*umin;
0467 end
0468 end
0469