Решение матрицы вида Ax = B ==> error: матрица близка к единственному или плохо масштабируется - PullRequest
12 голосов
/ 02 ноября 2011

У меня проблемы с решением системы вида Ax = B

Решение системы должно быть

x = inv(A)*B

Однако это не работает.

Я получаю следующее сообщение об ошибке, когда пытаюсь использовать приведенную выше строку кода:

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

Похоже, у matlab возникают проблемы с инвертированием указанной мной матрицы.Я попытался проверить, правильно ли работала обратная функция, набрав inv (A) * A

. Это должно дать матрицу тождеств, однако я получил ту же ошибку и некоторые номера мусора.

Это матрица A, которую я использую:

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]

Есть идеи, почему это не работает?Я также попытался преобразовать A в разреженную матрицу (sparse (A)), а затем запустить обратную команду.Без кубиков.

Ответы [ 4 ]

20 голосов
/ 02 ноября 2011

Проблема действительно в вашей математике.Предоставленная вами матрица не имеет полного ранга, поэтому она не является обратимой.Вы можете проверить это вручную (это не заняло времени), но MATLAB уже указывает на это, показывая это предупреждение.

Поскольку вы работаете с числами с плавающей запятой, это иногда вызывает другие тонкие проблемы,один из которых вы можете увидеть в результате det(A), который имеет порядок 1e-16, то есть точность машины или 0 на практике.

Вы можете видеть, что эта матрица не имеет полного рангавыполнение функции rank: rank(A) = 8.Для матрицы 9x9 это действительно означает, что матрица не является обратимой для двойных чисел (поскольку функция rank учитывает точность станка).

Если вы хотите использовать MATLAB для получения результата, который соответствуетВ ручном расчете вы можете использовать Symbolic Toolbox и его vpa (арифметику с переменной точностью), чтобы обойти возможные числовые проблемы за счет более медленных вычислений.

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

Как с VPA, так и с плавающей запятой выполучим, что ранг равен 8, размер равен [9 9], а определитель практически равен 0, то есть в единственном числе или не обратим.Изменение нескольких записей может сделать вашу матрицу регулярной (неособой), но она не гарантированно сработает и решит другую проблему.

Чтобы решить вашу актуальную проблему A*x=b для x, вамможно попытаться использовать mldivide (он же оператор обратной косой черты) или псевдообратный код Мура-Пенроуза:

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

Но помните, что такая система не имеет уникального решения, поэтому обе псевдооператор обратного слэша и оператор обратной косой черты могут (и в этом случае будут) возвращать очень разные решения, независимо от того, является ли любое из них приемлемым, действительно зависит от вашего приложения.

11 голосов
/ 02 ноября 2011

Это означает именно то, что говорится. Матрица единственная, что означает, что она не может быть инвертирована . Не все матрицы могут.

В геометрических терминах у вас есть матрица, которая превращает один 9-мерный объект в другой, но полностью выравнивает одно измерение. Это не может быть отменено; нет никакого способа сказать, как далеко вытащить вещи в этом направлении.

2 голосов
/ 02 ноября 2011

Матрица единственного числа, рассмотрим B = 2 * A ниже:

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]

det(B)

0
1 голос
/ 19 апреля 2013

bicgstab(A,b,tol,maxit), итерационный решатель, смог найти единственную линейную систему A * x = b для особой матрицы A:

size(A)=[162, 162] 
rank(A)=14 
cond(A)=4.1813e+132 

Я использовал:

tol=1e-10; 
maxit=100;

Ничто из вышеперечисленного (включая svd, \, inv, pinv, gmres) не сработало для меня, но bicgstab хорошо поработало. bicgstab сходилось на итерации 4 к решению с относительным остатком 1.1e-11. Быстро работает для разреженных матриц.

См. Документацию здесь: https://uk.mathworks.com/help/matlab/ref/bicgstab.html

...