How can i solve this linear system ?
Show older comments
Hello,
I have a linear system of equation composed of 14 equations and 49 unknowns. I know that my system can be writed in the Ax=b form and then performing the division A\b to find the unknown vector x. I'm new to Matlab so sorry if I'm asking trivial questions.
My questions are the following:
1) My system should have multiple solutions since it is underdetermined. A\b only gives 1 solution. Is there any way to get more than 1 solution ?
2) I already know that all my 49 unknown are within the range [0;1]. How can I set this constrains to all my unkown ?
3) I may have some unknown that I already know before solving the system. Is it possible to restrict some value of the x vector without having to rewrite the whole system like it is said in the following thread: http://www.mathworks.fr/matlabcentral/answers/17795-basic-matrix-equation-ax-b-with-restrictions
4) Is it possible to import a matrix from a text file, because my A matrix is quite big ?
Regards, Debzz
Accepted Answer
More Answers (2)
debzz
on 27 Jul 2014
2 Comments
John D'Errico
on 27 Jul 2014
By the way, you don't need to add answers. Use comments instead. An answer should be exactly that, an answer.
John D'Errico
on 27 Jul 2014
I looked at your problem as posed here. First, the fact that C and d do not conform properly for linear algebra, in the sense that d should be 14x1, not 1x14. So...
d = d.';
Next, your problem is probably poorly scaled. Large disparities in the magnitude of those matrix elements will potentially cause numerical problems with many optimization schemes. So...
r = max(abs(C),[],2);
Chat = bsxfun(@times,C,1./r);
dhat = d'./r;
This may have helped a bit. See that Chat is a bit better behaved than was C. But as importantly, see that C was singular! It has a zero singular value there, so the rank of your matrix was only 13, not 14. RANK would have told us the same thing, but SVD tells us a bit more. Note that a singular matrix tells us that an exact solution need not exist.
[svd(C),svd(Chat)]
ans =
12386 2.9235
12386 2.6458
12386 2.6458
12386 2.6458
12386 2.6458
12386 2.6458
12386 2.6458
2.6458 1.2438
2.6458 1.2438
2.6458 1.2438
2.6458 1.2438
2.6458 1.2438
2.6458 1.2438
1.4763e-13 2.7105e-16
Does any exact solution exist? If we augment Chat with dhat, then test the rank, if that rank were to change, then in fact there is no exact solution, even disregarding the bound constraints.
svd([Chat,dhat])
ans =
4.0219
2.7745
2.6458
2.6458
2.6458
2.6458
2.6458
1.415
1.2438
1.2438
1.2438
1.2438
1.2438
2.093e-07
Ah, so the augmented matrix is no longer rank deficient. So no exact solution exists.
Next, before I ever try lsqlin, use backslash. What does it do? (Besides tell us that C was singular, which we already knew.)
Chat\dhat
Warning: Rank deficient, rank = 13, tol = 1.538691e-14.
ans =
1.1663
0.04008
0.34907
-0.010648
0.11446
-0.67447
0.015243
0
0
0
0
0
1
0
0
0
0
0
0
1
0
0
0
0
1
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
1
0
0
0
0
0
0
1
0
BACKSLASH gave a valid answer, although one that fails your constraints.
Remember, that since we already knew there was no exact solution, we cannot expect perfection. Try lsqlin now. I'll be lazy with the options, using the defaults.
xhat = lsqlin(Chat,dhat,[],[],[],[],lb,ub)
Warning: The trust-region-reflective algorithm requires at least as many equations as variables
in C matrix; using active-set algorithm instead.
> In lsqlin at 301
Maximum number of iterations exceeded; increase options.MaxIter.
To continue solving the problem with the current solution as the
starting point, set x0 = x before calling lsqlin.
xhat =
0.12429
0
0.40281
-2.1684e-19
0.19805
0.092399
0.098842
1
-5.0388e-17
0
0
0
-5.1065e-12
-1.548e-16
0.95955
0
0
-1.1297e-16
0
0
0
1
-3.4694e-18
0
1
-1.7347e-18
0
0
0
1
0
0
0
1.1102e-16
0
0
1.7347e-18
1
0
0
0
0
0
0
1
0
0
0
0
Again, it found a solution that satisfies the bounds. But NO exact solution exists, so I doubt that we can do much better here. Allowing it to use an infinite number of iterations will not help. My guess is the singularity of your system is causing LSQLIN to keep looking.
5 Comments
John D'Errico
on 27 Jul 2014
Edited: John D'Errico
on 27 Jul 2014
You say that you have a problem that DOES have a known solution, but you don't show the problem. How can I add anything?
Read my response to your LAST answer, as a rank deficient system probably causes problems.
And please STOP ADDING an infinite number of answers that are not answers! This only confuses things. USE COMMENTS!
John D'Errico
on 27 Jul 2014
Edited: John D'Errico
on 27 Jul 2014
Again, C is a rank deficient matrix, so for a solution to exist, we need to have d be representable as a linear combination of the columns of C. We can test if that is true by a simple test:
rank([C,d'])
ans =
13
rank(C)
ans =
13
Both results must yield the same result, else an exact solution will not exist. The solution you provided is not really the exact solution of course, probably because of rounding issues.
[C*Sol,d',C*Sol - d']
ans =
1 1 0
1 1 0
0.9999 1 -0.0001
0.9999 1 -0.0001
0.9999 1 -0.0001
0.9999 1 -0.0001
1 1 0
9939.3 9939.4 -0.17258
1169.5 1169.6 -0.13423
4820.8 4821.3 -0.50531
5396.5 5396.3 0.21858
520.95 520.68 0.27128
84.383 84.52 -0.13719
209.62 210.32 -0.69796
It did not do too badly, but lsqlin will be trying to chase down an exact solution, and we have a rank deficient problem.
Note that if I drop the last row of C, it does not change the rank of C. There are ways of finding which row might be the best one to drop.
rank(C(1:13,:))
ans =
13
A simple one is...
[Q,R,E] = qr(C',0);
E
E =
8 9 10 11 12 13 14 6 7 5 2 3 4 1
That last element of E is the row we could have dropped. Here E(end) was 1, which tells me that the first row is mathematically the logical choice to drop.
How does LSQLIN do here?
options = optimset('lsqlin');
options.Algorithm = 'active-set';
x = lsqlin(C(2:14,:),d(2:14)',[],[],[],[],lb,ub,[],options)
Optimization terminated.
x =
-5.5511e-17
0
0.3815
0.6185
0
0
0
0.52827
0
0
0
0.33601
0
0.13573
0.49631
0.21446
0.27373
0
0
0.015498
0
1
0
0
0
0
0
0
1
0
0
-6.6174e-24
0
0
0
1
0
0
0
0
0
0
1
0
0
0
0
0
4.2352e-22
[C*x,d',C*x - d']
ans =
1 1 -3.8636e-14
1 1 2.176e-13
1 1 0
1 1 0
1 1 0
1 1 0
1 1 0
9939.4 9939.4 0
1169.6 1169.6 0
4821.3 4821.3 0
5396.3 5396.3 0
520.68 520.68 0
84.52 84.52 0
210.32 210.32 0
The result is now pretty much exact, with no warning messages generated, and no problem with the number of iterations needed. That the answer is not the same as Sol is irrelevant, since there are infinitely many valid solutions, and Sol was not truly an exact solution.
So clearly the problem LSQLIN (specifically the active-set algorithm) is having is with your rank deficiency. The fact that the system is underdetermined is not a problem.
Of course, we were able to happily drop one row of the matrix because we knew that d was representable as an exact linear combination of the columns of C. And valid solution to the last 13 rows must be as equally valid for the first row.
debzz
on 27 Jul 2014
John D'Errico
on 27 Jul 2014
You have many dimensions to play with. A minor problem is that this gives you little control over which solution is chosen, but unless you know the answer, or you have more information than you supply to the system, then LSQLIN will be pretty arbitrary about what it gives.
Since I don't know what is good or bad here about the solution, I can't offer advice. However an alternative option you might try is to use either LSQLIN or QUADPROG to find that solution which is closest to 0.5*ones(49,1), whiie still satisfying the linear system and the bound constraints.
Categories
Find more on Linear Least Squares in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!