YALMIP is returning that a program is infeasible when it is not - matlab

I'm having a problem trying to use YALMIP; I suspect I'm doing something silly and I would greatly appreciate if someone pointed out what it is.
I'm trying to solve some SDPs. When I don't define an objective, YALMIP returns a solution (implying that the problem is feasible). However, when I attach an objective to it, YALMIP returns that the problem is infeasible, which has left me a bit perplexed.
Here's the code for the simplest SDP I could cook up in which the above happens. Declaring the variables and setting the constraints is as follows:
y = sdpvar(6,1);
M = sdpvar(3,3);
C = [0,0,0,0,0,0; 0,0,0,0,0,0; -2,0,1.8,0,2,1; 0,0,0,0,0,0; 1,0,-1,0,-1.2,0;
0,0,0,0,0,0;];
F = [C*y==0, y(6) == 1, M>=0];
F = [F,M(1,1) == y(1), M(2,1) == y(2), M(3,1) == y(3),...
M(2,2) == y(4), M(3,2) == y(5), M(3,3) == y(6)];
Now if I merely ask YALMIP to find a feasible solution with
solvesdp(F)
it returns
info: 'Successfully solved (LMILAB)'
problem: 0
and some feasible M and y (I've checked that they indeed are). However, if I append the objective "minimise y(3)" (or indeed any linear combination of the entries of y) with
solvesdp(F,y(3))
it returns that the problem is infeasible:
info: 'Infeasible problem (LMILAB)'
problem: 1
and y and M are full of "NaN" tokens.
Many thanks in advance.

LMILAB should not be used together with YALMIP.
http://users.isy.liu.se/johanl/yalmip/pmwiki.php?n=Solvers.LMILAB
The solver in LMILAB has many deficiencies, and one which becomes crucial here is the fact that the solver lacks support for inequalities. To circumvent this, YALMIP adds double-sided inequalities, which completely destroys the numerical procedures of LMILAB.
Install a more general (and modern) solver such as SeDuMi, SDPT3, or Mosek
http://users.isy.liu.se/johanl/yalmip/pmwiki.php?n=Category.SemidefiniteProgrammingSolver
BTW, you are redundantly defining additional variables y. No reason to have them as separate decision variables and then encode how they relate to M. Simply extract them
y = M(find(tril(ones(3))));

Related

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);

Unable to code non linear equation in MATLAB R2013a - MATLAB giving warning message

I wanted to solve the following equation in MATLAB R2013a using the Symbolic Math Toolbox.
(y/x)-(((1+r)^n)-1)/r=0 where y,x and n>3 are given and r is the dependent variable
I tried myself & coded as follows:
f=solve('(y/x)-(((1+r)^n)-1)/r','r')
but as the solution for r is not exact i.e. it is converging on successive iterations hence MATLAB is giving a warning output with the message
Warning: Explicit solution could not be found.
f =
[ empty sym ]
How do I code this?
There are an infinite number of solutions to this for an unspecified value of n > 3 and unknown r. I hope that it's pretty clear why – it's effectively asking for a greater and greater number of roots of (1+r)^n. You can find solutions for fixed values of n, however. Note that as n becomes larger there are more and more solutions and of course some of them are complex. I'm going to assume that you're only interested in real values of r. You can use solve and symbolic math for n = 4, n = 5, and n = 6 (for n = 6, the solution may not be in a convenient form):
y = 441361;
x = 66990;
n = 5;
syms r;
rsol = solve(y/x-((1+r)^n-1)/r==0,r,'IgnoreAnalyticConstraints',true)
double(rsol)
However, the question is "do you need all the solutions or just a particular solution for a given value of n"? If you just need a particular solution, you shouldn't be using symbolic math at all as it's slower and has practical issues like the ones you're experiencing. You can instead just use a numerical approach to find a zero of the equation that is near a specified initial guess. fzero is the standard function for solving this sort of problem in a single variable:
y = 441361;
x = 66990;
n = 5;
f = #(r)y/x-((1+r).^n-1)./r;
r0 = 1;
rsol = fzero(f,r0)
You'll see that the value returned is the same as one of the solutions from the symbolic solution above. If you adjust the initial guess r0 (say r0 = -3), it will return the other solution. When using numeric approaches in cases when there are multiple solutions, if you want specific solutions you'll need to know about the behavior of your function and you'll need to add some clever extra code to choose initial guesses.
I think you forgot to define n as well.
f=solve('(y/x)-(((1+r)^n)-1)/r=0','n-3>0','r','n')
Should solve your problem :)

Issue with Matlab solve function?

The following command
syms x real;
f = #(x) log(x^2)*exp(-1/(x^2));
fp(x) = diff(f(x),x);
fpp(x) = diff(fp(x),x);
and
solve(fpp(x)>0,x,'Real',true)
return the result
solve([0.0 < (8.0*exp(-1.0/x^2))/x^4 - (2.0*exp(-1.0/x^2))/x^2 -
(6.0*log(x^2)*exp(-1.0/x^2))/x^4 + (4.0*log(x^2)*exp(-1.0/x^2))/x^6],
[x == RD_NINF..RD_INF])
which is not what I expect.
The first question: Is it possible to force Matlab's solve to return the set of all solutions?
(This is related to this question.) Moreover, when I try to solve the equation
solve(fpp(x)==0,x,'Real',true)
which returns
ans =
-1.5056100417680902125994180096313
I am not satisfied since all solutions are not returned (they are approximately -1.5056, 1.5056, -0.5663 and 0.5663 obtained from WolframAlpha).
I know that vpasolve with some initial guess can handle this. But, I have no idea how I can generally find initial guessed values to obtain all solutions, which is my second question.
Other solutions or suggestions for solving these problems are welcomed.
As I indicated in my comment above, sym/solve is primarily meant to solve for analytic solutions of equations. When this fails, it tries to find a numeric solution. Some equations can have an infinite number of numeric solutions (e.g., periodic equations), and thus, as per the documentation: "The numeric solver does not try to find all numeric solutions for [the] equation. Instead, it returns only the first solution that it finds."
However, one can access the features of MuPAD from within Matlab. MuPAD's numeric::solve function has several additional capabilities. In particular is the 'AllRealRoots' option. In your case:
syms x real;
f = #(x)log(x^2)*exp(-1/(x^2));
fp(x) = diff(f(x),x);
fpp(x) = diff(fp(x),x);
s = feval(symengine,'numeric::solve',fpp(x)==0,x,'AllRealRoots')
which returns
s =
[ -1.5056102995536617698689500437312, -0.56633904710786569620564475006904, 0.56633904710786569620564475006904, 1.5056102995536617698689500437312]
as well as a warning message.
My answer to this question provides other way that various MuPAD solvers can be used, particularly if you can isolate and bracket your roots.
The above is not going to directly help with your inequalities other than telling you where the function changes sign. For those you could try:
s = feval(symengine,'solve',fpp(x)>0,x,'Real')
which returns
s =
(Dom::Interval(0, Inf) union Dom::Interval(-Inf, 0)) intersect solve(0 < 2*log(x^2) - 3*x^2*log(x^2) + 4*x^2 - x^4, x, Real)
Try plotting this function along with fpp.
While this is not a bug per se, The MathWorks still might be interested in this difference in behavior and poor performance of sym/solve (and the underlying symobj::solvefull) relative to MuPAD's solve. File a bug report if you like. For the life of me I don't understand why they can't better unify these parts of Matlab. The separation makes not sense from the perspective of a user.

Solve equation numerically containing log

I have the following script that defines a function and sets up and equation:
H = #(f) sum(log(f));
f = rand(1, 1);
syms a
H(f)-H(f-a)
I want to solve H(f)-H(f-a)=0 for a. I tried using fzero in the following manner, fzero('H(f)-H(f-a)', 0), but this doesn't yield me anything useful.
well the clear answer for this would be that a=0. This is of course the obvious answer, and may be why you are not getting "anything useful", especially when only considering one value for f.
However, you can actually get useful information when you add more values and use the solve function.
H = #(f) sum(log(f));
f = rand(5, 1);
syms a
temp = H(f)-H(f-a);
out = double(solve(temp == 0,a));
This will output a vector with all values of a that are solutions to your function. Just note that this may not result in the best answers in general, numerical solving of high order functions is rather difficult and unreliable. Because of this, it may take a long time to run as well.

Using nlinfit in Matlab?

I'm having trouble understanding and applying the use of nlinfit function in Matlab. So, let's say I'm given vectors
x = [1, 2, 3, 4, 5]
y = [2.3, 2.1, 1.7, .95, .70]
and I'm asked to fit this data to an exponential form (I don't know if the numbers will work, I made them up) where y = A*e^(Bx) + C (A/B/C are constants).
My understanding is that nlinfit takes 4 arguments, the two vectors, a modelfunction which in this case should be the equation I have above, and then beta0, which I don't understand at all. My question is how do you implement the modelfunction in nlinft, and how do you find beta0 (when only working with 2 vectors you want to plot/fit) and how should it be implemented? Can someone show me an example so that I can apply this function for any fit? I suspect I'll be using this a lot in the future and really want to learn it.
Check out the second example in the docs: http://www.mathworks.com/help/stats/nlinfit.html
Basically you pass a function handle as your modelfunction parameter. Either make a function in a file and then just pass it the function name with an # in front or else make an anonymous function like this:
nlinfit(x, y, #(b,x)(b(1).*exp(b(2).*x) + b(3)), beta0)
You'll notice that in the above I have stuck all your parameters into a single vector. The first parameter of your function must be a vector of all the points you are trying to solve for (i.e. A, B and C in your case) and the second must be x.
As woodchips has said beta0 is your starting point so your best guess (doesn't have to be great) of your A, B and C parameters. so something like [1 1 1] or rand(3,1), it is very problem specific though. You should play around with a few. Just remember that this is a local search function and thus can get stuck on local optima so your starting points can actually be quite important.
beta0 is your initial guess at the parameters. The better your guess, the more likely you will see convergence to a viable solution. nlinfit is no more than an optimization. It has to start somewhere.