How can i solve this linear system ?

8 views (last 30 days)
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

John D'Errico
John D'Errico on 24 Jul 2014
Edited: John D'Errico on 25 Jul 2014
Your problem is such that there are infinitely many solutions. backslash will return ONE solution, but you want more. How many more? 2? 37? 454233531211 of them?
The general solution can be written in the form
X = X0 + null(A)*k
where k is any general vector, here of size [49-14,1], and X0 is given by
X0 = A\b
If you further require the solution to fall in the 49-dimensional unit box [0,1]^49, it is entirely possible that no solution exists at all. BUT, lsqlin can solve for A solution if any exists. Then you use the same trick that I showed above to find a new solution.
If you don't have the optimization toolbox, so no lsqlin, then you can use lsqnonneg, employing slack variables to transform the problem into one that it can solve. This will require some minor coding of course.
If some of the parameters are already known, then you could simply eliminate them from the problem. Subtract those terms from the right hand side of the linear system. Or, again, if you have lsqlin, then simply set up equality constraints. (This is a far better solution than setting the lower and upper bounds to the same value, which will probably introduce numerical problem.)
And as far as reading in a text matrix, of course MATLAB can read in a file. 14x49 is not even remotely what anyone would call big though.

More Answers (2)

debzz
debzz on 27 Jul 2014
Thanks for your help.
After some readings about lsqlin I came up with this code:
MATLAB code
C=[1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1;
9957.81 0 0 0 0 0 0 1168.06 0 0 0 0 0 0 4817.60 0 0 0 0 0 0 5417.43 0 0 0 0 0 0 520.87 0 0 0 0 0 0 86.75 0 0 0 0 0 0 210.55 0 0 0 0 0 0;
0 9957.81 0 0 0 0 0 0 1168.06 0 0 0 0 0 0 4817.60 0 0 0 0 0 0 5417.43 0 0 0 0 0 0 520.87 0 0 0 0 0 0 86.75 0 0 0 0 0 0 210.55 0 0 0 0 0;
0 0 9957.81 0 0 0 0 0 0 1168.06 0 0 0 0 0 0 4817.60 0 0 0 0 0 0 5417.43 0 0 0 0 0 0 520.87 0 0 0 0 0 0 86.75 0 0 0 0 0 0 210.55 0 0 0 0;
0 0 0 9957.81 0 0 0 0 0 0 1168.06 0 0 0 0 0 0 4817.60 0 0 0 0 0 0 5417.43 0 0 0 0 0 0 520.87 0 0 0 0 0 0 86.75 0 0 0 0 0 0 210.55 0 0 0;
0 0 0 0 9957.81 0 0 0 0 0 0 1168.06 0 0 0 0 0 0 4817.60 0 0 0 0 0 0 5417.43 0 0 0 0 0 0 520.87 0 0 0 0 0 0 86.75 0 0 0 0 0 0 210.55 0 0;
0 0 0 0 0 9957.81 0 0 0 0 0 0 1168.06 0 0 0 0 0 0 4817.60 0 0 0 0 0 0 5417.43 0 0 0 0 0 0 520.87 0 0 0 0 0 0 86.75 0 0 0 0 0 0 210.55 0;
0 0 0 0 0 0 9957.81 0 0 0 0 0 0 1168.06 0 0 0 0 0 0 4817.60 0 0 0 0 0 0 5417.43 0 0 0 0 0 0 520.87 0 0 0 0 0 0 86.75 0 0 0 0 0 0 210.55];
d=[1 1 1 1 1 1 1 11613.45 399.11 3475.97 5311.40 1139.73 87.63 151.79];
lb=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0];
ub=[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1];
A=[];
b=[];
Aeq=[];
beq=[];
options = optimoptions('lsqlin','Algorithm','active-set','MaxIter',1000000);
x=lsqlin(C,d,A,b,Aeq,beq,lb,ub,x,options);
Matlab keep telling me that the number of iterations exceeded. I increased MaxIter parameter to 1 million iterations but the number of iterations keep being exceeded. I'm I doing something wrong ?
  2 Comments
John D'Errico
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
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.

Sign in to comment.


debzz
debzz on 27 Jul 2014
Edited: debzz on 27 Jul 2014
Ok, so just to explain better my problem I did some test. I took the problem backwards. I had a similar linear system (Cx=d) to the one I posted above. In this one I already know a solution ( S ) so I wanted to see if lsqlin could solve x. To see if the solution was indeed a solution, I computed A*S and compare the result with d.
Matlab code
A*S=[1 1 1 1 1 1 1 9939.3 1169.5 4820.8 5396.5 521.0 84.4 209.6]
d=[1 1 1 1 1 1 1 9939.44 1169.60 4821.32 5396.32 520.68 84.52 210.32]
As you can see A*S and d are pretty close so the solution S is a good solution and now we are pretty sure that a solution exist.
Then I tried to use lsqlin to find a solution. I used the same script as I posted above (but with a different C and d matrix of course).
lsqlin can't find any solutions. And no matter how many iterations I set (I increased MaxIter parameter up to 1 million) the number of iteration is always exceeded and the x vector doesn't seem to improve at all.
In addition, I set the x0 initial solution vector as the vector S (the solution that I already knew). I was expecting the solver to do only 1 or 2 iterations since I fed it with the solution. Unfortunatly it didn't work. In fact the solver still can't find a solution eventhough I gave it to him.
Finally I swithed the algorithm to 'active-set' because when I use the default one I get the following warning:
MATLAB Code
Warning: Large-scale algorithm requires at least as many equations as variables
in C matrix; using medium-scale algorithm instead.
One more thing: I try to find a solution without the use of lower and upper bound and it worked. The problem is that the solution is useless because some of the solution are not within the range of [0;1].
There must be something that I am missing but I can't see it. Do you have a hint or something ?
  5 Comments
debzz
debzz on 27 Jul 2014
I have tried you code with the other linear system and it worked very well to. I'm pretty satisfied with this result right now but I might play and tweak the equalities, inequalities and bounds to see if I can have more control over the solution.
Thank you very much for your help and responsiveness M. John D'Errico.
John D'Errico
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.

Sign in to comment.

Products

Community Treasure Hunt

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

Start Hunting!