Mixed Integer Quadratic Programming with linear constraints in Matlab calling Gurobi - matlab

I have some troubles to understand how to implement the following MIQP (Mixed Integer Quadratic Programming) with linear constraints in Matlab calling Gurobi.
Let me explain in a schematic way my setting.
(1) x is the unknown and it is a column vector with size 225x1.
(2) The objective function (which should be minimised wrto x) looks like
which can be rewritten as
I have a Matlab script computing alpha, Q,c (Q,c sparse) when some_known_parameters1 are given:
function [alpha, Q,c]=matrix_objective_function(some_known_parameters1)
%...
end
(3) The constraints are linear in x, include equalities and inequalities, and are written in the form
I have a Matlab script computing Aeq,beq,Aineq,bineq (Aeq,Aineq sparse) when some_known_parameters2 is given:
function [Aeq,beq,Aineq,bineq]=constraints(some_known_parameters2)
%...
end
(4) Some components of x are restricted to be in {0,1}. I have a Matlab script producing a string of letters B (binary), C (continous) when some_known_parameters3 is given:
function type=binary_continuous(some_known_parameters3)
%...
end
Now, I need to put together (1)-(4) using Gurobi. I am struggling to understand how. I found this example but it looks very cryptic to me. Below I report some lines I have attempted to write, but they are incomplete and I would like your help to complete them.
clear
rng default
%Define some_known_parameters1,
some_known_parameters2,some_known_parameters3 [...]
%1) generate alpha,Q,c,Aeq,beq,Aineq,bineq,type with Q,c,Aeq, Aineq sparse
[alpha, Q,c]=matrix_objective_function(some_known_parameters1)
[Aeq,beq,Aineq,bineq]=constraints(some_known_parameters2)
type=binary_continuous(some_known_parameters3)
%2) Set up Gurobi
clear model;
model.A=[Aineq; Aeq];
model.rhs=full([bineq(:); beq(:)]);
model.sense=[repmat('<', size(Aineq,1),1); repmat('=', size(Aeq,1),1)];
model.Q=Q; %not sure?
model.alpha=alpha; %not sure?
model.c=c; %not sure?
model.vtype=type;
result=gurobi(model); %how do I get just the objective function here without the minimiser?
Questions:
(1) I'm not sure about
model.Q=Q;
model.alpha=alpha;
model.c=c;
I'm just trying to set the matrices of the objective function using the letters provided here but it gives me error. The example here seems to me doing
model.Q=Q;
model.obj=c;
But then how do I set alpha? Is it ignoring it because it does not change the set of solutions?
(2) How do I get as output stored in a matrix just the minimum value of the objective function without the corresponding x?

(1) You're right, there's no need to pass the constant alpha since it doesn't affect the optimal solution. Gurobi's MATLAB API only accepts sparse matrices. Furthermore model.obj is always the c vector in the problem statement:
model.Q = sparse(Q);
model.obj = c;
(2) To get the optimal objective value, you first need to pass your model to gurobi and solve it. Then you can access it via the objval attribute:
results = gurobi(model);
val = results.objval + alpha

Related

MATLAB Initial Objective Function Evaluation Error

I am trying to create a plot in MATLAB by iterating over values of a constant (A) with respect to a system of equations. My code is pasted below:
function F=Func1(X, A)
%X(1) is c
%X(2) is h
%X(3) is lambda
%A is technology (some constant)
%a is alpha
a=1;
F(1)=1/X(1)-X(3)
F(2)=X(3)*(X(1)-A*X(2)^a)
F(3)=-1/(24-X(2))-X(3)*A*a*X(2)^(a-1)
clear, clc
init_guess=[0,0,0]
for countA=1:0.01:10
result(countA,:)=[countA,fsolve(#Func1, init_guess)]
end
display('The Loop Has Ended')
display(result)
%plot(result(:,1),result(:,2))
The first set of code, I am defining the set of equations I am attempting to solve. In the second set of lines, I am trying to write a loop which iterates through the values of A that I want, [1,10] with an increment of 0.01. Right now, I am just trying to get my loop code to work, but I keep on getting this error:
"Failure in initial objective function evaluation. FSOLVE cannot continue."
I am not sure why this is the case. From what I understand, this is the result of my initial guess matrix not being the right size, but I believe it should be of size 3, as I am solving for three variables. Additionally, I'm fairly confident there's nothing wrong with how I'm referencing my Func1 code in my Loop code.
Any advice you all could provide would be sincerely appreciated. I've only been working on MATLAB for a few days, so if this is a rather trivial fix, pardon my ignorance. Thanks.
Couple of issues with your code:
1/X(1) in function Func1 is prone to the division by zero miscalculations. I would change it to 1/(X(1)+eps).
If countA is incrementing by 0.01, it cannot be used as an index for result. Perhaps introduce an index ind to increment.
I have included your constant A within the function to clarify what optimization variables are.
Here is the updated code. I don't know if the results are reasonable or not:
init_guess=[0,0,0];
ind = 1;
for countA=1:0.01:10
result(ind,:)=[countA, fsolve(#(X) Func1(X,countA), init_guess)];
ind = ind+1;
end
display('The Loop Has Ended')
display(result)
%plot(result(:,1),result(:,2))
function F=Func1(X,A)
%X(1) is c
%X(2) is h
%X(3) is lambda
%A is technology (some constant)
%a is alpha
a=1;
F(1)=1/(X(1)+eps)-X(3);
F(2)=X(3)*(X(1)-A*X(2)^a);
F(3)=-1/(24-X(2))-X(3)*A*a*X(2)^(a-1);
end

Gurobi in Matlab without objective function

I am using Gurobi in Matlab to determine whether a system of linear equalities and linear inequalities has at least one solution. I don't have an objective function to minimise/maximise.
This is my code (I haven't posted the actual content of the matrices Aineq, Aeq, bineq, beq)
clear model;
model.A=[Aineq; Aeq];
model.obj=[];
model.sense=[repmat('<', size(Aineq,1),1); repmat('=', size(Aeq,1),1)];
model.rhs=full([bineq; beq]);
params.outputflag = 0;
result=gurobi(model, params);
if isfield(result,'x')
exists=1;
else
exists=0;
end
Question: what should I set as objective function? If I write model.obj=[]; as above I get
Error using gurobi
Incorrect size(model.obj)
If I delete the model line I get
Error using gurobi
model must contain fields: A, obj, sense, and rhs
This question is related to mine but it doesn't explain what to put in place of the objective function.
Unfortunately I don't have the needed reputation to comment, so this is an answer.
It's important that your matrix A is a sparse matrix, because Gurobi's MATLAB API only accepts sparse matrices: model.A=sparse([Aineq; Aeq]). Then it should work by just removing the line model.obj = [] from your code. If no objective is passed to Gurobi, it will automatically use 0 as the objective function, so that your model will minimize 0 in subject to your constraints. In this case every feasible solution is optimal and satisfies your constraints. Alternatively, you could do this by hand with
model.obj = zeros(size(model.A, 2), 1);

No output while using "gmres" in Matlab

I want to solve a system of linear equalities of the type Ax = b+u, where A and b are known. I used a function in MATLAB like this:
x = #(u) gmres(A,b+u);
Then I used fmincon, where a value for u is given to this expression and x is computed. For example
J = #(u) (x(u)' * x(u) - x^*)^2
and
[J^*,u] = fmincon(J,...);
withe the dots as matrices and vectors for the equalities and inequalities.
My problem is, that MATLAB delivers always an output with information about the command gmres. But I have no idea, how I can stop this (it makes the Program much slower).
I hope you know an answer.
Patsch
It's a little hidden in the documentation, but it does say
No messages are displayed if the flag output is specified.
So you need to call gmres with at least two outputs. You can do this by making a wrapper function
function x = gmresnomsg(varargin)
[x,~] = gmres(varargin{:});
end
and use that for your handle creation
x = #(u) gmresnomsg(A,b+u);

matlab plot vectors must be the same lengths

I am writing a program regarding solving the following boundary value problem using shooting-bisection method:
y''-y+x=0, y(0)=y(1)=0.
I first convert this to a system of first order equations, set
y'=z
then I let dydt represent the vector (y',z'), and come up with the script file:
function dydt=shoot(t,y)
dydt=[y(2);y(1)-t]
end
With this, I then came up with the following code:
clear
clc
a=0;
b=1;
alpha=0;
beta=0;
s(1)=(beta-alpha)/(b-a);
s(2)=-1
[G,Y]=ode113('shoot',[a b],[alpha;s(1)]);
[G,Z]=ode113('shoot',[a b],[alpha;s(2)])
hold
tol=1e-4
u=s(1);
v=s(2);
while abs(u-v)>tol;
s(3)=(u+v)/2;
[G,W]=ode113('shoot',[a b],[alpha;s(3)]);
if W(end,1)>0
u=s(3);
else
v=s(3);
end
end
[G,W]=ode113('shoot',[a b],[alpha;s(3)])
plot(G,Y(:,1),'-o', G,Z(:,1),'-o',G,W(:,1),'-o')
Then I run the program, MATLAB said I'm using the plot argument incorrectly, where plot vectors must be the same lengths. I have no idea how to fix this problem. Any help is appreciated.
Your Y, Z and W outputs are from different runs of ode113. The output independents variables, G from each run are different because ode113 is an adaptive solver. There are two ways you can fix this. You can save your G outputs as separate variables:
...
[Gy,Y]=ode113('shoot',[a b],[alpha;s(1)]);
[Gz,Z]=ode113('shoot',[a b],[alpha;s(2)]);
...
[Gw,W]=ode113('shoot',[a b],[alpha;s(3)]);
plot(Gy,Y(:,1),'-o', Gz,Z(:,1),'-o',Gw,W(:,1),'-o');
Or you could specify a fixed set of output points by specifying more than two points for tspan (second argument to ode113):
...
tspan = linspace(a,b,50);
[G,Y]=ode113('shoot',tspan,[alpha;s(1)]);
[G,Z]=ode113('shoot',tspan,[alpha;s(2)]);
...
[G,W]=ode113('shoot',tspan,[alpha;s(3)]);
plot(G,Y(:,1),'-o', G,Z(:,1),'-o',G,W(:,1),'-o');
Unless your version of Matlab is more than 10 years old, you should also specify your integration function, shoot, via a function handle, not a string, i.e.:
[Gw,W]=ode113(#shoot,[a b],[alpha;s(3)]);

Create vector-valued function with arbitrary components

Good evening everyone,
I want to create a function
f(x) = [f1(x), f2(x), ... , fn(x)]
in MatLab, with an arbitrary form and number for the fi. In my current case they are meant to be basis elements for a finite-dimensional function space, so for example a number of multi variable polynomials. I want to able to be able to set form (e.g. hermite/lagrange polynomials, ...) and number via arguments in some sort of "function creating" function, so I would like to solve this for arbitrary functions fi.
Assume for now that the fi are fi:R^d -> R, so vector input to scalar output. This means the result from f should be a n-dim vector containing the output of all n functions. The number of functions n could be fairly large, as there is permutation involved. I also need to evaluate the resulting function very often, so I hope to do it as efficiently as possible.
Currently I see two ways to do this:
Create a cell with each fi using a loop, using something like
funcell{i}=matlabFunction(createpoly(degree, x),'vars',{x})
and one of the functions from the symbolic toolbox and a symbolic x (vector). It is then possible to create the desired function with cellfun, e.g.
f=#(x) cellfun(#(v) v(x), funcell)
This is relatively short, easy and what can be found when doing searches. It even allows extension to vector output using 'UniformOutput',false and cell2mat. On the downside it is very inefficient, first during creation because of matlabFunction and then during evaluation because of cellfun.
The other idea I had is to create a string and use eval. One way to do this would be
stringcell{i}=[char(createpoly(degree, x)),';']
and then use strjoin. In theory this should yield an efficient function. There are two problems however. The first is the use of eval (mostly on principle), the second is inserting the correct arguments. The symbolic toolbox does not allow symbols of the form x(i), so the resulting string will not contain them either. The only remedy I have so far is some sort of string replacement on the xi that are allowed, but this is also far from elegant.
So I do have ways to do what I need right now, but I would appreciate any ideas for a better solution.
From my understanding of the problem, you could do the straightforward:
Initialization step:
my_fns = cell(n, 1); %where n is number of functions
my_fns{1} = #f1; % Assuming f1 is defined in f1.m etc...
my_fns{2} = #f2;
Evaluation at x:
z = zeros(n, 1);
for i=1:n,
z(i) = my_fns{i}(x)
end
For example if you put it in my_evaluate.m:
function z = my_evaluate(my_fns, x)
z = zeros(n, 1);
for i=1:n,
z(i) = my_fns{i}(x)
end
How might this possibly be sped up?
Depends on if you have special structure than can be exploited.
Are there calculations common to some subset of f1 through fn that need not be repeated with each function call? Eg. if the common calculation step is costly, you could do y = f_helper(x) and z(i) = fi(x, y).
Can the functions f1...fn be vector / matrix friendly, allowing evaluation of multiple points with each function call?
The big issue is how fast your function calls f1 through fn are, not how you collect the results from those calls in a vector.