1

これが何を意味するのかよくわかりません。「警告: 行列は作業精度に対して特異です。」

マトリックス bestM と呼ばれる 3x4 マトリックスがあります。マトリックス Q は bestM の 3x3 であり、マトリックス m は bestM の最後の列です。

C = -Q * 行列 m の逆行列を実行したいのですが、その警告と C =[Inf Inf Inf] が表示されます。これは、世界のカメラの中心を計算しているため、正しくありません。

bestM = [-0.0031 -0.0002 0.0005 0.9788;
         -0.0003 -0.0006 0.0028 0.2047;
         -0.0000 -0.0000 0.0000 0.0013];   

Q = bestM(1:3,1:3);
m = bestM(:,4);

X = inv(Q);
C = -X*m;
disp(C);
4

2 に答える 2

5

特異行列は、ゼロに相当する行列と考えることができます.0を反転しようとすると、爆発します(無限大になります)。これがここで得られるものです。ユーザー 1281385 は、format コマンドを使用して精度を上げることについて完全に間違っています。format コマンドは、表示される形式を変更するために使用されます。実際、フォーマットのヘルプコマンドの最初の行には、

形式は、MATLAB 計算の実行方法には影響しません。

于 2012-10-14T00:28:26.130 に答える
1

ここにあるように、特異行列は逆行列を持たない行列です。dvreed77がすでに指摘しているように、これは行列の1/0と考えることができます。

私が答えている理由は、inv明示的に使用することはほとんど決して良い考えではないということです。同じ逆関数が数百回必要な場合は、それだけの価値があるかもしれませんが、ほとんどの場合、製品に関心がありますC

C = -inv(Q)*m

これは、バックスラッシュ演算子を使用して、Matlabではるかに正確かつ高速に計算できます。

C = -Q\m

詳細help slashについては、入力してください。そして、あなたが本当に逆を明示的に必要とする状況に自分自身を見つけたとしても、私はあなたに避けることをお勧めしますinv

invQ = Q\eye(size(Q))

以下は、明示的な逆関数が便利な数少ない状況の1つを示すための小さなパフォーマンステストです。

% This test will demonstrate the one case I ever encountered where
% an explicit inverse proved useful. Unfortunately, I cannot disclose
% the full details without breaking the law, but roughly, it came down
% to this: The (large) design matrix A, a result of a few hundred 
% co-registrated images, needed to be used to solve several thousands 
% of systems, where the result matrices b came from processing the 
% images one-by-one. 
%
% That means the same design matrix was re-used thousands of times, to 
% solve thousands of systems at a time. To add to the fun, the images
% were also complex-valued, but I'll leave that one out of consideration
% for now :)  

clear; clc

% parameters for this demo
its = 1e2;
sz  = 2e3;
Bsz = 2e2;

% initialize design matrix
A = rand(sz);

% initialize cell-array to prevent allocating memory from consuming 
% unfair amounts of time in the first loop. 
% Also, initialize them, NOT copy them (as in D=C,E=D), because Matlab 
% follows a lazy copy-on-write scheme, which would influence the results
C = {cellfun(@(~) zeros(sz,Bsz), cell(its,1), 'uni', false)   zeros(its,1)};
D = {cellfun(@(~) zeros(sz,Bsz), cell(its,1), 'uni', false)   zeros(its,1)};
E = {cellfun(@(~) zeros(sz,Bsz), cell(its,1), 'uni', false)   zeros(its,1)};

% The impact of rand() is the same in both loops, so it has no 
% effect, it just gives a longer total run time. Still, we do the 
% rand explicitly to *include* the indexing operation in the test. 
% Also, caching will most definitely influence the results, because 
% any compiler (JIT), even without optimizations, might recognize the 
% easy performance gain when the code computes the same array over and 
% over again. It probably will, but we have no control over when and 
% wherethat happens. So, we prevent that from happening at all, by 
% re-initializing b at every iteration. 

% The assignment to cell is a necessary part of the demonstration; 
% it is the desired output of the whole calculation. Assigning to cell 
% instead of overwriting 'ans' takes some time, which is to be included 
% in the demonstration, again for cache reasons: the extra time is now
% guaranteed to be equal in both loops, so it really does not matter -- 
% only the total run time will be affected.

% Direct computation
start = tic;
for ii = 1:its    
    b = rand(sz,Bsz);    
    C{ii,1} = A\b;
    C{ii,2} = max(max(abs( A*C{ii,1}-b )));
end
time0 = toc(start);
[max([C{:,2}])   mean([C{:,2}])   std([C{:,2}])]

% LU factorization (everyone's
start = tic;
[L,U,P] = lu(A, 'vector');
for ii = 1:its    
    b = rand(sz,Bsz);    
    D{ii,1} = U\(L\b(P,:));
    D{ii,2} = max(max(abs( A*D{ii,1}-b )));
end
time1 = toc(start);
[max([D{:,2}])   mean([D{:,2}])   std([D{:,2}])]


% explicit inv
start = tic;
invA = A\eye(size(A)); % NOTE: DON'T EVER USE INV()!
for ii = 1:its
    b = rand(sz,Bsz);
    E{ii,1} = invA*b;
    E{ii,2} = max(max(abs( A*E{ii,1}-b )));
end
time2 = toc(start);
[max([E{:,2}])   mean([E{:,2}])   std([E{:,2}])]

speedup0_1 = (time0/time1-1)*100
speedup1_2 = (time1/time2-1)*100
speedup0_2 = (time0/time2-1)*100

結果:

% |Ax-b|
1.0e-12 * % max.   mean     st.dev.
          0.1121   0.0764   0.0159 % A\b   
          0.1167   0.0784   0.0183 % U\(L\b(P,;))
          0.0968   0.0845   0.0078 % invA*b

speedup0_1 = 352.57 % percent
speedup1_2 =  12.86 % percent
speedup0_2 = 410.80 % percent

明示的な逆関数にはその用途があることは明らかですが、goto他の言語の構文と同じように、慎重かつ賢明に使用してください。

于 2012-10-14T04:46:53.387 に答える