MATLAB Answers

solving system of equations using singular value decomposition and fsolve

55 views (last 30 days)
Hello, i have a system of equations which i want to solve. My simplified system is shown below.
k1=0.6828;
k2=1.3656;
k3=2.0485;
k4=2.7313;
l=0.1920;
M= [cos(k1*l)^2, (sin(k1*l)*cos(k1*l))/k1, sin(k1*l)*cos(k1*l), (sin(k1*l)^2)/k1;
-sin(k1*l)*cos(k1*l), -(sin(k1*l)^2)/k1, cos(k1*l)^2, (sin(k1*l)*cos(k1*l))/k1;
cos(k2*l)^2, (sin(k2*l)*cos(k2*l))/k2, sin(k2*l)*cos(k2*l), (sin(k2*l)^2)/k2;
-sin(k2*l)*cos(k2*l), -(sin(k2*l)^2)/k2, cos(k2*l)^2, (sin(k2*l)*cos(k2*l))/k2;
cos(k3*l)^2, (sin(k3*l)*cos(k3*l))/k3, sin(k3*l)*cos(k3*l), (sin(k3*l)^2)/k3;
-sin(k3*l)*cos(k3*l), -(sin(k3*l)^2)/k3, cos(k3*l)^2, (sin(k3*l)*cos(k3*l))/k3;
cos(k4*l)^2, (sin(k4*l)*cos(k4*l))/k4, sin(k4*l)*cos(k4*l), (sin(k4*l)^2)/k4;
-sin(k4*l)*cos(k4*l), -(sin(k4*l)^2)/k4, cos(k4*l)^2, (sin(k4*l)*cos(k4*l))/k4];
F= [0.0051; -0.0092; 0.0199; -0.0157; 0.0436; -0.0168; 0.0745; -0.0103];
X= [xi; xpi; yi; ypi];
% F=M*X is the equation to solve with elements of X being unknowns
i have a wide range of k values to solve (and more complex M also but for simplicity i stuck to this case). I have tried to solve using Singular value decomposition (SVD), fsolve and but all these functions reveals different results. Please advice what will be the best way to solve such system. SVD was selected because in some cases, matrix m became rank deficit. My solutions are as follows.
[U,S,V] = svd(M,0)
U1=U(:,1:2);
S1=S(1:2,1:2);
V1=V(:,1:2);
c = U1.'*(F);
p1 = inv(S1)*c;
X = V1*p1
I also tried using "solve" or "fsolve" but all of these functions give me different values of X. Please advice on how to solve such a system.

Accepted Answer

John D'Errico
John D'Errico on 7 Jun 2018
Solving a singular (or nearly so) linear system of equations will have infinitely many solutions, all equally good (or bad).
Fsolve is not a good way to solve the problem, using an iterative solver to find a solution will at best only provide a different solution for every set of starting values, all equally bad.
Use pinv, or lsqminnorm.
X = pinv(M)*F;
or (in a recent MATLAB release)
X = lsqminnorm(M,F);
If you have additional information about the variables, then there are ways you can bring that into the problem. But without that, there is nothing you can simply do that is better than the above solutions.
  2 Comments
John D'Errico
John D'Errico on 11 Jun 2018
Yes. The beauty of pinv as a solution, is it works as well as possible if the system is singular or nearly so, or if it is perfectly well conditioned.
If your matrix is non-singular, then X=pinv(M)*F will yield the same solution as does M\F.
You can absolutely be safe and just use pinv always there. The only downside to using pinv is it will be slightly less efficient. Thus pinv takes just a bit more work. But that difference is TINY for a 4x4 problem. For example:
M = rand(4);
F = rand(4);
timeit(@() M\F)
ans =
6.497e-06
timeit(@() pinv(M)*F)
ans =
6.4058e-05
So, it took roughly 10 times as long. But in terms of absolute numbers, who cares if you take an extra tiny fraction of a millisecond? :)
If you are doing it many millions or billions of times, well, yes, it may be significant. But even for a few thousand times, or tens or even hundreds of thousands, it simply is not worth worrying about the time differential there.

Sign in to comment.

More Answers (1)

Anton Semechko
Anton Semechko on 7 Jun 2018
This is an overdetermined system (i.e., number of equations > number of variables). You can obtain least squares solution as X=(M'*M)\(M'*F). Note that (M'*M) is the matrix that is being inverted here, not M (because M is not a square matrix).
  10 Comments
Anton Semechko
Anton Semechko on 13 Jun 2018
John, I admit that the answer I offered at the beginning was a bad way to obtain LS solutions to overdermined systems. Thanks for educating me!

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!