matrices A*x =B where x> 0

I want to solve A*x = B where x>0,
My A matrix is a rectangular 6x9 and B is a 6x1,
due to the nature of the data x can not be negative or 0.
I have tried the following:
X = A\B
P = pinv(A)*(B)
x = lsqnonneg(A,B)
but still have 0 in my solution.
is it possible to solve for x > 0 ?

3 Comments

Typically, x and B are given and you try to find A. Here you've specified the system and you're trying find x that generated B. It is not clear why you think x must be greater than zero. Can you share your A and B matrices?
A = [ 0.770335115000000 0.229664885000000 0 0 0, 0.689230654000000 0.287340926000000 0.0234284210000000 0 0, 0.580978095000000 0.342040346000000 0.0769815590000000 0 0, 0.494185146000000 0.351855144000000 0.133568256000000 0.0203914540000000 0, 0.454513118000000 0.346967268000000 0.160231631000000 0.0382879830000000 0, 0.379692287000000 0.325593900000000 0.201103278000000 0.0731566080000000 0.0204539260000000 ] B = [ 6.80211000000000e-07 4.95738000000000e-07 3.69505000000000e-07 3.49115000000000e-07 3.73618000000000e-07 3.49385000000000e-07 ]
are the two matrices. A is an energy spectrum broken down into energy bins of 10, so each row represents a different spectrum and B is the corresponding dose to each column. I want to work out the contribution(x) of each 'bin' to the overall dose so as each bin has to contribute in some form x can't be zero or negative.
You have not provided enough information for an Answer.
Consider using:
  • lsqlin (link) in the Optimization Toolbox,
  • lsqminnorm (link), introduced in R2017b

Sign in to comment.

Answers (2)

John D'Errico
John D'Errico on 30 Aug 2018

3 votes

You can use lsqnonneg, or lsqlin to solve the non-negatively constrained least squares problem.
HOWEVER, you cannot enforce a strict inequality, thus x>0.
In fact, any such solution will allow a tiny perturbation that extends beyond the limits. This is dues to floating point trash in the computations, and cannot be avoided in linear algebraic computations of this sort. Typically, when one gets such a solution that extends beyond the desired limits, a post-fix, like the max function can be used to correct the issue. If it that tiny perturbation is just trash, then it can be ignored.
A simple solution is to provide some lower bound which will keep the solution strictly positive. Perhaps 1e-8 or 1e-12 for the lower bound might be acceptable. (A reasonable value would depend on the system itself.) lsqlin can provide that capability. Since the solver can still return a result that will slightly exceed the tolerances, you need to allow some slop there, so even if you get a result that is below the lower bound, it will still be above zero.
Try this using lsqlin:
A = [ 0.770335115000000 0.229664885000000 0 0 0; 0.689230654000000 0.287340926000000 0.0234284210000000 0 0; 0.580978095000000 0.342040346000000 0.0769815590000000 0 0; 0.494185146000000 0.351855144000000 0.133568256000000 0.0203914540000000 0; 0.454513118000000 0.346967268000000 0.160231631000000 0.0382879830000000 0; 0.379692287000000 0.325593900000000 0.201103278000000 0.0731566080000000 0.0204539260000000 ];
B = [ 6.80211000000000e-07 4.95738000000000e-07 3.69505000000000e-07 3.49115000000000e-07 3.73618000000000e-07 3.49385000000000e-07 ];
Params = lsqlin(A, B(:), [], [], [], [], ones(size(A,2))*1E-8, [])
Params =
1.1329e-05
5.3892e-05
9.7314e-05
0.00011766
0.00012823

Asked:

on 30 Aug 2018

Answered:

on 30 Aug 2018

Community Treasure Hunt

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

Start Hunting!