Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
809 views
in Technique[技术] by (71.8m points)

matlab - Solving matrices of the form Ax = B ==> error: Matrix is close to singular or badly scaled

I'm having trouble solving a system of the form Ax=B

The solution to the system should be

x = inv(A)*B

However, this doesn't work.

I get the following error message when I try the above line of code:

Warning: Matrix is close to singular or badly scaled.
     Results may be inaccurate. RCOND = 1.156482e-018. 

It seems that matlab is having trouble inverting the matrix that I've specified. I tried to verify that the inverse function was working properly by typing in inv(A)*A

This should give the identity matrix, however I got the same error and some garbage numbers.

This is the A matrix that I'm using:

A = [5/2   1/2  -1     0     0    -1/2  -1/2   0     0
     1/2   1/2   0     0     0    -1/2  -1/2   0     0 
    -1     0     5/2  -1/2  -1     0     0    -1/2   1/2
     0     0    -1/2   1/2   0     0     0     1/2  -1/2
     0     0    -1     0     3/2  -1/2   1/2   0     0
    -1/2  -1/2   0     0    -1/2   2     0    -1     0  
    -1/2  -1/2   0     0     1/2   0     1     0     0 
     0     0    -1/2   1/2   0    -1     0     2     0 
     0     0     1/2  -1/2   0     0     0     0     1]

Any ideas as to why this isn't working? I also tried to convert A to a sparse matrix (sparse(A)), and then run the inverse command. No dice.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem is indeed in your mathematics. The matrix you provided isn't of full rank, so it isn't invertible. You could verify that manually (haven't taken the time to do so), but MATLAB already points this out by showing that warning.

Since you are working with floating point numbers, this sometimes causes other subtle problems, one of which you can see in the result of det(A), which is in the order of 1e-16, i.e. machine precision or 0 in practice.

You can see that this Matrix is not of full rank by executing the rank function: rank(A) = 8. For a 9x9 matrix, this indeed means that the matrix is not invertible for doubles (as the rank function accounts for machine precision).

If you want to use MATLAB to get a result that corresponds to a manual calculation, you can use the Symbolic Toolbox and its vpa (variable precision arithmetic) to work around possible numerical problems at the cost of a slower calculation.

B = [5  1 -2  0  0 -1 -1  0  0;
     1  1  0  0  0 -1 -1  0  0;
    -2  0  5 -1 -2  0  0 -1  1;
     0  0 -1  1  0  0  0  1 -1;
     0  0 -2  0  3 -1  1  0  0;
    -1 -1  0  0 -1  4  0 -2  0;
    -1 -1  0  0  1  0  2  0  0;
     0  0 -1  1  0 -2  0  4  0;
     0  0  1 -1  0  0  0  0  2];
A = B/2;
size(A)    % = [9 9]
det(A)     % = -1.38777878078145e-17
rank(A)    % = 8
C = vpa(A);
det(C)     % = 0.0
rank(C)    % = 8

Both with VPA and floating points you will get that the rank is 8, the size is [9 9] and the determinant is practically 0, i.e. singular or not invertible. Changing a few entries might make your matrix regular (non-singular), but it is not guaranteed to work and it will solve a different problem.

To solve your actual problem A*x=b for x, you can try to use mldivide (a.k.a. the backslash operator) or a Moore-Penrose pseudo-inverse:

x1 = A;
x2 = pinv(A)*b;

But do remember that such a system does not have a unique solution, so both the pseudo-inverse and the backslash operator may (and in this case will) return very different solutions, whether any of them is acceptable really depends on your application.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...