solving system of equations using singular value decomposition and fsolve

56 views (last 30 days)
Sumera Yamin on 7 Jun 2018
Commented: Anton Semechko on 13 Jun 2018
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.

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.
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.

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).