non negative answers for Mldivide(), x = a\b?

4 views (last 30 days)
Hi all, Im looking for a way to state that two of the variables in x when claculating x = a\b need to be non negative.
for example: I need
x(2) >=0;
x(3) >=0
when im calculating
a = [-1 1 1.75 2 0 2 0
-1 1 1.75 0.5 1 0.5 1
0 0 -1 0 1 0 0
0 0 -1 0 0 0 1
0 1 1 0 0 0 0];
b = [0
0
0
0
1];
x = a\b
note: all other elements of x are fine to be negative.
Any help will much appreciated!
Many thanks

Accepted Answer

Star Strider
Star Strider on 22 Aug 2015
If you have the Optimization Toolbox, probably the easiest way is to use the lsqlin function. It allows you to constrain the parameters.
  2 Comments
Luke Eley
Luke Eley on 23 Aug 2015
Many Thanks, hadn't come across lsqlin before but works perfectly.

Sign in to comment.

More Answers (1)

John D'Errico
John D'Errico on 23 Aug 2015
Edited: John D'Errico on 23 Aug 2015
Actually, probably better than lsqlin, IF you only need non-negativity, is lsqnonneg. You don't even need a toolbox for it.
A = rand(1000,100);
B = rand(1000,1);
opts = optimset('disp','none');
timeit(@() lsqlin(A,B,[],[],[],[],zeros(100,1),[],[],opts))
ans =
0.046757
timeit(@() lsqnonneg(A,B))
ans =
0.035336
As you can see, lsqnonneg is faster. It does not require any special handling. And it has a simple calling sequence for the simple case that it can handle.
  2 Comments
Luke Eley
Luke Eley on 23 Aug 2015
Edited: Matt J on 23 Aug 2015
Hi John, Thanks for commenting, how would I state that just some elements of x have to be non negative when using lsqnonneg()
for instance, the below eg works for lsqlin():
a = [-1 1 1.75 2 0 2 0;
-1 1 1.75 0.5 1 0.5 1;
0 0 -1 0 1 0 0;
0 0 -1 0 0 0 1;
0 0 -2 1 0 0 0;
0 0 -2 0 0 1 0;
0 1 1 0 0 0 0];
b = [0 0 0 0 0 0 1]';
lb = [-Inf,0,0,-Inf,-Inf,-Inf,-Inf];
ub = [Inf,1,1,Inf,Inf,Inf,Inf];
x = lsqlin(a,b,[],[],[],[],lb,ub)
I would like to use lsqnonneg, as no need for the toolbox, if possible?
Matt J
Matt J on 23 Aug 2015
Edited: Matt J on 23 Aug 2015
would like to use lsqnonneg, as no need for the toolbox, if possible
If z is one of your unbounded variables, you could make the change of variables
z=u-v
where u and v are new variables constrained to be non-negative.
I see you've also now introduced upper bounds ub(i)=1. Accommodating those is less straightforward. One option would be to create additional variables
y=1-x(i) (*)
In addition to constraining y>=0, you must add equation (*) above to your list of equations and put a large weight on it. It's less certain to work and, even if it does, probably slower than lsqlin. However, if you must work without the Optimization Toolbox, it's one approach to consider.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!