clc echo on %********************************************************* % % Global bilinear programming % %********************************************************* % % YALMIP comes with a simple branch-and-bound code % for solving problems with bilinear/quadratic constraints. % % The code is under development, and is currently only % applicable to small problems. % % For the examples below to work, you must have an efficient % LP solver (cplex,clp,nag,...) insrtalled and a solver for % general polynomial problems (currently only fmincon or PENBMI) pause yalmip('clear') clc %********************************************************* % The first example is the problem from the moment % relaxation demo (concave quadratic constraint). %********************************************************* x1 = sdpvar(1,1); x2 = sdpvar(1,1); x3 = sdpvar(1,1); objective = -2*x1+x2-x3; F = set(x1*(4*x1-4*x2+4*x3-20)+x2*(2*x2-2*x3+9)+x3*(2*x3-13)+24>0); F = F + set(4-(x1+x2+x3)>0); F = F + set(6-(3*x2+x3)>0); F = F + set(x1>0); F = F + set(2-x1>0); F = F + set(x2>0); F = F + set(x3>0); F = F + set(3-x3>0); pause % Explicitly specify the global solver (this is currently recommended) ops = sdpsettings('solver','bmibnb'); % Global solver pause % Solve! solvesdp(F,objective,ops) pause yalmip('clear') clc %*********************************************************** % The second example is slightly larger. It is a problem % with a concave quadratic objective function, and two % concave quadratic constraints. %*********************************************************** x1 = sdpvar(1,1); x2 = sdpvar(1,1); x3 = sdpvar(1,1); x4 = sdpvar(1,1); x5 = sdpvar(1,1); x6 = sdpvar(1,1); objective = -25*(x1-2)^2-(x2-2)^2-(x3-1)^2-(x4-4)^2-(x5-1)^2-(x6-4)^2; F = set((x3-3)^2+x4>4) + set((x5-3)^2+x6>4); F = F + set(x1-3*x2<2) + set(-x1+x2<2) + set(x1+x2>2); F = F + set(6>x1+x2>2); F = F + set(10)+set(x2>0); pause % The global solver in YALMIP can currently only deal with linear objectives. % A simple epi-graph formulation solves this. t = sdpvar(1,1); F = F + set(objectivex>0); F = F + set(e>0); F = F + set(obj==t); % We will nowe try to solve this using the same strategy as before solvesdp(F,t,ops) pause clc % As an alternative, we might use additional cuts using the CUT functionality. % These additional constraints are only used in domain reduction and % solution of lower bound programs, but not in the local solver. % We square all linear constraints and add these as cuts % % Note that the triu operator leaves returns a matrix with % zeros below the diagonal. These are however neglected by YALMIP % in the call to SET. % f = sdpvar(F(find(is(F,'linear')))); F = F + cut(triu(f*f') > 0); pause % ...and solve (To speed up things, we turn off LP based domain reduction) % % NOTE : The first ~15 iterations are rather slow, but things starts to % speed up when YALMIP starts pruning redundnant linear constraints. % solvesdp(F,t,sdpsettings(ops,'bmibnb.lpreduce',0)) pause clc % The global solver in YALMIP can only solve bilinear programs, % but a pre-processor is capable of transforming higher order problems % to bilinear programs. As an example, the variable x^3y^2 will be replaced % with the the variable w and the constraints w == uv, u == zx, z == x^2, v == y^2. % The is done automatically if the global solver, or PENBMI, is called with % a higher order polynomial problem. Note that this conversion is rather % inefficient, and only very small problems can be addressed using this simple approach. % Additionally, this module has not been tested in any serious sense. pause % Let us solve a small trivial polynomial program sdpvar x y F = set(x^3+y^5 < 5) + set(y > 0); F = F + set(-100 < [x y] < 100) % Always bounded domain pause solvesdp(F,-x,ops) pause %*********************************************************** % The main motivation for implementing a bilinear solver in % YALMIP is matrix-valued problems, i.e. BMI problems. % % Of-course, BMI problems are even harder than the nonconvex % quadratic problems solved above. However, in some cases, % it is actually possible to solve BMI problems globally. % % Don't expect too much though... %*********************************************************** pause clc %*********************************************************** % The following is a classical problem %*********************************************************** A0 = [-10 -0.5 -2;-0.5 4.5 0;-2 0 0]; A1 = [9 0.5 0;0.5 0 -3 ; 0 -3 -1]; A2 = [-1.8 -0.1 -0.4;-0.1 1.2 -1;-0.4 -1 0]; K12 = [0 0 2;0 -5.5 3;2 3 0]; x = sdpvar(1,1); y = sdpvar(1,1); t = sdpvar(1,1); F = set(A0+x*A1+y*A2+x*y*K12-t*eye(3)<0); F = F + set(-0.5 < x < 2) + set(-3 < y < 7); pause % Specify solvers (this requires PENBMI!) ops = sdpsettings('solver','bmibnb'); % Global solver ops = sdpsettings(ops,'bmibnb.uppersolver','penbmi'); % Local solver pause % Solve! solvesdp(F,t,ops); pause clc %*********************************************************** % The next example shows how to solve a standard LQ control % problem with constraints on the feedback gain %*********************************************************** A = [-1 2;-3 -4];B = [1;1]; P = sdpvar(2,2); K = sdpvar(1,2); F = set(P>0)+set((A+B*K)'*P+P*(A+B*K) < -eye(2)-K'*K); F = F + set(K<0.1)+set(K>-0.1); F = F + set(1000> P(:)>-1000); solvesdp(F,trace(P),ops); pause clc %*********************************************************** % Decay-rate estimation as a global BMI example ... % % Note, this is a quasi-convex problem that PENBMI actually % solves to global optimality, so the use of a global solver % is pretty stupid. It is only included here to show some % properties of the global solver. % % may run for up to 100 iterations depending on the solvers %*********************************************************** A = [-1 2;-3 -4]; t = sdpvar(1,1); P = sdpvar(2,2); F = set(P>eye(2))+set(A'*P+P*A < -2*t*P); F = F + set(-1e4 < P(:) < 1e4) + set(100 > t > 0) ; pause solvesdp(F,-t,ops); pause % Now, that sucked, right! 100 iterations and still 10% gap... % % The way we model a problem can make a huge difference. % The decay-rate problem can be substantially improved by % using a smarter model. The original problem is homogenous % w.r.t P, and a better way to make the feasible set bounded % is to constrain the trace of P A = [-1 2;-3 -4]; t = sdpvar(1,1); P = sdpvar(2,2); F = set(P>0)+set(A'*P+P*A < -2*t*P); F = F + set(trace(P)==1) + set(100 > t > 0) ; pause solvesdp(F,-t,ops); pause % Nothing prevents us from adding an additional % constraint derived from trace(P)=1 F = F + set(trace(A'*P+P*A) < -2*t); pause solvesdp(F,-t,ops); pause % When we add redundant constraints, we improve the relaxations % and obtain better lower bounds. For the upper bounds however, % these cuts only add additional computational burden. % To overcome this, the command CUT can be used. % Constraints defined with CUT are not used when the upper % bound problems are solved, but are only used in relaxations F = set(P>0)+set(A'*P+P*A < -2*t*P); F = F + set(trace(P)==1) + set(100 > t > 0) ; F = F + cut(trace(A'*P+P*A) < -2*t); pause solvesdp(F,-t,ops); pause % Finally, it should be mentioned that the branch & bound % algorithm can run without any installed local BMI solver. % This version of the algorithms is obtained by specifying % the upper bound solver as 'none' ops = sdpsettings(ops,'bmibnb.uppersolver','none'); F = set(P>0)+set(A'*P+P*A < -2*t*P); F = F + set(trace(P)==1) + set(100 > t > 0) ; F = F + cut(trace(A'*P+P*A) < -2*t); pause solvesdp(F,-t,ops); pause echo off break % ******************************** % Sahinidis (-6.666 in 1) % ******************************** yalmip('clear'); x1 = sdpvar(1,1); x2 = sdpvar(1,1); F = set(0 < x1 < 6)+set(0 < x2 < 4) + set(x1*x2 < 4) solvesdp(F,-x1-x2,sdpsettings('bmibnb.uppersolver','penbmi','bmibnb.lowersolver','pensdp','verbose',2,'solver','bmibnb','bmibnb.maxiter',100,'penbmi.P0',0.9e-1,'bmibnb.lpsolver','cdd','cdd.method','dual-simplex')) % **************************** % Decay-rate (-2.5) % **************************** yalmip('clear'); A = [-1 2;-3 -4]; t = sdpvar(1,1); P = sdpvar(2,2); F = set(P>eye(2))+set(A'*P+P*A < -2*t*P); F = F + set(-1e4 < P(:) < 1e4) + set(100 > t > -100) ; ops = sdpsettings('bmibnb.lowersolver','pensdp','verbose',2,'solver','bmibnb','bmibnb.maxiter',100,'penbmi.P0',0.9e-1,'bmibnb.lpsolver','cdd','cdd.method','dual-simplex'); solvesdp(F,-t,ops); % ******************************** % Classical example from Safonov etc % ******************************** yalmip('clear') x = sdpvar(1,1); y = sdpvar(1,1); t = sdpvar(1,1); A0 = [-10 -0.5 -2;-0.5 4.5 0;-2 0 0]; A1 = [9 0.5 0;0.5 0 -3 ; 0 -3 -1]; A2 = [-1.8 -0.1 -0.4;-0.1 1.2 -1;-0.4 -1 0]; K12 = [0 0 2;0 -5.5 3;2 3 0]; F = lmi(x>-0.5)+lmi(x<2) + lmi(y>-3)+lmi(y<7) + lmi(t>-1000)+lmi(t<1000);%set(x+y<2.47)+set(x+y>2.47); F = F + lmi(A0+x*A1+y*A2+x*y*K12-t*eye(3)<0); solvesdp(F,t,sdpsettings('bmibnb.lowersolver','pensdp','verbose',2,'solver','bmibnb','bnb.maxiter',30,'penbmi.P0',0.09e-1,'bmibnb.lpsolver','glpk')) % ******************************** % Lassere 1 % optimal : -4, takes 13 % ******************************** clear all x1 = sdpvar(1,1); x2 = sdpvar(1,1); x3 = sdpvar(1,1); x = [x1;x2;x3]; B = [0 0 1;0 -1 0;-2 1 -1]; b = [3;0;-4]; v = [0;-1;-6]; r = [1.5;-0.5;-5]; p = -2*x1+x2-x3; F = set(x1+x2+x3 < 4) + set(x1<2)+set(x3<3) + set(3*x2+x3 < 6); F = F + set(x>0) + set(x'*B'*B*x-2*r'*B*x+r'*r-0.25*(b-v)'*(b-v) >0); solvesdp(F,p,sdpsettings('bmibnb.uppersolver','penbmi','bmibnb.lowersolver','glpk','verbose',2,'solver','bmibnb','bnb.maxiter',30,'penbmi.P0',0.09e-1,'bmibnb.lpsolver','glpk')) % ******************************** % Lassere 2 % optimal : -310 in 3 % ******************************** clear all x1 = sdpvar(1,1); x2 = sdpvar(1,1); x3 = sdpvar(1,1); x4 = sdpvar(1,1); x5 = sdpvar(1,1); x6 = sdpvar(1,1); t = sdpvar(1,1); p = -25*(x1-2)^2-(x2-2)^2-(x3-1)^2-(x4-4)^2-(x5-1)^2-(x6-4)^2; F = set((x3-3)^2+x4>4)+set((x5-3)^2+x6>4); F = F + set(x1-3*x2<2)+set(-x1+x2<2); F = F + set(x1-3*x2 <2)+set(x1+x2>2); F = F + set(6>x1+x2>2); F = F + set(10)+set(x2>0); solvesdp(F,p,sdpsettings('bmibnb.uppersolver','penbmi','bmibnb.lowersolver','glpk','verbose',2,'solver','bmibnb','bnb.maxiter',30,'penbmi.P0',0.09e-1,'bmibnb.lpsolver','glpk')) F = F + set(p100 % ******************************** clear all x = sdpvar(10,1); t = sdpvar(1,1); x(1) = 1-sum(x(2:end)); obj = 0; for i = 1:9 obj = obj+x(i)*x(i+1); end for i = 1:8 obj = obj+x(i)*x(i+2); end obj = obj + x(1)*x(7)+ x(1)*x(9)+ x(2)*x(10)+ x(4)*x(7); F = set(1>x>0); F = F + set(-obj0) + set(sum(x)<1); F = F+set(-100); F = F+set(p1)=1;K0(K0<-1)=-1; K = sdpvar(1,2);setsdpvar(K,-K0); F = set(K<1)+set(K>-1)+set(P>0)+set((A+B*K)'*P+P*(A+B*K) < -eye(2)-K'*K); %F = F + set([-(A+B*K)'*P-P*(A+B*K)-eye(2) K';K eye(1)] > 0) F = F+lmi(diag(P)>0)+lmi(P(:)>-151) + lmi(P(:)<150) + lmi(P>P0)+lmi(K>-100) + lmi(K<100); solvesdp(F,trace(P),sdpsettings('usex0',1,'bmibnb.uppersolver','penbmi','bmibnb.lowersolver','pensdp','verbose',2,'solver','bmibnb','bnb.maxiter',30,'penbmi.P0',0.9e-1,'bmibnb.lpsolver','glpk','bmibnb.lpreduce',1)) % ******************************** % GAMS st_qpc_m1 % optimal -473.77 in 3 % ******************************** clear all x1 = sdpvar(1,1); x2 = sdpvar(1,1); x3 = sdpvar(1,1); x4 = sdpvar(1,1); x5 = sdpvar(1,1); t = sdpvar(1,1); F = set([x1;x2;x3;x4;x5]>0); F = F + set(x1 + x2 + 2*x3 + x4 + x5 > 10); F = F + set(2*x1 + 3*x2 + x5 > 8); F = F + set(x2 + 4*x3 - x4 + 2*x5 > 12); F = F + set(8*x1 - x2 - x3 + 6*x4 > 20); F = F + set(- 2*x1 - x2 - 3*x3 - x4 - x5 > -30); obj = -(- (10*x1 - 0.34*x1*x1 - 0.28*x1*x2 + 10*x2 - 0.22*x1*x3 + 10*x3 - 0.24*x1*x4 + 10*x4 - 0.51*x1*x5 + 10*x5 - 0.28*x2*x1 - 0.34*x2*x2 - 0.23*x2*x3 -0.24*x2*x4 - 0.45*x2*x5 - 0.22*x3*x1 - 0.23*x3*x2 - 0.35*x3*x3 - 0.22*x3*x4 - 0.34*x3*x5 - 0.24*x4*x1 - 0.24*x4*x2 - 0.22*x4*x3 - 0.2*x4*x4 - 0.38*x4*x5 - 0.51*x5*x1 - 0.45*x5*x2 - 0.34*x5*x3 - 0.38*x5*x4 - 0.99*x5*x5)); solvesdp(F,obj,sdpsettings('bmibnb.uppersolver','penbmi','bmibnb.lowersolver','pensdp','verbose',2,'solver','bmibnb','bnb.maxiter',30,'penbmi.P0',0.9e-1,'bmibnb.lpsolver','glpk')) F = F + set(obj0); F = F + set(- x1 + x2 < 1); F = F + set(x1 - x2 < 1); F = F + set(- x1 + 2*x2 < 3); F = F + set(2*x1 - x2 < 3); obj = (2*x1 - 2*x1*x1 + 2*x1*x2 + 3*x2 - 2*x2*x2); F = F + set(obj